PyconDE/PyData 2026

-- Views

April 20, 26

スライド概要

profile-image

ダイキン工業 アジャイル内製センターの外部登壇資料を掲載しています

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

(ダウンロード不可)

関連スライド

各ページのテキスト
1.

Schema-Driven Lambdaliths in Python with AWS Lambda Powertools and Pydantic PyConDE & PyData 2026 DAIKIN INDUSTRIES, LTD. MORI Haruto / TANIO Toranosuke 1/47

2.

About the Speakers ① ▍TANIO Toranosuke Background M.Sc. in Information Science 6th year at DAIKIN Joined a web app development team as a Developer Became Scrum Master in year 2 Agile Coach across multiple teams since year 5 Co-organizer of a ~500-engineer internal community 2/47

3.

Do you like TypeScript ? 3/47

4.

The Full-Stack TypeScript Wave ▍One language across the entire stack Frontend (React, Vue, etc.) Backend (Hono, etc.) Infrastructure (AWS CDK, etc.) Hono Lightweight web framework born in Japan Multi-runtime, Web Standards-compliant Hono RPC: shared API contracts, server to client 4/47

5.
[beta]
The Rise of Lambdalith
▍Hono on Lambda — just 2 lines
import { Hono } from 'hono'
import { handler } from 'hono/aws-lambda' // ← add this
const app = new Hono()
app.get('/books', (c) => c.text('Hello Hono!'))
app.post('/books', (c) => {
const { title } = await c.req.json()
return c.text(`Hello ${title}!`)
})
export const handler = handler(app) // ← add this

One Lambda routes and handles all events

5/47

6.

But we're here because we love Python 6/47

7.

What We'll Explore: 1. Why Lambdalith 2. Schema-first, server to client 7/47

8.

About Us 8/47

9.

DAIKIN INDUSTRIES, LTD. ▍The world's only fully integrated HVAC company Refrigerants, manufacturing, sales and service — all inhouse Business Segments HVAC: Air conditioning Core business Chemicals: Fluorochemicals Refrigerants of HVAC Filters: Air purification Boosting HVAC efficiency 9/47

10.

Global No.1 in HVAC Sales ▍A worldwide operation Revenue: USD 31B (EUR 29B) 80% overseas / Europe: USD 4.7B 170+ countries 130+ manufacturing sites Leading in humidity control and ventilation 10/47

11.

Daikin's Agile In-House Team ▍Agile & fully in-house — unusual for a Japanese enterprise Bottom-up adoption to speed up hypothesis testing Engineers growing through continuous improvement Presented at top Japanese conferences JaSST Tokyo : Japan's largest quality conference Region Scrum Gathering Tokyo : World's largest regional Scrum conference 11/47

12.

Perfecting the Air ▍DK-CONNECT (Japan) Cloud-based unified control for whole buildings — HVAC, lighting, and more Easy operation and monitoring for facility managers Turning operational data into value Energy usage visibility Peak power reduction for cost savings AI-driven remote control 12/47

13.

Our Business Domain ▍EneFocus α Analyzes customer HVAC data every minute Proposes optimal operation and energy savings Catches excessive temperatures and forgotten-on units On-call support from service engineers Workflow tools and report generation — developing and operating in-house 13/47

14.

Product Growth and Software Bloat ▍Lambda functions multiplied with features Separate functions for each responsibility data fetching, aggregation, analysis, creating slides Clear responsibilities at first — pain emerged at scale 14/47

15.

Problems with Split Lambdas at Scale ▍Cold starts and bundle size became bottlenecks Each Lambda bundled shared libs separately Duplicate deps inflated deploy artifacts More functions = more cold start overhead Startup time outweighed actual processing 15/47

16.

Why We Needed to Rethink ▍Splitting wasn't optimal here Cold start at every function boundary Our workload: sequential pipeline with heavy shared deps Overhead outweighed the benefits of separation 16/47

17.

About the Speakers ② ▍MORI Haruto Background M.Eng. in Applied Physics 4 years as a software engineer Developer — covering infra, backend, and frontend Joined the Scrum team last year First conference talk ever, including Japan I love traveling! Tell me your favorite restaurants near Frankfurt 17/47

18.

The Lambdalith Approach ▍One Lambda handles all routing and processing API gateway + application logic in a single Lambda Load dependencies once, share across all endpoints -> Minimizes cold start surface area Separate domains per Bounded Context — domain isolation at the infra level -> A natural fit for Domain-Driven Design 18/47

19.
[beta]
First Approach: FastAPI + Lambda Web Adapter
▍A concrete starting point for Lambdalith

FastAPI unifies routing, validation, and response
Lambda Web Adapter runs the web app on Lambda

Familiar web framework DX — easy to prototype and validate
from fastapi import FastAPI
app = FastAPI()
@app.get("/hello")
async def hello_get(text: str, number: int) -> dict:
return {"text": text, "number": number}

