메뉴
HN
Hacker News • 4일 전

Cloudflare Python Workers 정식 출시(GA)

IMP
7/10
핵심 요약

Cloudflare가 Python Workers를 정식 버전(GA)으로 출시했습니다. 이제 Python이 Cloudflare 개발자 플랫폼에서 1급 언어로 완전 지원되며, FastAPI, Django, Flask 같은 인기 프레임워크를 Workers에서 실행할 수 있게 되었습니다. 기존에 필요했던 JavaScript 타입 변환 코드 없이 순수한 Python 코드만으로 Cloudflare의 모든 바인딩(R2, D1, Queues 등)을 사용할 수 있게 된 점이 핵심입니다.

번역된 본문

2년 전 저희는 Cloudflare Workers 런타임에서 Python 애플리케이션을 실행할 수 있는 방법으로 Python Workers를 선보였습니다. TypeScript로 Workers를 작성하는 것만큼 Python으로도 간단하게 작성할 수 있게 하고, Python 패키지와 프레임워크 생태계가 '그냥 동작'하도록 만드는 것이 목표였습니다. 오늘, Python Workers가 정식 출시(GA, General Availability)되었습니다.

GA는 무엇을 의미할까요? 이제 Python이 Cloudflare 개발자 플랫폼에서 완전히 지원되는 1급 언어가 되었다는 뜻입니다. 이미 알고 있는 Python 코드, 라이브러리, 디자인 패턴을 그대로 가져와 Workers AI, R2, D1, Hyperdrive, Durable Objects, Queues, Workflows 등 Cloudflare 플랫폼 전체와 원활하게 연결할 수 있습니다. FastAPI, Django, Flask 같은 인기 Python 프레임워크도 Python Workers 안에서 실행할 수 있습니다. 심지어 Dynamic Workers를 사용하면 다른 Worker 안에서 Python Worker를 생성할 수도 있습니다.

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는 2018년부터 WebAssembly를 지원해왔기 때문에, Wasm으로 컴파일된 Python 인터프리터를 실행하기에 완벽한 환경이었습니다. Pyodide를 활용함으로써 광범위한 Python 애플리케이션을 Cloudflare Workers에서 빠르게 지원할 수 있었습니다. 저희의 목표는 어디에서든 Python 앱을 개발하는 것만큼 쉽고 고성능으로, 무한히 확장 가능한 Python 앱을 위한 최초의 플랫폼을 만드는 것이었습니다. 오늘 소개하는 기능들은 이런 수년간의 노력의 결과입니다. 이미 많은 개발자들이 Python Workers로 애플리케이션을 구축하고 있으며, 오늘부터 이러한 기능들이 모두를 위한 프로덕션 수준으로 준비되었습니다.

Python은 이제 Cloudflare Workers 런타임의 1급 언어입니다

Python Workers는 이제 Cloudflare 개발자 플랫폼 바인딩을 네이티브로 지원합니다. 이전에는 Python Workers에서 이러한 Cloudflare 바인딩을 사용할 때 RPC 경계에서 Python 객체를 TypeScript 객체로 명시적으로 변환해야 했습니다. 예를 들어, Python 딕셔너리를 Cloudflare Queue로 보내려면 다음과 같은 접착 코드(glue code)가 필요했습니다:

from pyodide.ffi import to_js
import js

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

이 방식은 Python 개발자가 Python Workers를 작성하면서도 JavaScript 환경과 코드를 항상 신경 써야 했고, 사람과 AI 에이전트 모두에게 흔한 오류의 원인이었습니다. 이를 해결하기 위해 저희는 전체 타입 변환 과정을 Workers 런타임과 Python SDK 내부에 캡슐화했습니다. 덕분에 JavaScript 코드를 한 줄도 작성하지 않고 모든 Cloudflare 바인딩을 Python다운 방식으로 활용할 수 있으며, 다음 코드가 그대로 동작합니다:

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

웹 프레임워크: FastAPI, Django, Flask

이제 좋아하는 Python 프레임워크(FastAPI, Django, Flask 등)를 사용해 Python Workers에서 API 서버를 구축할 수 있습니다. 웹 애플리케이션을 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)

# 또는 동일하게
Default = asgi.entrypoint(app)

마찬가지로 workers.wsgi 패키지를 사용하면 Django 같은 동기식 웹 애플리케이션을 실행할 수 있습니다.

