Hacker News

Python Workers are now generally available

Python Workers 정식 출시

Cloudflare가 WebAssembly 기반 Python Workers를 정식 출시했습니다. Pyodide를 바탕으로 FastAPI·Django·Flask, PostgreSQL·MySQL, AI 라이브러리와 Cloudflare의 Workers 서비스 연동을 지원하며, 패키지 호환성을 넓히는 표준화 작업도 진행했습니다.

AI 요약

Cloudflare가 2년간 공개 베타로 운영한 Python Workers를 Generally Available(GA) 단계로 올렸습니다. Python을 Cloudflare Workers의 정식 지원 언어로 제공하며, 기존 Python 코드와 라이브러리를 Workers AI, R2, D1, Hyperdrive, Durable Objects, Queues, Workflows 같은 서비스에 연결합니다. FastAPI, Django, Flask 같은 웹 프레임워크도 별도 서버 없이 실행합니다.

Python 객체와 Cloudflare 바인딩을 직접 연결합니다

초기 Python Workers에서는 Python 객체를 JavaScript 객체로 변환해야 했습니다. 예를 들어 Queue에 Python 딕셔너리를 보내려면 pyodide.ffi.to_jsjs.Object.fromEntries를 직접 사용해야 했습니다. 이제 Workers 런타임과 Python SDK가 RPC 경계에서 타입 변환을 처리합니다. Python 코드에서 self.env.QUEUE.send({"key": "value"})처럼 작성하면 됩니다. JavaScript 환경의 객체 변환 방식을 따로 고려하지 않아도 됩니다.

Python Workers는 Cloudflare의 다른 바인딩도 같은 방식으로 사용합니다. Dynamic Workers를 이용하면 한 Worker 안에서 다른 Python Worker를 만들 수도 있습니다.

ASGI와 WSGI로 FastAPI·Django·Flask를 실행합니다

Cloudflare는 workers.asgiworkers.wsgi 커넥터를 제공합니다. FastAPI 애플리케이션은 asgi.entrypoint(app)을 추가해 Worker 진입점으로 연결합니다. Django처럼 동기식 애플리케이션은 wsgi.entrypoint(app)을 사용합니다. 별도로 Uvicorn이나 Gunicorn을 실행하지 않습니다.

ASGI와 WSGI는 웹 애플리케이션과 서버 사이의 표준 인터페이스입니다. 기존 환경에서는 Uvicorn이나 Gunicorn이 여러 연결과 스레드를 처리하고, FastAPI 같은 프레임워크가 애플리케이션 로직을 담당합니다. Python Workers에서는 Workers 플랫폼이 웹 서버 역할을 맡습니다. 전 세계 Cloudflare 네트워크가 로드 밸런싱과 확장을 처리하고, 커넥터는 JavaScript 요청을 ASGI·WSGI 구조로 바꾸고 응답을 다시 전달하는 얇은 연결 계층으로 동작합니다. 두 인터페이스를 사용하는 다른 Python 웹 프레임워크에도 적용할 수 있습니다.

Hyperdrive로 PostgreSQL과 MySQL에 연결합니다

WebAssembly 환경에서는 POSIX 네트워크 시스템 호출이 기본적으로 동작하지 않아 aiomysql, asyncpg 같은 데이터베이스 드라이버가 TCP 연결을 열 수 없었습니다. Cloudflare는 Workers의 connect API를 이용해 Python 소켓 시스템 호출을 구현했습니다.

드라이버가 TCP 연결이나 바이트 읽기를 요청하면, Python의 표준 소켓 연산을 Workers 런타임의 JavaScript 호출로 변환합니다. 드라이버는 이 구현을 알 필요가 없습니다. 사용자는 Wrangler 설정에 Hyperdrive 바인딩을 등록한 뒤 self.env.HYPERDRIVE_MYSQL에서 호스트, 포트, 사용자, 비밀번호, 데이터베이스 정보를 받아 기존 드라이버로 연결합니다. 현재 지원 패키지 목록은 Hyperdrive Python Workers 문서에서 확인해야 합니다.

PyEmscripten으로 WebAssembly 패키지 생태계를 넓힙니다

Python Workers는 Pyodide 위에서 실행되므로 C, C++, Rust 확장을 포함한 패키지는 WebAssembly용으로 다시 빌드해야 합니다. 이전에는 Cloudflare 팀이 패키지를 직접 컴파일해 별도로 호스팅해야 했습니다. 지원 패키지 수가 제한된 이유입니다.

Cloudflare는 Python을 브라우저 런타임에서 실행하기 위한 플랫폼을 표준화하는 PEP 783을 제안했고, 1년 넘는 논의 끝에 채택됐다고 설명합니다. 이 표준에 따라 패키지 관리자는 PyEmscripten용 wheel을 만들고, 같은 표준을 구현한 여러 환경에 배포할 수 있습니다. Pyodide 빌드 도구 체계를 안정화하고, 패키지 관리자가 직접 사용할 수 있도록 다듬었습니다. cibuildwheel에도 PyEmscripten 지원을 추가했습니다.