19/47

20.

Initial Implementation ▍Run a FastAPI directly as a Lambda execution unit FROM python:3.XX-slim # Just add this line COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:X.X.X/lambda-adapter \ /opt/extensions/lambda-adapter. # ... CMD ["sh", "-c", "exec uvicorn --port=$PORT main:app"] Lambda Web Adapter handles execution on Lambda Routing and validation are delegated to FastAPI 20/47

21.

What Lambdalith Delivered 21/47

22.

Split Lambda vs Lambdalith ▍Performance comparison 45 endpoints Shared business logic Same container image Split Lambda 45 functions API Gateway routes requests Lambdalith (FastAPI) 1 function FastAPI + Lambda Web Adapter 22/47

23.

Looking at a Single Request ▍Split Lambda wins on a one-off cold start Split Lambda: 781ms Lambdalith (FastAPI): 2,582ms FastAPI + Adapter + shared deps all load at once On a single invocation, Lambdalith loses 23/47

24.

However... Production Isn't One Request ▍Hit 6 endpoints in sequence — the result flips Split Lambda: 5,946ms Lambdalith (FastAPI): 2,986ms Split cold-starts all 6 functions Lambdalith cold-starts once, the other 5 are warm In our use case, first-visit experience improved ~2x 24/47

25.

Warm Latency? Nearly Identical ▍Routing overhead was lighter than expected Split Lambda: 88ms Lambdalith (FastAPI): 96ms The cost of a better DX: just 8ms 25/47

26.

Deploy Time Tells the Same Story ▍Fewer functions, fewer definitions — faster deploys Measured with AWS CDK for TypeScript Initial deploy Incremental deploy Split Lambda Lambdalith (FastAPI) 115.7s 62.4s 5.2s 4.2s The initial-deploy gap matters most — faster CI/CD and validation cycles 26/47

27.

Why Lambdalith Wins ▍Optimizing globally beat optimizing locally Split Lambda wins per-request But eliminating repeated cold starts and duplicate loads wins overall Total app execution time dropped, not just individual functions Shared library management simplified Better visibility for dev and ops 27/47

28.

But we weren't done yet 28/47

29.

Beyond Performance — What Came Next ▍Daily operations demanded more than speed Unified logging, tracing, and metrics Observability scattered across middleware and handlers — hard to keep consistent Shared parameter fetching and caching SSM and DynamoDB lookups duplicated everywhere Keep the Lambdalith direction, but make it operationally sustainable 29/47

30.

Enter Lambda Powertools for Python ▍An AWS-native utility library Routing feels like Flask / FastAPI Consistent API for logger / tracer / metrics Built-in parameter retrieval and caching Non-HTTP event sources in the same function Lessons learned, now Lambda-native and maintainable 30/47

31.
[beta]
Familiar Routing for FastAPI Users
▍Almost identical to Flask / FastAPI syntax
from aws_lambda_powertools.event_handler.api_gateway import APIGatewayRestResolver
app = APIGatewayRestResolver(enable_validation=True)
@app.get("/sites/<site_id>")
def get_site(site_id: str):
return {"site_id": site_id}
@app.post("/analysis/run")
def run_analysis():
return {"message": "analysis started"}
def lambda_handler(event, context):
return app.resolve(event, context)

Low migration cost, low cognitive load

31/47

32.
[beta]
All That Middleware Logic? Now It's Clean
▍One decorator for logger and tracer
app = APIGatewayRestResolver()
logger = Logger()
tracer = Tracer()
@app.get("/sites/<site_id>")
@tracer.capture_method
def get_site(site_id: str):
return {"site_id": site_id, "limit": limit}
@logger.inject_lambda_context
@tracer.capture_lambda_handler
def lambda_handler(event, context):
return app.resolve(event, context)

No more verbose middleware boilerplate!

# ← add this

# ← add this
# ← add this

32/47

33.

Built-in Parameter Retrieval and Caching ▍Parameter Store / Secrets Manager made simple from aws_lambda_powertools.utilities import parameters # Fetch from SSM Parameter Store (TTL cache by default) endpoint = parameters.get_parameter("/myapp/api/endpoint") # Fetch from Secrets Manager secret = parameters.get_secret("myapp/db-credentials") # Control cache TTL with max_age (seconds) config = parameters.get_parameter("/myapp/config", max_age=300) No need to implement fetching and caching separately 33/47

34.
[beta]
A Lambdalith That Handles More Than HTTP

FastAPI + LWA assumes HTTP request translation

-> Can't handle EventBridge/SQS events in the same function

Powertools works directly with event/context

Event-source agnostic — no HTTP translation needed
from aws_lambda_powertools.utilities.data_classes import EventBridgeEvent
def lambda_handler(event, context):
if "source" in event: # EventBridge
eb_event = EventBridgeEvent(event)
process_scheduled_task(eb_event.detail)
return
return app.resolve(event, context) # HTTP

