Get Your Lambda...
Damian Wysocki

Django
Django
Lambda




HTTP REQUEST
Lambda
- Debugging Lambda locally is painful
The Developer’s Dilemma

The Developer’s Dilemma
Slow feedback.
Hard to debug.
Not Pythonic.
Traditional Lambda Workflow
Meet the Hero!
- Simulates AWS Lambda locally
- Cold/warm start support
- Custom events & context
- Easy setup
- Customizability
- Auto-reloading
- State Persistence

[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.saleor_handler]
handler_path = "handler.http_handler"
url_path = "/saleor/{path:path}"def http_handler(event, context):
print("Hello from Lambda")
return {
"statusCode": 200,
"body": "Hello World"
}python -m smythdef http_handler(event, context):
print("Hello from Lambda")
return {
"statusCode": 200,
"body": "Hello World"
}Add ipdb.set_trace() for real debugging!
def http_handler(event, context):
import ipdb;ipdb.set_trace()
return {
"statusCode": 200,
"body": "Hello World"
}HTTP
REQUEST
Lambda
EVENT
HTTP
REQUEST
Lambda
EVENT
API GW V2
HTTP
REQUEST
EVENT
Lambda
API GW V1
HTTP
REQUEST
EVENT
Lambda
def http_handler(event, context):
print("Hello from Lambda")
return {
"statusCode": 200,
"body": "Hello World"
}from smyth.types import EventData, RunnerProcessProtocol, SmythHandler
async def generate_api_gw_v1_event_data(
request: Request,
smyth_handler: SmythHandler,
process: RunnerProcessProtocol
) -> EventData:
return {
... # API GW V1 event
}
def http_handler(event, context):
print("Hello from Lambda")
return {
"statusCode": 200,
"body": "Hello World"
}[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.saleor_handler]
handler_path = "handler.http_handler"
url_path = "/saleor/{path:path}"[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.saleor_handler]
handler_path = "handler.http_handler"
url_path = "/saleor/{path:path}"
event_data_function_path = "handler.generate_api_gw_v1_event_data"
more complex example
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.saleor_handler]
handler_path = "handler.http_handler"
url_path = "/saleor/{path:path}"
event_data_function_path = "handler.generate_api_gw_v1_event_data"
def order_handler(event, context):
lambda_client.invoke(
FunctionName="email_handler",
InvocationType="Event", # or RequestResponse
Payload=b'{"to": "hello@mirumee.com", "subject": "Order made"}',
)
return {"statusCode": 200, "body": f"Orders requests: {COUNT}"}
def email_handler(event, context):
print(event)
return {"statusCode": 200, "body": f"Products requests: {COUNT}"}more complex example
def order_handler(event, context):
lambda_client.invoke(
FunctionName="email_handler",
InvocationType="Event", # or RequestResponse
Payload=b'{"to": "hello@mirumee.com", "subject": "Order made"}',
)
return {"statusCode": 200, "body": f"Orders requests: {COUNT}"}
def email_handler(event, context):
print(event)
return {"statusCode": 200, "body": f"Products requests: {COUNT}"}more complex example
import boto3
lambda_client = boto3.client(
"lambda",
endpoint_url="http://localhost:8080"
)
def order_handler(event, context):
lambda_client.invoke(
FunctionName="email_handler",
InvocationType="Event", # or RequestResponse
Payload=b'{"to": "hello@mirumee.com", "subject": "Order made"}',
)
return {"statusCode": 200, "body": f"Orders requests: {COUNT}"}more complex example
import boto3
lambda_client = boto3.client(
"lambda",
endpoint_url="http://localhost:8080"
)
def order_handler(event, context):
lambda_client.invoke(
FunctionName="email_handler",
InvocationType="Event", # or RequestResponse
Payload=b'{"to": "hello@mirumee.com", "subject": "Order made"}',
)
return {"statusCode": 200, "body": f"Orders requests: {COUNT}"}more complex example
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.saleor_handler]
handler_path = "handler.http_handler"
url_path = "/saleor/{path:path}"more complex example
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
[tool.smyth.handler.email_handler]
handler_path = "email_handler"
url_path = "/emails/{path:path}"[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"import boto3
lambda_client = boto3.client(
"lambda",
endpoint_url="http://localhost:8080"
)
def order_handler(event, context):
lambda_client.invoke(
FunctionName="email_handler",
InvocationType="Event", # or RequestResponse
Payload=b'{"to": "hello@mirumee.com", "subject": "Order made"}',
)
return {"statusCode": 200, "body": f"Orders requests: {COUNT}"}- Each handler runs in a separate process
- Cold start: New process, code reloaded
- Warm start: Process reused, state preserved
- Simulate real AWS Lambda concurrency
Concurrency: Cold & Warm Start
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"order_handler
email_handler
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
concurrency = 2
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"
concurrency = 2
order_handler
email_handler
order_handler
email_handler
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.first_warm"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.first_warm"
order_handler
email_handler
order_handler
email_handler
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.first_warm"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.first_warm"
order_handler
email_handler
order_handler
email_handler
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.first_warm"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.round_robin"
order_handler
email_handler
order_handler
email_handler
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.first_warm"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.round_robin"
order_handler
email_handler
order_handler
email_handler
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.first_warm"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.round_robin"
order_handler
email_handler
order_handler
email_handler
[tool.smyth]
host = "0.0.0.0"
port = 8080
[tool.smyth.handlers.order_handler]
handler_path = "handler.order_handler"
url_path = "/orders/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.first_warm"
[tool.smyth.handler.email_handler]
handler_path = "handler.email_handler"
url_path = "/emails/{path:path}"
concurrency = 2
strategy_function_path = "smyth.runner.strategy.round_robin"
order_handler
email_handler
order_handler
email_handler
Why lambda?
- auto-scaling
- easy deployment
- it's cheap
Why lambda?
- auto-scaling
- easy deployment
- it's cheap - it is?







dodac link do kalkulatora




Meet the Hero
Lynara: ASGI Apps on Lambda
import asyncio
from lynara import Lynara, APIGatewayProxyEventV2Interface
from fastapi import FastAPI
app = FastAPI()
lynara = Lynara(app=app)
def lambda_handler(event, context):
return asyncio.run(
lynara.run(event, context, APIGatewayProxyEventV2Interface)
)








No rewrite needed. Your ASGI app is portable!
Lambda
HTTP REQUEST
EVENT
ASGI

benchmarks

Serverless Dev Flow, Your Way
- Lambda is cheap/free for dev & test
- No infra to manage - perfect for startups, MVPs
- Outgrow Lambda? Move to EC2/Docker/K8s - no rewrite
- Scale down to zero your ASGI App - serverless
Ready to Supercharge Your Python Serverless?
Try Smyth for local Lambda dev.
Deploy with Lynara for serverless FastAPI/Django.
Questions?
Copy of deck
By Damian Wysocki
Copy of deck
- 64