아직 생태계가 표준을 채택하는 과정이지만, 장기적으로 Python 패키지가 WebAssembly에서 동작하는 wheel을 제공하기를 기대한다고 밝혔습니다.

AI 라이브러리와 Workers AI를 함께 사용합니다

기존 Python Workers에서는 requestshttpx 같은 HTTP 클라이언트가 의존하는 저수준 소켓 연산이 부족해 openai, langchain 같은 라이브러리를 제대로 실행하기 어려웠습니다. Cloudflare는 HTTP 클라이언트가 WebAssembly 환경에서 JavaScript fetch API로 요청을 보낼 수 있도록 관련 프로젝트에 기여했습니다. 소켓 시스템 호출 지원과 결합해 Python의 네트워크 계층을 Workers에 맞췄습니다.

이제 openai, langchain, mcp를 Python Workers에서 사용합니다. langchain-cloudflare 패키지로 Workers AI 모델을 호출하거나, AI Gateway를 거쳐 외부 모델 요청을 보낼 수 있습니다. 예시에서는 ChatCloudflareWorkersAI@cf/meta/llama-3.3-70b-instruct-fp8-fast 모델과 AI 바인딩을 연결해 비동기 체인을 실행합니다.

제공되는 애플리케이션 예시

Python Workers 예제 저장소에는 여러 Cloudflare 서비스를 조합한 패턴이 포함됩니다. 이미지 변환 생성기는 요청을 Queue에 넣고, Workflows로 Workers AI 이미지 생성 과정을 조정한 뒤 결과를 R2에 저장합니다. Bluesky Jetstream 예제는 Durable Object로 장기 상태를 유지하면서 ATProto WebSocket 연결을 계속 유지합니다.

그 밖에 Python MCP 서버, Workers AI와 Vectorize를 사용하는 RAG 시스템 예제도 제공합니다. Cloudflare 개발자 문서의 TypeScript 예제 상당수에는 Python 예제도 추가했으며, 코드 조각 언어를 JavaScript·TypeScript·Python 사이에서 전환하도록 했습니다. 이후에는 성능과 메모리 효율을 개선하고 지원 패키지를 더 늘릴 계획입니다.

