Getting Started with Python Workers
Python Workers brings first-class Python support to Cloudflare's edge network. Deploy globally distributed Python applications with zero containers, no Kubernetes, and no cold starts worth worrying about.
Your First Python Worker
A Python Worker is as simple as defining an on_fetch handler. This is the entry point for every HTTP request:
from js import Response
async def on_fetch(request):
return Response.new("Hello from Python on the edge!") That's it. That's a globally deployed Python application. No containers, no WSGI servers, no infrastructure to manage.
What's Included
Python Workers come with a rich set of capabilities out of the box:
- Standard library support — Most of
asyncio,json,datetime,re,urlliband friends - Popular packages pre-installed — FastAPI, httpx, numpy, pandas, LangChain, and more
- FFI bridge — Call JavaScript APIs when needed, but write Python everywhere else
- All Cloudflare bindings — Native access to KV, R2, D1, Queues, and the entire platform
The on_fetch Handler
The on_fetch handler is an async function that receives a Request object and returns a Response. You can access request properties like URL, method, headers, and body:
from js import Response, env
async def on_fetch(request):
url = request.url
method = request.method
headers = dict(request.headers)
if url.pathname == "/health":
return Response.json({
"status": "healthy",
"method": method
})
return Response.new("Hello, World!") Environment Bindings
Cloudflare services are accessed through environment bindings. Import env from js to access KV, R2, D1, Queues, AI, and more:
from js import Response, env
async def on_fetch(request):
# Access KV
value = await env.KV.get("my-key")
# Access D1 database
results = await env.DB.prepare("SELECT * FROM users").all()
# Access R2 bucket
object = await env.BUCKET.get("file.txt")
# Access AI
response = await env.AI.run("@cf/meta/llama-3-8b-instruct",
messages=[{"role": "user", "content": "Hello"}]
)
return Response.json({"data": results}) Wrangler Configuration
Configure your Worker's bindings in wrangler.toml:
name = "my-python-worker"
main = "main.py"
compatibility_date = "2024-01-01"
[[kv_namespaces]]
binding = "KV"
id = "your-kv-namespace-id"
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "my-bucket"
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "your-database-id"
[ai]
binding = "AI" Development Setup
Get up and running with local development using Wrangler:
# Install wrangler (once)
bun install -g wrangler
# Local development with hot reload
wrangler dev main.py
# Run tests — just regular Python
python -m pytest
# Deploy to production (30 seconds to global deployment)
wrangler deploy FastAPI Integration
FastAPI works natively in Python Workers. Your existing FastAPI knowledge transfers directly:
from fastapi import FastAPI
from js import Response
app = FastAPI()
@app.get("/api/users/{user_id}")
async def get_user(user_id: int):
result = await env.DB.prepare(
"SELECT * FROM users WHERE id = ?"
).bind(user_id).first()
return {"user": result}
# That's it. Deploy with: wrangler deploy Secrets Management
Store sensitive values securely with Wrangler secrets:
# Set secrets (encrypted at rest)
wrangler secret put DATABASE_URL
wrangler secret put API_KEY
# Access in code
async def on_fetch(request):
db_url = env.DATABASE_URL # Securely injected Why Python Workers?
- Edge-First Architecture — Your code runs <50ms from users globally. No region selection. No multi-region complexity.
- Billing That Makes Sense — Pay for what you use. No idle servers. First 100k requests/day free.
- Security by Default — Automatic DDoS protection, WAF rules, and rate limiting.
- Ecosystem Integration — SQLAlchemy patterns work with D1. Boto3 works with R2. FastAPI works in Workers.
- No Ops Required — No Kubernetes. No Docker. No load balancers. No auto-scaling groups. Just Python.