34/47

35.

Powertools Didn't Slow Us Down In fact, it was sometimes faster Metric Warm start Cold start (6EPs) Memory usage Deploy (initial) Powertools ASGI (FastAPI) 76ms 96ms 2,377ms 2,986ms 202MB 209MB 67.8s 62.4s Δ -21% -20% -3% +9% 35/47

36.

Lambdalith: done, now... Back to the question we started with 36/47

37.

What Hono RPC Achieved ▍Server types propagate directly to the client How do we get this in Python? -> Pydantic + OpenAPI + codegen gets us there Type sharing Client generation Language barrier Powertools + Hono RPC Pydantic Direct TS type export Via OpenAPI schema Not needed Auto-generated with (same lang) Orval, etc. Can be crossed None (TS -> TS) (Python -> TS) 37/47

38.

The Schema-Driven Big Picture ▍Pydantic Model -> OpenAPI Spec -> Client 1. Define the schema with Pydantic BaseModel from pydantic import BaseModel, Field class Book(BaseModel): book_id:str title: str = Field(max_length=50) price: float = Field(ge=0, le=100) 2. Powertools / FastAPI auto-generates the OpenAPI spec 3. Orval, etc. auto-generates a TypeScript client 4. Frontend calls the API with full type safety 38/47

39.
[beta]
What Developers Write
▍Pydantic Model -> OpenAPI Spec -> Client

1. Define the schema with Pydantic BaseModel
2. Powertools / FastAPI auto-generates the OpenAPI spec
app = APIGatewayRestResolver(enable_validation=True)
app.enable_swagger() # /swagger + OpenAPI JSON auto-published
@app.get("/sites/<site_id>")
def get_site(site_id: str) -> Site:
return site_service.get(site_id)

3. Orval, etc. auto-generates a TypeScript client
4. Frontend calls the API with full type safety

39/47

40.

What Developers Write ▍Pydantic Model -> OpenAPI Spec -> Client 1. Define the schema with Pydantic BaseModel 2. Powertools / FastAPI auto-generates the OpenAPI spec 3. Orval, etc. auto-generates a TypeScript client npx orval --input https://api.example.com/swagger?format=json \ --output ./src/generated 4. Frontend calls the API with full type safety 40/47

41.
[beta]
Auto-Generated TypeScript Client

1. Define the schema with Pydantic BaseModel
2. Powertools / FastAPI auto-generates the OpenAPI
schema
3. Orval, etc. auto-generates a TypeScript client
4. Frontend calls the API with full type safety
export interface Book {
// Auto-generated by Orval — no hand-writing needed
book_id: string;
title: string;
price: number;
}
const { data: book } = useGetBook("S001"); // TanStack Query custom hook — also auto-generated
book.title; // ← inferred as string
book.price; // ← inferred as number

41/47

42.

Evolving to Integration-Level Testing ▍Schemathesis Pure Python OSS Property-based testing tool for Web APIs Verify API correctness without writing a single test $ schemathesis run https://api.example.com/swagger?format=json Drop into CI — verify schema compliance on every push 42/47

43.
[beta]
Schema-Based Testing with Schemathesis
▍Auto-generates test cases from schema definitions
class User(BaseModel):
name: str = Field(min_length=3,
email: str

examples=["Alice"])

Schema-example test

Schema-based random test

{ "name": "Alice", "email": "[email protected]" }

{ "name": "abcdj", "email": "tsm" }

Boundary-value test

Negative test

{ "name": "abc", "email": "[email protected]" }

{ "name": "ab", "email": 1234 }

Exhaustively tests edge cases no human would think of

43/47

44.

Session Wrap-Up 44/47

45.

End-to-End Developer Experience with Python ▍Lambda Powertools x Lambdalith Cold start reduction with measurable performance gains All-in-one integration with AWS services beyond Lambda Simpler code, lower operational overhead ▍Schema-Based Frontend Integration and Testing Auto-generated TypeScript schemas via Orval Integration-level API testing via Schemathesis Powertools + Pydantic: one stack, full coverage 45/47

46.

(Appendix) Cost of Schema-Driven Validation ▍Validation overhead is +38ms Powertools ASGI (FastAPI) Split ON 118ms 113ms 96ms What +38ms buys you OFF 80ms 74ms 66ms Diff +38ms +39ms +30ms Reject invalid input at the API boundary, immediately Auto-generated OpenAPI schema Type propagation to frontend, automated API testing 46/47

47.

(Appendix) ▍Lambdalith (FastAPI) Is Not a Silver Bullet Memory usage Concurrent 50req total Split Lambda Lambdalith (FastAPI) 159MB 209MB 925ms 2,784ms Strong when shared deps are heavy and requests span multiple endpoints Concentrated concurrent workloads require careful design 47/47