Hacker News 반응

  • @dsign — 물론 Cloudflare의 기술 이야기겠지만, 제목을 처음 봤을 때는 “Python 코더를 전부 AI로 대체했고, 그 코더들이 이제 일반에 공개됐다”는 뜻으로 읽었습니다. :-)
    • @Joeboy — 저도 처음에는 소프트웨어 개발자 채용 시장의 암울한 상황을 다룬 제목인 줄 알았습니다.
    • @FartyMcFarter — 저도 바로 “클라우드에서 고용할 수 있는 Python SWE 서비스” 같은 내용이라고 생각했습니다.
  • @stefan_lec — 콜드 스타트 성능은 어떤가요? Workers에서 WebAssembly를 사용할 때 시작 시간이 더 걸리는 것이 단점이라고 기억합니다. 혹시 이 문제를 해결했나요?
    • @dom96 — 이전 블로그 글에 콜드 스타트 수치가 있습니다. 아직 더 개선할 부분이 있고, 다음 작업의 초점이 될 예정입니다. https://blog.cloudflare.com/python-workers-advancements/
    • @hbcondo714 — AWS MicroVM의 Firecracker VM과 Fly.io Sprites를 사용하고 있습니다. Workers에도 관심이 있습니다. https://news.ycombinator.com/item?id=48642510 https://news.ycombinator.com/item?id=46557825
    • @aeyes — 해당 블로그 글의 콜드 스타트 수치는 AWS Lambda보다 빠르다고 보여주지만, 제가 연결한 벤치마크 페이지에서는 Lambda가 훨씬 빠르고 일관성도 높습니다. https://cold.picheta.me/#bare
    • @dom96 — 링크가 잘못된 것 같습니다. https://cold.picheta.me/#packages를 가리켜야 합니다.
    • @amenghra — 많은 경우 콜드 스타트 시간은 사용자에게 보이지 않을 수 있습니다. 정적 콘텐츠를 CDN에서 제공하고, 로컬 저장소에 있는 오래된 콘텐츠를 먼저 보여주면서 최신 데이터를 가져오는 식입니다. 전체 과정이 100밀리초 아래라면 상당히 즉각적으로 느껴질 수도 있습니다.
  • @spicypixel — 언젠가는 Go도 그만큼 간단하게 사용할 수 있으면 좋겠습니다.
    • @vira28 — 동의합니다. 그때까지 기다리겠습니다. 그래도 마침내 Python 지원을 추가한 것은 반갑습니다.
    • @OutOfHere — 제가 알기로 Go를 WebAssembly에서 실행하는 것은 불가능합니다.
    • @ncruces — Go 컴파일러는 기본적으로 wasm/js 브라우저 대상과 wasm/wasip1 WASI 대상을 지원합니다.
  • @karmakaze — Mojo도 지원해야 합니다. 엣지 컴퓨팅에 잘 맞을 수 있습니다.
  • @victorbjorklund — 다음은 Elixir로 해주세요. Worker 간 클러스터링도 함께요. Elixir가 Cloudflare Workers에 맞지 않을 것 같다는 점을 감안한 농담입니다.
  • @simonw — Pyodide는 Python 생태계에서 정말 멋진 프로젝트입니다. Cloudflare가 Pyodide에 자금을 지원하는 것도 고려하면 좋겠습니다. https://opencollective.com/pyodide/contribute
    • @codingglass — 전적으로 동의합니다. 몇 년 전 Hood를 영입한 것은 그 프로젝트에 돈을 잘 쓴 사례였습니다. 더 지원하지 말아야 한다는 뜻은 아닙니다. =)
    • @simonw — Hood Chatham이 링크한 글의 저자 중 한 명이라는 사실을 놓쳤습니다. Pyodide에 대한 상당한 후원이라고 봐도 되겠네요.
    • @dom96 — 저자 중 한 명인 Gyeongjae도 Pyodide 핵심 개발자입니다. 두 사람의 도움 없이는 Python Workers가 여기까지 오기 어려웠습니다.
  • @pastrami_panda — 모든 예제 페이지가 404를 반환합니다.
  • @illia-v — “HTTP 클라이언트가 WebAssembly 환경에서 JavaScript fetch API로 직접 요청을 보내도록 upstream에 기여했다”는 부분에 맥락을 덧붙이고 싶습니다. urllib3 유지 관리자의 설명에 따르면 urllib3은 몇 년 전 Pyodide·Emscripten 지원을 추가하는 큰 기여를 받았고, 이후 JSPI 지원도 추가했습니다. 이 변경이 Requests에서 동작하게 만든 기반입니다. 제가 아는 한 이 작업의 자금은 urllib3 유지 관리자들이 아니라 구현한 외부 기여자에게 전달됐습니다. urllib3 프로젝트는 변경을 검토하고 병합했으며, 이제 결과로 생긴 백엔드를 유지 관리합니다.

이 차이가 중요한 이유는 upstream 프로젝트에 기능 구현 비용을 지원하는 것과, 이후 해당 기능을 유지해야 하는 upstream 유지 관리자에게 자금을 지원하는 일이 다르기 때문입니다. urllib3의 Emscripten 백엔드는 아직 실험 단계이며 보안 정책에서도 명시적으로 범위 밖입니다. CVE-2025-50182는 그 과정에서 생긴 문제의 한 예입니다. fetch를 통해 요청을 보낼 때 urllib3의 리디렉션 제어가 예상대로 동작하지 않았습니다. 브라우저와 fetch의 네트워크 의미가 일반적인 urllib3 백엔드와 다르기 때문에 비슷한 차이가 더 있을 수 있습니다. 이 작업이 upstream에 기여되어 Pyodide와 Cloudflare에 유용하게 쓰이는 점은 반갑지만, 그에 따른 지원 책임까지 고려해야 합니다.

↳ @pbreit — 요즘 개발의 절반이 네트워크 요청인데, “네이티브” HTTP 클라이언트가 이렇게 부실하거나 아예 없는 경우가 많다는 점은 늘 이상했습니다.

↳ @syrusakbary — 몇 년 전 제가 남긴 댓글의 다른 문제를 보여주는 사례라고 생각합니다. Pyodide와 Cloudflare는 HTTP 요청에 실제 네트워크 스택을 사용하지 않고, 함수를 패치해 내부에서 JavaScript fetch를 사용합니다. Python의 비동기 이벤트 루프도 JavaScript 이벤트 루프를 사용하도록 패치했습니다. 이 방식에는 호환성 문제가 생깁니다. JavaScript 이벤트 루프는 명시적인 await를 기다리지 않고 비동기 함수를 실행하는 반면, Python은 await할 때까지 실행하지 않습니다. 네트워크 의미를 그대로 보존해야 한다고 생각합니다. 동작이 달라지면 문제가 생깁니다. https://news.ycombinator.com/item?id=39907240