원문 보기
원문 보기 (영어)
We introduced Python Workers two years ago, providing a way to run Python applications in the Cloudflare Workers runtime. Our goal was to make it as simple to write Workers in Python as it is in TypeScript, and to make the ecosystem of Python packages and frameworks “just work”. Today, Python Workers are now generally available (GA). What does GA mean? It means Python is now a first-class, fully supported language on the Cloudflare Developer Platform. You can bring the Python code, libraries, and design patterns you already know and connect them seamlessly to Workers AI, R2, D1, Hyperdrive, Durable Objects, Queues, Workflows, and the rest of the Cloudflare platform. You can also run popular Python frameworks like FastAPI, Django, and Flask inside Python Workers. You can even create a Python Worker inside another Worker using 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) The journey behind Python Workers Bringing Python to Cloudflare Workers was a natural choice. Because Workers has supported WebAssembly since 2018 , it gave us the perfect environment to run a Wasm-compiled Python interpreter. By using Pyodide , we were able to quickly support a wide range of Python applications in Cloudflare Workers. Our goal was to create the first platform for infinitely scalable Python apps, while making it as easy and performant as developing Python apps anywhere else. The features we are highlighting today are the result of this multi-year effort. Many developers are already building applications within Python Workers; today, we are making these capabilities production-ready for everyone. Python is now a first-class language in the Cloudflare Workers runtime Python Workers now natively support Cloudflare Developer Platform bindings. Previously, using these Cloudflare bindings in Python Workers required converting Python objects into TypeScript objects explicitly at the RPC boundary. For example, sending a Python dictionary into a Cloudflare Queue required the following glue code to work: from pyodide.ffi import to_js import js self .env. QUEUE .send(to_js({ "key" : "value" }, dict_converter = js.Object.fromEntries)) This required Python developers to keep the JavaScript environment and code in mind while writing Python Workers, and it was a common source of error for both humans and AI agents. To address this, we have encapsulated the entire type conversion process within the Workers runtime and the Python SDK. This allows you to utilize all Cloudflare bindings in a Pythonic way without writing a single line of JavaScript code, making the following just work: self .env. QUEUE .send({ "key" : "value" }) Web frameworks: FastAPI, Django, and Flask You can now run your favorite Python framework, such as FastAPI, Django, or Flask, to build an API server in Python Workers. We implemented a built-in connector that you can use to easily connect your web application to Python Workers. Let’s say you have a simple FastAPI web application: from fastapi import FastAPI app = FastAPI() @app.get ( "/" ) async def root (): message = "Hello, world!" return { "message" : message} In native environments, you would use a web server such as uvicorn to run this application. $ uvicorn main:app In Python Workers, you can run the same application using the workers.asgi package we provide, just by adding this snippet to your code: 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) Similarly, you can use workers.wsgi package to run synchronous web applications such as Django. from workers import WorkerEntrypoint, wsgi from your_django_app.wsgi import app Default = wsgi.entrypoint(app) So, what happens under the hood? Python has a standard contract for how web applications should communicate with web servers, known as the Web Server Gateway Interface (WSGI), or its modern asynchronous counterpart, ASGI. This standard allows developers to build applications that are completely server-agnostic. In a traditional deployment, web servers like Uvicorn or Gunicorn are responsible for handling multiple concurrent client connections and threads to scale traffic, while web frameworks like FastAPI can focus purely on the application logic. In Cloudflare Workers, the Workers platform itself serves as the web server. Since our global network already seamlessly handles load balancing and infinite scaling, we don't need to reinvent the wheel by running a server inside Python Workers. Instead, our workers.asgi and workers.wsgi connectors act as a thin, optimized bridge. They translate the incoming native JavaScript request into the standard WSGI/ASGI structures that Python applications expect, and seamlessly pipe the response back out with minimal overhead. By doing this, Python developers get the best of both worlds: you can write and organize code using your favorite web frameworks, while letting the Cloudflare Workers platform instantly scale your API across the globe, without ever configuring a server. These connectors can be used not only with FastAPI, Django, or Flask, but with any Python web framework that uses the WSGI or ASGI interface. You can find more information about using each web framework in the Python Workers documentation . Using PostgreSQL and MySQL with Hyperdrive If you are building a Python application using relational databases such as PostgreSQL or MySQL, you can now integrate Hyperdrive into Python Workers. Previously, Python Workers didn’t support TCP sockets, making database drivers unavailable. To understand why this was a blocker, you need to look at how WebAssembly operates. Python database drivers like aiomysql or asyncpg rely on the standard library's socket module to establish connections. In a standard environment, this module makes POSIX system calls to the underlying operating system. Inside a WebAssembly sandbox, those POSIX networking syscalls are normally stubs that always fail. Any attempt to open a standard socket would immediately fail. To solve this problem, we implemented socket system calls using the Workers connect API. When a database driver attempts to open a TCP connection, it goes through our custom socket syscall implementation. It translates standard Python socket operations like opening a connection and reading bytes into the corresponding JavaScript calls used by the Workers runtime. Because this translation happens at the system call level, your database drivers don't have to know about the underlying implementation at all. This socket bridge is what makes our Hyperdrive integration possible. To use Hyperdrive in Python Workers, first connect your database with Hyperdrive and set up the binding in the Wrangler config: "hyperdrive" : [ { "binding" : "HYPERDRIVE_MYSQL" , "id" : "<example id: 57b7076f58be42419276f058a8968187>" , } ] Then, connect to Hyperdrive using the database drivers you are familiar with: 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() You can refer to the Hyperdrive Python Workers documentation to find out how you can use Hyperdrive in Python Workers, and which packages are currently supported. Expanding the WebAssembly package ecosystem Because Python Workers run ins