use std::collections::HashMap;
use lambda_http::Context;
use pyo3::pyclass;
#[pyclass(name = "ClientApplication")]
#[derive(Clone)]
pub struct PyClientApplication {
#[pyo3(get)]
installation_id: String,
#[pyo3(get)]
app_title: String,
#[pyo3(get)]
app_version_name: String,
#[pyo3(get)]
app_version_code: String,
#[pyo3(get)]
app_package_name: String,
}
#[pyclass(name = "ClientContext")]
#[derive(Clone)]
pub struct PyClientContext {
#[pyo3(get)]
client: PyClientApplication,
#[pyo3(get)]
custom: HashMap<String, String>,
#[pyo3(get)]
environment: HashMap<String, String>,
}
#[pyclass(name = "CognitoIdentity")]
#[derive(Clone)]
pub struct PyCognitoIdentity {
#[pyo3(get)]
identity_id: String,
#[pyo3(get)]
identity_pool_id: String,
}
#[pyclass(name = "Config")]
#[derive(Clone)]
pub struct PyConfig {
#[pyo3(get)]
function_name: String,
#[pyo3(get)]
memory: i32,
#[pyo3(get)]
version: String,
#[pyo3(get)]
log_stream: String,
#[pyo3(get)]
log_group: String,
}
#[derive(Clone)]
#[pyclass(name = "LambdaContext")]
pub struct PyLambdaContext {
#[pyo3(get)]
request_id: String,
#[pyo3(get)]
deadline: u64,
#[pyo3(get)]
invoked_function_arn: String,
#[pyo3(get)]
xray_trace_id: Option<String>,
#[pyo3(get)]
client_context: Option<PyClientContext>,
#[pyo3(get)]
identity: Option<PyCognitoIdentity>,
#[pyo3(get)]
env_config: PyConfig,
}
impl PyLambdaContext {
pub fn new(ctx: Context) -> Self {
Self {
request_id: ctx.request_id,
deadline: ctx.deadline,
invoked_function_arn: ctx.invoked_function_arn,
xray_trace_id: ctx.xray_trace_id,
client_context: ctx.client_context.map(|client_ctx| PyClientContext {
client: PyClientApplication {
installation_id: client_ctx.client.installation_id,
app_title: client_ctx.client.app_title,
app_version_name: client_ctx.client.app_version_name,
app_version_code: client_ctx.client.app_version_code,
app_package_name: client_ctx.client.app_package_name,
},
custom: client_ctx.custom,
environment: client_ctx.environment,
}),
identity: ctx.identity.map(|identity| PyCognitoIdentity {
identity_id: identity.identity_id,
identity_pool_id: identity.identity_pool_id,
}),
env_config: PyConfig {
function_name: ctx.env_config.function_name,
memory: ctx.env_config.memory,
version: ctx.env_config.version,
log_stream: ctx.env_config.log_stream,
log_group: ctx.env_config.log_group,
},
}
}
}
#[cfg(test)]
mod tests {
use http::{header::HeaderName, HeaderMap, HeaderValue};
use lambda_http::lambda_runtime::{Config, Context};
use pyo3::{prelude::*, py_run};
use super::*;
#[test]
fn py_lambda_context() -> PyResult<()> {
pyo3::prepare_freethreaded_python();
let headers = HeaderMap::from_iter([
(
HeaderName::from_static("lambda-runtime-aws-request-id"),
HeaderValue::from_static("my-id"),
),
(
HeaderName::from_static("lambda-runtime-deadline-ms"),
HeaderValue::from_static("123"),
),
(
HeaderName::from_static("lambda-runtime-invoked-function-arn"),
HeaderValue::from_static("arn::myarn"),
),
(
HeaderName::from_static("lambda-runtime-trace-id"),
HeaderValue::from_static("my-trace-id"),
),
(
HeaderName::from_static("lambda-runtime-client-context"),
HeaderValue::from_str(
&r#"
{
"client": {
"installationId": "my-installation-id",
"appTitle": "my-app-title",
"appVersionName": "my-app-version-name",
"appVersionCode": "my-app-version-code",
"appPackageName": "my-app-package-name"
},
"custom": {
"custom-key": "custom-val"
},
"environment": {
"environment-key": "environment-val"
}
}
"#
.split_whitespace()
.collect::<String>(),
)
.unwrap(),
),
(
HeaderName::from_static("lambda-runtime-cognito-identity"),
HeaderValue::from_str(
&r#"
{
"identity_id": "my-identity-id",
"identity_pool_id": "my-identity-pool-id"
}
"#
.split_whitespace()
.collect::<String>(),
)
.unwrap(),
),
]);
let lambda_context = Context::try_from(headers).unwrap();
let lambda_context = lambda_context.with_config(&Config {
function_name: "my-fn".to_string(),
memory: 128,
version: "my-version".to_string(),
log_stream: "my-log-stream".to_string(),
log_group: "my-log-group".to_string(),
});
Python::with_gil(|py| {
let ctx = PyCell::new(py, PyLambdaContext::new(lambda_context))?;
py_run!(
py,
ctx,
r#"
assert ctx.request_id == "my-id"
assert ctx.deadline == 123
assert ctx.invoked_function_arn == "arn::myarn"
assert ctx.xray_trace_id == "my-trace-id"
assert ctx.client_context.client.installation_id == "my-installation-id"
assert ctx.client_context.client.app_title == "my-app-title"
assert ctx.client_context.client.app_version_name == "my-app-version-name"
assert ctx.client_context.client.app_version_code == "my-app-version-code"
assert ctx.client_context.client.app_package_name == "my-app-package-name"
assert ctx.client_context.custom == {"custom-key":"custom-val"}
assert ctx.client_context.environment == {"environment-key":"environment-val"}
assert ctx.identity.identity_id == "my-identity-id"
assert ctx.identity.identity_pool_id == "my-identity-pool-id"
assert ctx.env_config.function_name == "my-fn"
assert ctx.env_config.memory == 128
assert ctx.env_config.version == "my-version"
assert ctx.env_config.log_stream == "my-log-stream"
assert ctx.env_config.log_group == "my-log-group"
"#
);
Ok(())
})
}
}