mcpField
P
python-cloudflare

python-cloudflare

github.com/josiahsiegel云与 DevOps5972 次安装19 周前更新
代码仓库

关于 python-cloudflare

python-cloudflare 是一项介绍在 Cloudflare 部署 Python 应用的技能,面向构建边缘 API、重计算服务或长时工作流的开发者。内容涵盖 Python Workers、Containers 和开发部署流程。

主要功能

  1. 01Python Workers 与 Pyodide
  2. 02FastAPI 部署模式
  3. 03Containers 重计算方案
  4. 04环境变量与服务绑定
  5. 05Python Workflows 持久执行
  6. 06本地开发与部署命令

适用场景

  1. 01在边缘运行 Python API
  2. 02将 FastAPI 部署到 Workers
  3. 03使用容器运行 Pandas 或 AI 工具链
  4. 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):
FastAPIawait 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 对比建议
简单 APIWorker
pandas/numpyContainer
GPU/AIContainer
延迟 <50msWorker

何时使用此技能

用于 Cloudflare 边缘部署:

  • 将 Python API 部署到 Cloudflare Workers
  • 在 Cloudflare 边缘运行 FastAPI
  • 使用 Containers 进行密集计算
  • 设置服务间 RPC
  • 优化冷启动

相关技能:

  • 对于 FastAPI,请参阅 python-fastapi
  • 对于异步模式,请参阅 python-asyncio
  • 对于 Docker,请参阅 python-github-actions

在 Cloudflare 上运行 Python(Workers 与 Containers)

概述

Cloudflare 提供两种运行 Python 的方式:

  1. Python Workers - 使用 Pyodide(WebAssembly)的无服务器函数
  2. 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
功能WorkersContainers
冷启动约 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