Путь Python Workers к готовности к использованию в продакшене

Python Workers появились в Cloudflare два года назад, позволяя запускать Python-приложения в Workers runtime. Цель была простой: сделать написание Workers на Python таким же удобным, как на TypeScript, и обеспечить совместимость с экосистемой Python-пакетов и фреймворков.

Сегодня Python Workers переходят в статус General Availability (GA).

Что это означает? Python теперь — первоклассный, полностью поддерживаемый язык на Cloudflare Developer Platform. Разработчики могут использовать привычный код, библиотеки и паттерны проектирования, подключая их к Workers AI, R2, D1, Hyperdrive, Durable Objects, Queues, Workflows и остальной платформе. Также можно запускать популярные Python-фреймворки — FastAPI, Django, Flask — внутри Python Workers и даже создавать Python Worker внутри другого Worker, используя Dynamic Workers.

from fastapi import FastAPI, Request
from workers import asgi, WorkerEntrypoint

app = FastAPI()

@app.get("/")
async def root(request: Request):
    env = request.scope["env"]
    return await env.AI.run(
        "@cf/openai/gpt-oss-120b",
        {
            "instructions": "You are a friendly assistant.",
            "input": "What is the origin of the phrase Hello, World?",
        },
    )

Default = asgi.entrypoint(app)

История Python Workers

Добавить Python в Cloudflare Workers был естественный выбор. Поскольку Workers поддерживает WebAssembly с 2018 года, это обеспечило идеальное окружение для запуска Wasm-скомпилированного интерпретатора Python. С помощью Pyodide удалось быстро добавить поддержку широкого спектра Python-приложений в Cloudflare Workers.

Цель была создать первую платформу для бесконечно масштабируемых Python-приложений, при этом сохраняя удобство и производительность разработки на Python где угодно.

Функции, которые представляются сегодня, являются результатом многолетних усилий. Многие разработчики уже создают приложения в Python Workers; сейчас эти возможности становятся production-ready для всех.

Python — первоклассный язык в Cloudflare Workers runtime

Python Workers теперь нативно поддерживают bindings Cloudflare Developer Platform. Ранее использование этих bindings в Python Workers требовало явного преобразования Python-объектов в TypeScript-объекты на RPC boundary. Например, отправка Python-словаря в Cloudflare Queue требовала такого code glue:

from pyodide.ffi import to_js
import js