↳ @hoodchatham — “JavaScript 이벤트 루프가 선점형이다”보다는 “eager”라는 표현이 맞는 것 같습니다. 선점형은 보통 시그널 핸들러처럼 명시적인 양보 지점을 기다리지 않고 정상 실행을 중단하는 경우를 말합니다. 어쨌든 WebLoop에서는 Python 코루틴이 lazy하게 동작합니다. Python 이벤트 루프가 구현해야 하는 기본 연산은 call_later()이며, 이는 setTimeout()으로 비교적 깔끔하게 연결됩니다. JavaScript 이벤트 루프를 사용하는 이유는 JavaScript 런타임의 실제 I/O 이벤트가 그곳에서 발생하기 때문입니다. 별도의 이벤트 루프를 실행하면 실제 JavaScript I/O를 막습니다. 따라서 uvloop를 동작시키는 것은 의미가 없습니다.

↳ @hoodchatham — Pyodide가 브라우저에서 실제 네트워크 스택을 사용할 수 없는 이유는 브라우저의 기본 보안 원칙 때문입니다. 직접 네트워킹을 허용하면 CORS 제한을 우회할 수 있습니다. Gyeongjae Choi의 작업 덕분에 Node와 Cloudflare의 Pyodide에서는 직접 소켓을 사용할 수 있습니다. 원문 글의 PostgreSQL·MySQL 연동 부분에 설명되어 있습니다. https://blog.cloudflare.com/python-workers-ga/#using-postgre...

  • @syrusakbary — Cloudflare 팀의 작업을 반갑게 봅니다. 2년 전 Python Workers가 처음 나왔을 때부터 관심이 컸습니다. Wasmer에도 경쟁 제품이 있지만, Cloudflare의 작업은 늘 흥미롭고 참고할 만합니다. 초기 출시 글에서 제가 제기한 의견을 다시 확인해 봤는데, 패키지 지원을 포함해 의미 있는 진전이 있었습니다. PyEmscripten이 PEP 783으로 표준화된 점도 좋습니다.

다만 당시의 구조적 우려 중 일부는 여전히 남아 있습니다. Workerd에 포함된 하나의 Python·Pyodide 버전에 묶이는 점, JavaScript와 V8 구조에 묶여 콜드 스타트 시간을 줄이는 과정에서 문제가 생길 수 있다는 점입니다. 현재 구조로 100밀리초 아래의 시작 시간을 달성하기는 어렵다고 생각합니다. 올해 초 저희 벤치마크에서는 Wasmer Edge의 최소 Python 애플리케이션이 약 60밀리초에 시작했고, Cloudflare Workers는 약 900밀리초였습니다. 수치는 몇 달 전 자료이므로 지금은 크게 개선됐기를 바랍니다. 이번 GA 발표에는 최신 콜드 스타트 수치가 없습니다. Python Workers의 현재 p50·p95 콜드 스타트 시간을, 네이티브 사용자 패키지가 있는 경우와 없는 경우로 나눠 공유할 수 있나요?

↳ @dom96 — Python 버전 하나에만 묶인다는 설명은 정확하지 않습니다. 호환성 플래그로 버전을 선택할 수 있습니다. 예를 들어 python_workers_314는 Python 3.14용 플래그이고, 3.13과 3.12용 플래그도 있습니다. 다만 이전 버전을 선택하면 더 오래된 Pyodide도 함께 사용하므로 JSPI 같은 기능이 빠질 수 있습니다. V8 구조가 콜드 스타트 개선에 어려움을 주는 점은 맞습니다. 그래도 메모리 스냅샷 구현으로 시작 시간을 크게 줄였고, 추가 개선을 진행하고 있습니다. 샤딩으로 콜드 스타트 발생 빈도도 낮췄습니다. https://blog.cloudflare.com/python-workers-advancements/

↳ @syrusakbary — 설명 감사합니다. 이전 버전의 Python을 선택하면 해당 Python 버전뿐 아니라 Workerd도 함께 바뀐다는 점이 제가 말한 문제를 잘 보여줍니다. 예를 들어 JSPI가 포함된 이전 Python 버전을 사용하려면 이전 Workerd도 함께 업데이트해야 하는 것으로 보입니다. Workerd가 발전할수록 이 구조가 문제가 될 수 있습니다. 공유해 준 글에서는 Cloudflare Python Workers의 시작 시간이 약 1.027초였습니다. Wasmer의 Python 앱 콜드 스타트는 60밀리초로 16배 빠릅니다. 그래서 최신 측정 결과를 요청한 것입니다.

  • @indigodaddy — FastHTML은 지원하지 않나요?
  • @appveyor — Workers는 어떤 Pyodide 버전에서 실행되나요? 마지막으로 확인했을 때는 0.28.x였습니다.
  • @xnx — PHP와 Perl이 그렇게 조롱받았는데, 결국 비슷한 방식으로 다시 발명되는 모습이 놀랍습니다.
  • @manquer — 2008년에 Python 2.5 지원으로 출시된 GAE로 다시 돌아온 것 아닌가요? https://googleappengine.blogspot.com/2008/04/introducing-goo...

원문: Hacker News / 번역·요약: Trawling