Lambda (Python) template
The lambda-python backend template scaffolds a single AWS Lambda function
written in Python. It is designed to run in a real AWS Lambda Python runtime container
locally via LocalStack, the same image as
production AWS Lambda, so the code that runs locally is the code that runs
in AWS.
When to pick this template
Section titled “When to pick this template”- You want a serverless on-ramp without committing to a long-running container
- Your service is request-response and small enough to fit a single handler
- You’re learning Lambda and want fast local iteration without an AWS bill
- You’d ship to AWS Lambda eventually and want code that’s portable from day one
For a long-running HTTP backend, pick spring-boot instead.
Scaffold
Section titled “Scaffold”blissful-infra service add <service> --type backend --template lambda-python# Scaffolds the handler and its config. The serverless runtime is not# wired up in the tenant model yet. See the note above.Resulting layout at ~/.blissful-infra/clients/<client>/<service>/:
<service>/├── blissful-infra.yaml # service config (type: service, backend: lambda-python)├── docker-compose.yaml # generated; localstack + deployer sidecar├── lambda.yaml # function manifest├── deploy.sh # deployer logic (zips + registers with LocalStack)├── lambda/│ ├── handler.py # the entry point: your code│ └── requirements.txt # Python dependencies└── README.mdWhat runs
Section titled “What runs”flowchart LR subgraph compose[Service compose project] ls["LocalStack<br/>(emulates AWS Lambda runtime)"] dep["Deployer (one-shot)<br/>zip + register on up"] dep -->|awslocal lambda<br/>create-function| ls end user["You"] -->|invoke| ls user -->|edit handler.py| fs[(local files)] user -->|deploy| depThe invoke and deploy arrows were the lambda command, which no longer exists. A tenant-era replacement has not been designed yet.
On service up:
- LocalStack container starts on the per-service
internalnetwork - Deployer sidecar waits for LocalStack to report ready
- Deployer reads
lambda.yaml, zipslambda/+ deps, callsawslocal lambda create-function - Deployer exits clean. The function is now invocable.
Manifest reference (lambda.yaml)
Section titled “Manifest reference (lambda.yaml)”name: hello # function name (lowercase alphanumeric + hyphens)runtime: python3.11 # python3.11 | python3.12 | nodejs20.x | nodejs22.x | java21 | go1.xhandler: handler.lambda_handler # <module>.<function>timeout_seconds: 30 # max 900 (15 min, real Lambda limit)memory_mb: 256 # 128-10240environment: GREETING: "Hello" # all values must be strings (real Lambda constraint)The manifest shape is unchanged by the 2.0 cleanup. It describes the function itself, not how blissful-infra wires it up.
Day-to-day
Section titled “Day-to-day”Scaffolding works:
blissful-infra service add <service> --type backend --template lambda-pythonThe deploy, invoke and logs steps were the lambda command, which was removed in 2.0. There is no current replacement, so a scaffolded function cannot be driven end to end from the CLI. Restoring this needs two things: a tenant-era serverless compose shape, and a command surface to replace lambda deploy / invoke / logs.
Adding dependencies
Section titled “Adding dependencies”Add to lambda/requirements.txt, then redeploy:
requests==2.31.0boto3 # NOT REQUIRED: included in the AWS Lambda runtimeThe deployer pip-installs into a temp dir and zips alongside your handler code. Native deps (numpy, pandas, pillow) install with manylinux wheels by default, matching what real Lambda expects.
Bigger handlers
Section titled “Bigger handlers”The default handler.py is a single-function “hello” greeter. For real apps,
structure as you’d write any Python module:
lambda/├── handler.py # entry: calls into the rest├── domain/│ ├── __init__.py│ └── greeting.py├── adapters/│ ├── __init__.py│ └── ddb.py└── requirements.txtThe deployer zips the whole lambda/ dir, so anything importable from
handler.py ships.
Cloud deploy
Section titled “Cloud deploy”Not implemented yet. When the AWS adapter lands, this same lambda.yaml
lambda/will deploy to real AWS Lambda viablissful-infra deploy --target aws. No code changes required.
For now this is a local-only on-ramp. See ADR-0007 for the planned cloud-deploy story.
Limitations vs real Lambda
Section titled “Limitations vs real Lambda”- No API Gateway routing locally: invoke via CLI only
- No event source mappings auto-wired: S3/SQS/DDB triggers need manual
awslocalsetup - Cold-start times are faster locally than on real AWS, don’t optimize for local timings
- IAM enforcement is off in LocalStack free tier, permission bugs that fail in production may pass locally
- No file-watch auto-redeploy: manual
lambda deployafter edits