关于 python-cloudflare
python-cloudflare 是一项介绍在 Cloudflare 部署 Python 应用的技能,面向构建边缘 API、重计算服务或长时工作流的开发者。内容涵盖 Python Workers、Containers 和开发部署流程。
主要功能
- 01Python Workers 与 Pyodide
- 02FastAPI 部署模式
- 03Containers 重计算方案
- 04环境变量与服务绑定
- 05Python Workflows 持久执行
- 06本地开发与部署命令
适用场景
- 01在边缘运行 Python API
- 02将 FastAPI 部署到 Workers
- 03使用容器运行 Pandas 或 AI 工具链
- 04构建带重试和状态持久化的流程
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill python-cloudflare安装后在 Claude Code 中输入/python-cloudflare确认已加载。
详细介绍
快速参考
| 平台 | 冷启动 | 软件包 | 最适用场景 |
|---|---|---|---|
| Workers(Pyodide) | 约 50ms | 有限 | API 端点 |
| Containers | 约 10s | 任意 | 密集计算、AI |
| Worker 模式 | 代码 |
|---|---|
| 基本处理程序 | class Default(WorkerEntrypoint): |
| FastAPI | await asgi.fetch(app, request, self.env) |
| 环境变量 | self.env.API_KEY |
| 服务绑定 | await self.env.WORKER_B.method() |
| 命令 | 用途 |
|---|---|
pywrangler init | 创建 Python Worker |
pywrangler dev | 本地开发 |
pywrangler deploy | 部署到 Cloudflare |
| Containers 与 Worker 对比 | 建议 |
|---|---|
| 简单 API | Worker |
| pandas/numpy | Container |
| GPU/AI | Container |
| 延迟 <50ms | Worker |
何时使用此技能
用于 Cloudflare 边缘部署:
- 将 Python API 部署到 Cloudflare Workers
- 在 Cloudflare 边缘运行 FastAPI
- 使用 Containers 进行密集计算
- 设置服务间 RPC
- 优化冷启动
相关技能:
- 对于 FastAPI,请参阅
python-fastapi - 对于异步模式,请参阅
python-asyncio - 对于 Docker,请参阅
python-github-actions
在 Cloudflare 上运行 Python(Workers 与 Containers)
概述
Cloudflare 提供两种运行 Python 的方式:
- Python Workers - 使用 Pyodide(WebAssembly)的无服务器函数
- Cloudflare Containers - 完整的 Docker 容器(测试版,2025 年 6 月)
Python Workers
工作原理
- Python 通过 Pyodide 运行(编译为 WebAssembly 的 CPython)
- 在 Cloudflare 边缘网络上的 V8 隔离环境中执行
- 内存快照可实现快速冷启动
- 支持许多纯 Python 软件包
快速入门
# Install pywrangler (Python Workers CLI)
pip install pywrangler
# Create new Python Worker
pywrangler init my-worker
cd my-worker
# Project structure
my-worker/
├── src/
│ └── entry.py
├── pyproject.toml
└── wrangler.toml
基本 Worker
# src/entry.py
from workers import Response, WorkerEntrypoint
class Default(WorkerEntrypoint):
async def fetch(self, request):
return Response("Hello from Python Worker!")
配置
# wrangler.toml
name = "my-python-worker"
main = "src/entry.py"
compatibility_date = "2024-12-01"
[build]
command = ""
# pyproject.toml
[project]
name = "my-python-worker"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"fastapi",
"pydantic",
]
[dependency-groups]
dev = ["workers-py"]
在 Workers 上运行 FastAPI
# src/entry.py
from workers import WorkerEntrypoint
from fastapi import FastAPI, Request
from pydantic import BaseModel
app = FastAPI()
class Default(WorkerEntrypoint):
async def fetch(self, request):
import asgi
return await asgi.fetch(app, request, self.env)
@app.get("/")
async def root():
return {"message": "Hello from FastAPI on Cloudflare!"}
@app.get("/env")
async def get_env(req: Request):
env = req.scope.get("env")
if env and hasattr(env, "API_KEY"):
return {"has_api_key": True}
return {"has_api_key": False}
class Item(BaseModel):
name: str
price: float
description: str | None = None
@app.post("/items/")
async def create_item(item: Item):
return item
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
使用环境变量
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint):
async def fetch(self, request):
# Access environment variables via self.env
api_key = self.env.API_KEY
database_url = self.env.DATABASE_URL
return Response(f"API Key exists: {bool(api_key)}")
# wrangler.toml
[vars]
API_KEY = "your-api-key"
DATABASE_URL = "your-database-url"
服务绑定(RPC)
# Worker A - Caller
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint):
async def fetch(self, request):
# Call Worker B's add method
result = await self.env.WORKER_B.add(1, 2)
return Response(f"Result: {result}")
# Worker B - Callee
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint):
async def fetch(self, request):
return Response("Hello from Worker B")
def add(self, a: int, b: int) -> int:
return a + b
# Worker A wrangler.toml
[[services]]
binding = "WORKER_B"
service = "worker-b"
缓存
from workers import WorkerEntrypoint
from pyodide.ffi import to_js as _to_js
from js import Response, URL, Object, fetch
def to_js(x):
return _to_js(x, dict_converter=Object.fromEntries)
class Default(WorkerEntrypoint):
async def fetch(self, request):
request_url = URL.new(request.url)
params = request_url.searchParams
tags = params["tags"].split(",") if "tags" in params else []
url = params["uri"] or None
if url is None:
return Response.json(to_js({"error": "URL required"}), status=400)
# Fetch with cache tags
options = {"cf": {"cacheTags": tags}}
result = await fetch(url, to_js(options))
cache_status = result.headers["cf-cache-status"]
return Response.json(to_js({
"cache": cache_status,
"status": result.status
}))
支持的软件包
# HTTP clients (async only)
import aiohttp
import httpx
# Data processing
import numpy # Limited support
import pandas # Limited support
# Standard library works well
import json
import re
import urllib
import base64
import hashlib
# Check Pyodide package list for full support
# https://pyodide.org/en/stable/usage/packages-in-pyodide.html
冷启动优化
# Imports at module level are cached in memory snapshot
import json
import hashlib
from pydantic import BaseModel
# This code runs during snapshot creation
CACHED_CONFIG = load_config()
class Default(WorkerEntrypoint):
async def fetch(self, request):
# Fast access to pre-loaded modules and data
return Response(json.dumps(CACHED_CONFIG))
Cloudflare Containers(测试版)
概述(2025 年 6 月)
- 支持完整的 Docker 容器
- 可运行任意语言/运行时(Python、Go、Java 等)
- 支持 FFmpeg、Pandas 和 AI 工具链
- 按使用量计费
- 全球边缘部署
何时使用 Containers 与 Workers
| 功能 | Workers | Containers |
|---|---|---|
| 冷启动 | 约 50ms | 约 10s(使用预热) |
| 软件包支持 | 兼容 Pyodide | 任意 |
| 内存 | 有限 | 可配置 |
| 文件系统 | 否 | 是 |
| 原生二进制文件 | 否 | 是 |
| 最适用场景 | API 端点 | 批处理任务、AI、密集计算 |
Container 设置
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY . .
# Run application
CMD ["python", "main.py"]
# main.py
import pandas as pd
import numpy as np
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/process")
async def process_data():
# Heavy computation that wouldn't work in Workers
df = pd.DataFrame(np.random.randn(10000, 4))
result = df.describe().to_dict()
return result
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8080)
Wrangler 命令
# Build container
wrangler containers build . --tag my-app:latest
# Push to registry
wrangler containers push my-app:latest
# Deploy
wrangler containers deploy my-app
# List containers
wrangler containers list
# Delete
wrangler containers delete my-app
Container 优化
# Multi-stage build for smaller images
FROM python:3.12-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt --target=/app/deps
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app/deps /app/deps
COPY . .
ENV PYTHONPATH=/app/deps
CMD ["python", "main.py"]
# Optimize for container cold starts
import asyncio
# Lazy imports for faster startup
def get_pandas():
import pandas as pd
return pd
async def process_large_data():
pd = get_pandas() # Import only when needed
# Process data...
GPU 支持(预览版)
# Container with GPU support
import torch
def run_inference(data):
device = "cuda" if torch.cuda.is_available() else "cpu"
model = load_model().to(device)
with torch.no_grad():
result = model(data.to(device))
return result.cpu().numpy()
Python 工作流(持久化执行)
概述
Cloudflare Workflows 现已支持 Python,可用于构建多步骤、长时间运行的应用,并提供自动重试和状态持久化。
from cloudflare.workflows import Workflow, step
class DataPipeline(Workflow):
@step
async def fetch_data(self, url: str) -> dict:
"""Fetch data from external API."""
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
@step
async def process_data(self, data: dict) -> dict:
"""Process the fetched data."""
# Heavy processing - will retry if fails
processed = transform(data)
return processed
@step
async def save_results(self, data: dict) -> str:
"""Save to database."""
result_id = await save_to_db(data)
return result_id
async def run(self, input_url: str) -> str:
data = await self.fetch_data(input_url)
processed = await self.process_data(data)
result_id = await self.save_results(processed)
return f"Saved as {result_id}"
最佳实践
1. 尽量减少冷启动
# Do expensive imports at module level
import json
import hashlib
from pydantic import BaseModel
# Pre-compute static data
STATIC_CONFIG = {"version": "1.0", "features": ["a", "b"]}
class Default(WorkerEntrypoint):
async def fetch(self, request):
# Fast path - no initialization needed
return Response(json.dumps(STATIC_CONFIG))
2. 使用异步 HTTP 客户端
# Workers only support async HTTP
import httpx
class Default(WorkerEntrypoint):
async def fetch(self, request):
async with httpx.AsyncClient() as client:
response = await client.get("https://api.example.com/data")
return Response(response.text)
3. 妥善处理错误
from workers import WorkerEntrypoint, Response
class Default(WorkerEntrypoint):
async def fetch(self, request):
try:
result = await self.process_request(request)
return Response(json.dumps(result), headers={
"Content-Type": "application/json"
})
except ValueError as e:
return Response(json.dumps({"error": str(e)}), status=400)
except Exception as e:
# Log error (sent to Workers Logs)
print(f"Error: {e}")
return Response(json.dumps({"error": "Internal error"}), status=500)
4. 采用便于测试的结构
# src/handlers.py - Pure Python logic
async def handle_create_item(data: dict) -> dict:
# Testable without Worker runtime
validated = validate_item(data)
return {"id": generate_id(), **validated}
# src/entry.py - Worker entrypoint
from workers import WorkerEntrypoint, Response
from handlers import handle_create_item
class Default(WorkerEntrypoint):
async def fetch(self, request):
if request.method == "POST":
data = await request.json()
result = await handle_create_item(data)
return Response(json.dumps(result))
5. 本地开发
# Start local development server
pywrangler dev
# Test locally
curl http://localhost:8787/
# Deploy to Cloudflare
pywrangler deploy
评论
支持 Markdown