self.env.QUEUE.send(to_js({"key"": "value"}, dict_converter=js.Object.fromEntries))

Это требовало от Python-разработчиков держать в голове JavaScript-окружение и код при написании Python Workers — частый источник ошибок как для людей, так и для AI-агентов. Чтобы решить это, в Workers runtime и Python SDK инкапсулировали весь процесс преобразования типов. Теперь все Cloudflare bindings работают полностью на питоническом уровне без единой строки JavaScript:

self.env.QUEUE.send({"key"": "value"})

Веб-фреймворки: FastAPI, Django и Flask

Теперь можно запускать любимый Python-фреймворк — FastAPI, Django или Flask — для создания API-сервера в Python Workers. Реализована встроенная connector, которая легко подключает веб-приложение к Python Workers.

Например, простое FastAPI-приложение:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    message = "Hello, world!"
    return {"message": message}

В стандартном окружении используется веб-сервер вроде uvicorn:

$ uvicorn main:app

В Python Workers то же приложение запускается с помощью пакета workers.asgi, добавив эту строку:

from workers import asgi

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        return await asgi.fetch(app, request, self.env)

# or equivalently
Default = asgi.entrypoint(app)

Аналогично, пакет workers.wsgi запускает синхронные приложения вроде Django:

from workers import WorkerEntrypoint, wsgi
from your_django_app.wsgi import app

Default = wsgi.entrypoint(app)

Как это работает под капотом?

Python имеет стандартный контракт, как веб-приложения общаются с веб-серверами — Web Server Gateway Interface (WSGI) или его асинхронный аналог ASGI. Этот стандарт позволяет разработчикам создавать приложения, полностью независимые от сервера. В традиционном развёртывании веб-серверы вроде Uvicorn или Gunicorn отвечают за обработку множественных одновременных подключений и потоков масштабирования трафика, пока веб-фреймворки фокусируются на логике приложения.

В Cloudflare Workers сама платформа Workers выступает веб-сервером. Поскольку глобальная сеть Cloudflare уже безупречно обрабатывает балансировку нагрузки и бесконечное масштабирование, не нужно reinvent wheel и запускать сервер внутри Python Workers.

Вместо этого коннекторы workers.asgi и workers.wsgi работают как тонкий, оптимизированный мост. Они преобразуют входящий native JavaScript request в WSGI/ASGI структуры, которые ожидают Python-приложения, и бесшовно пропускают ответ с минимальными затратами. Так разработчики Python получают лучшее из обоих миров: код можно писать и организовать, используя любимые веб-фреймворки, при этом позволяя Cloudflare Workers платформе мгновенно масштабировать API по всему миру без настройки сервера.

Эти коннекторы работают не только с FastAPI, Django или Flask, но с любым Python-фреймворком, использующим интерфейс WSGI или ASGI.

Подробности о каждом фреймворке можно найти в документации Python Workers.

PostgreSQL и MySQL через Hyperdrive

При создании Python-приложения с реляционными БД вроде PostgreSQL или MySQL теперь можно интегрировать Hyperdrive в Python Workers.

Ранее Python Workers не поддерживали TCP-сокеты, из-за чего драйверы БД были недоступны. Чтобы понять, почему это был блокер, нужно посмотреть, как WebAssembly работает. Python-драйверы БД вроде aiomysql или asyncpg полагаются на стандартный библиотечный модуль socket для установления соединений. В стандартном окружении этот модуль делает POSIX системные вызовы к ОС. Внутри WebAssembly sandbox эти POSIX networking syscalls обычно — stub-функции, которые всегда падают. Любая попытка открыть стандартный сокет мгновенно падала. Для решения реализовали системные вызовы сокетов, используя Workers connect API.

Когда драйвер БД пытается открыть TCP-соединение, оно проходит через пользовательскую реализацию socket syscall. Она переводит стандартные Python socket операции (открытие соединения, чтение байтов) в соответствующие JavaScript вызовы, используемые Workers runtime. Поскольку это преобразование происходит на уровне системных вызовов, драйверам БД не нужно ничего знать о реализации.

Именно этот socket bridge делает интеграцию Hyperdrive возможной. Чтобы использовать Hyperdrive в Python Workers, сначала подключите БД к Hyperdrive и задайте binding в конфиге Wrangler:

"hyperdrive": [
    {
        "binding": "HYPERDRIVE_MYSQL",
        "id": "<example id: 57b7076f58be42419276f058a8968187>",
    }
]

Потом подключитесь к Hyperdrive, используя привычные драйверы:

import aiomysql

from workers import WorkerEntrypoint

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        hd = self.env.HYPERDRIVE_MYSQL
        conn = await aiomysql.connect(
            host=hd.host,
            port=int(hd.port),
            user=hd.user,
            password=hd.password,
            db=hd.database,
            ssl=None,
        )

        cur = await conn.cursor()
        await cur.execute("SELECT username FROM user")
        r = await cur.fetchall()
        await cur.close()
        conn.close()

Как использовать Hyperdrive в Python Workers и какие пакеты сейчас поддерживаются, можно посмотреть в документации.

Расширение экосистемы WebAssembly-пакетов

Поскольку Python Workers запускаются внутри WebAssembly sandbox, любые пакеты с native C/C++/Rust расширениями должны быть cross-compiled в WebAssembly для работы в Python Workers. Однако ранее не было стандартного способа cross-compile любого Python-пакета в WebAssembly. Это означало, что команде пришлось вручную компилировать и размещать custom WebAssembly пакеты. Это сильно ограничило количество пакетов, доступных в Python Workers.

Захотелось исправить это и позволить пользователям использовать более широкий спектр пакетов. Однако не хотелось просто создавать пакеты, пригодные только для Python Workers, что не принесло бы пользу сообществу. Поскольку Python Workers построены на Pyodide, хотелось, чтобы экосистема эволюционировала так, чтобы это приносило пользу Pyodide и всему Python-on-WebAssembly сообществу.

Поэтому предложили PEP 783, который стандартизирует платформу для запуска Python в browser runtime, называемую PyEmscripten. После более чем года обсуждений и уточнений предложение было принято, позволяя мейнтейнерам пакетов строить и публиковать пакеты для PyEmscripten платформы и делать их доступными для всех окружений, которые реализуют PyEmscripten.

Также стабилизировали существующий Pyodide build toolchain и эволюционировали его в форму, доступную всем мейнтейнерам пакетов, позволяя разработчикам легко строить пакеты для PyEmscripten платформы. Кроме того, добавили поддержку PyEmscripten платформы в cibuildwheel, чтобы облегчить внедрение этой платформы для других.

Пока экосистема принимает этот стандарт, надеемся, что в будущем каждый Python-пакет будет иметь wheel, работающий с WebAssembly. Активно работают с мейнтейнерами крупных пакетов, чтобы добавить PyEmscripten builds. Если встретили пакет, который ещё не поддерживается, напишите на Discord или GitHub — команда будет работать над его сборкой.

AI-агенты и pipeline-ы на Python

Большая экосистема data science и machine learning пакетов делает Python естественным выбором для создания intelligent agent-ов и AI pipeline-ов. Однако исторически это представляло вызов в Python Workers: библиотеки вроде openai и langchain полагаются на HTTP client-ы вроде requests или httpx для общения с внешними API. Однако из-за отсутствия поддержки низкоуровневых socket операций в Python Workers эти HTTP client-ы не работали должным образом.

Для решения внесли вклад upstream, чтобы эти HTTP client-ы могли маршрутизировать запросы напрямую через JavaScript fetch API в WebAssembly окружениях. В сочетании с новой поддержкой низкоуровневых socket операций это делает весь networking stack работающим бесшумно внутри Python Workers.

Результат: теперь можно запускать AI библиотеки вроде openai, langchain и mcp нативно в Python Workers. Можно также комбинировать их с Workers AI для запуска serverless inference на GPU-ях в сети Cloudflare или проксировать запросы через Cloudflare AI Gateway.

Пример ниже показывает, как запустить Worker AI модели в langchain, используя пакет langchain-cloudflare:

from langchain_cloudflare import ChatCloudflareWorkersAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from workers import Response, WorkerEntrypoint

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        prompt = PromptTemplate.from_template(
            "In one sentence, describe a great day in the life of an {profession}."
        )
        llm = ChatCloudflareWorkersAI(
            model_name="@cf/meta/llama-3.3-70b-instruct-fp8-fast",
            binding=self.env.AI,
            max_tokens=64,
        )
        chain = prompt | llm | StrOutputParser()

        result = await chain.ainvoke({"profession"": "electrician"})
        return Response.json({"result"": result})

Что можно построить сегодня

Собрали коллекцию production-ready паттернов в репозитории python-workers-examples. Вот несколько способов, как можно комбинировать Python Workers с экосистемой Cloudflare.

Асинхронная оркестрация AI

Построение full-stack AI приложения часто означает подключение множественных сервисов вроде storage, queuing и inference. Этот пример показывает, как построить AI-driven image-to-image generator полностью на Python Workers. Приложение принимает запросы пользователя, бросает их в Cloudflare Queue и использует Workflows для оркестрации генерации изображения через Workers AI, сохраняя результат в R2 bucket.

Обработка real-time потоков с Bluesky Jetstream

Потребление firehose real-time событий обычно требует dedicated server для поддержания соединения. В этом примере используется Python Worker для подключения к ATProto/Bluesky Jetstream WebSocket. Благодаря backing этого соединения Durable Object, Python Worker может поддерживать long-lived состояние, обеспечивая, что WebSocket соединение остаётся живым.

Ещё примеры для изучения

Model Context Protocol (MCP) Server

Постройте и разверните MCP server, используя официальный Python MCP пакет, чтобы дать AI ассистентам доступ к edge data.

RAG система с Vectorize

Построение RAG системы используя Workers AI и Vectorize, vector database Cloudflare.

Примеры кода на Python во всей документации Cloudflare

Обновили документацию во всех Cloudflare продуктах, включив примеры кода на Python. Почти везде, где есть пример кода, показывающий, как что-то сделать на TypeScript, теперь есть тоже пример на Python. Обязались продолжать включать примеры на Python во всех продуктах. На всей developer documentation можно переключаться между примерами на JavaScript, TypeScript и Python.

Что дальше?

Достижение GA — только начало. Много планов, чтобы сделать Python Workers лучше, включая повышение производительности и снижение потребления памяти, а также поддержку большего количества пакетов.

Продолжайте рассказывать, что вы хотите построить на Python Workers, и команда будет двигать границы возможного. Посмотрите документацию Python Workers и начните строить свой первый Python Worker!