workers-runtime-sdk 1.6.15__tar.gz → 1.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/CHANGELOG.md +13 -0
  2. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/PKG-INFO +1 -1
  3. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/pyproject.toml +1 -1
  4. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/asgi.py +13 -1
  5. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/request.py +9 -3
  6. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/response.py +2 -19
  7. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/utils.py +20 -0
  8. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/_client.py +17 -0
  9. workers_runtime_sdk-1.7.0/tests/web-frameworks-test/fastapi-tests/src/test_platform_io.py +31 -0
  10. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/test_routing.py +9 -0
  11. workers_runtime_sdk-1.7.0/tests/web-frameworks-test/fastapi-tests/src/test_websocket.py +39 -0
  12. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/worker.py +65 -46
  13. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/sdk/tests/test_sdk.py +5 -0
  14. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/uv.lock +1 -1
  15. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/.gitignore +0 -0
  16. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/AGENTS.md +0 -0
  17. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/README.md +0 -0
  18. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/_cloudflare_compat_flags.pyi +0 -0
  19. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/_pyodide_entrypoint_helper.pyi +0 -0
  20. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/_workers_sdk_entropy_import_context.py +0 -0
  21. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/_workers_sdk_package_patches.py +0 -0
  22. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/_workers_sdk_patch_loader.pth +0 -0
  23. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/_workers_sdk_patch_loader.py +0 -0
  24. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/asgi.py +0 -0
  25. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/__init__.py +0 -0
  26. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/blob.py +0 -0
  27. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/entrypoints.py +0 -0
  28. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/fetch.py +0 -0
  29. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/formdata.py +0 -0
  30. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/py.typed +0 -0
  31. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/rpc.py +0 -0
  32. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/types.py +0 -0
  33. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/workflows.py +0 -0
  34. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/src/workers/wsgi.py +0 -0
  35. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/public/data.json +0 -0
  36. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/public/hello.txt +0 -0
  37. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/pyproject.toml +0 -0
  38. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/conftest.py +0 -0
  39. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_analytics_engine.py +0 -0
  40. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_assets.py +0 -0
  41. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_d1.py +0 -0
  42. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_do.py +0 -0
  43. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_hyperdrive_mysql.py +0 -0
  44. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_hyperdrive_postgresql.py +0 -0
  45. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_images.py +0 -0
  46. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_kv.py +0 -0
  47. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_mtls.py +0 -0
  48. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_queue.py +0 -0
  49. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_r2.py +0 -0
  50. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_ratelimit.py +0 -0
  51. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_vectorize.py +0 -0
  52. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_version_metadata.py +0 -0
  53. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/test_workflow.py +0 -0
  54. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/worker.py +0 -0
  55. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/worker_durable_object.py +0 -0
  56. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/src/worker_workflow.py +0 -0
  57. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/bindings-test/wrangler.jsonc +0 -0
  58. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/conftest.py +0 -0
  59. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/test_bindings.py +0 -0
  60. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/test_fastapi.py +0 -0
  61. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/test_in_workerd.py +0 -0
  62. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/test_web_frameworks.py +0 -0
  63. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/pyproject.toml +0 -0
  64. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/_client.py +0 -0
  65. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/conftest.py +0 -0
  66. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/__init__.py +0 -0
  67. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/api_urls.py +0 -0
  68. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/auth_backend.py +0 -0
  69. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/drf_auth.py +0 -0
  70. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/drf_serializers.py +0 -0
  71. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/drf_throttling.py +0 -0
  72. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/drf_views.py +0 -0
  73. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/forms.py +0 -0
  74. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/middleware.py +0 -0
  75. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/templatetags/__init__.py +0 -0
  76. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/templatetags/custom_tags.py +0 -0
  77. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/urls.py +0 -0
  78. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/django_app/views.py +0 -0
  79. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/templates/base.html +0 -0
  80. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/templates/context_test.html +0 -0
  81. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/templates/csrf_form.html +0 -0
  82. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/templates/hello.html +0 -0
  83. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_async_utilities.py +0 -0
  84. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_auth.py +0 -0
  85. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_caching.py +0 -0
  86. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_cors.py +0 -0
  87. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_csrf.py +0 -0
  88. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_drf_auth_permissions.py +0 -0
  89. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_drf_content_negotiation.py +0 -0
  90. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_drf_serializers.py +0 -0
  91. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_drf_throttling.py +0 -0
  92. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_drf_versioning.py +0 -0
  93. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_drf_views.py +0 -0
  94. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_error_handling.py +0 -0
  95. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_file_uploads.py +0 -0
  96. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_forms.py +0 -0
  97. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_middleware.py +0 -0
  98. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_pagination.py +0 -0
  99. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_request_response.py +0 -0
  100. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_sessions.py +0 -0
  101. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_signals.py +0 -0
  102. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_streaming.py +0 -0
  103. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_templates.py +0 -0
  104. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_url_routing.py +0 -0
  105. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/test_views_basic.py +0 -0
  106. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/src/worker.py +0 -0
  107. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/django-async/wrangler.jsonc +0 -0
  108. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/public/data.json +0 -0
  109. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/public/index.html +0 -0
  110. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/public/style.css +0 -0
  111. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/pyproject.toml +0 -0
  112. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/conftest.py +0 -0
  113. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/static/app.css +0 -0
  114. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/static/data.json +0 -0
  115. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/static/hello.txt +0 -0
  116. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/static/index.html +0 -0
  117. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/test_assets.py +0 -0
  118. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/test_error_handling.py +0 -0
  119. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/test_platform_lifecycle.py +0 -0
  120. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/test_response_types.py +0 -0
  121. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/test_staticfiles.py +0 -0
  122. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/src/test_sync_handlers.py +0 -0
  123. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/web-frameworks-test/fastapi-tests/wrangler.jsonc +0 -0
  124. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi/asgi.wd-test +0 -0
  125. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi/pyproject.toml +0 -0
  126. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi/tests/test_asgi.py +0 -0
  127. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi/worker.py +0 -0
  128. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi/wrangler.jsonc +0 -0
  129. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi-ws-disconnect/asgi-ws-disconnect.wd-test +0 -0
  130. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi-ws-disconnect/pyproject.toml +0 -0
  131. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi-ws-disconnect/tests/test_ws_disconnect.py +0 -0
  132. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi-ws-disconnect/worker.py +0 -0
  133. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/asgi-ws-disconnect/wrangler.jsonc +0 -0
  134. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object/durable-object.wd-test +0 -0
  135. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object/pyproject.toml +0 -0
  136. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object/worker.py +0 -0
  137. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object/wrangler.jsonc +0 -0
  138. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-abort/durable-object-abort.wd-test +0 -0
  139. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-abort/pyproject.toml +0 -0
  140. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-abort/worker.py +0 -0
  141. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-abort/wrangler.jsonc +0 -0
  142. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-inheritance/durable-object-inheritance.wd-test +0 -0
  143. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-inheritance/pyproject.toml +0 -0
  144. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-inheritance/worker.py +0 -0
  145. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-inheritance/wrangler.jsonc +0 -0
  146. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-websocket/durable-object-websocket.wd-test +0 -0
  147. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-websocket/pyproject.toml +0 -0
  148. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-websocket/tester.js +0 -0
  149. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-websocket/worker.py +0 -0
  150. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/durable-object-websocket/wrangler.jsonc +0 -0
  151. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/entropy-patches.wd-test +0 -0
  152. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/pyproject.toml +0 -0
  153. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/tests/test_aiohttp_websocket.py +0 -0
  154. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/tests/test_langsmith.py +0 -0
  155. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/tests/test_numpy.py +0 -0
  156. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/tests/test_pydantic.py +0 -0
  157. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/tests/test_rust_packages.py +0 -0
  158. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/tests/test_ssl_avoidance.py +0 -0
  159. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/worker.py +0 -0
  160. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/entropy-patches/wrangler.jsonc +0 -0
  161. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/python-rpc/pyproject.toml +0 -0
  162. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/python-rpc/python-rpc.wd-test +0 -0
  163. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/python-rpc/worker.js +0 -0
  164. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/python-rpc/worker.py +0 -0
  165. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/python-rpc/wrangler.jsonc +0 -0
  166. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/sdk/pyproject.toml +0 -0
  167. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/sdk/sdk.wd-test +0 -0
  168. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/sdk/server.py +0 -0
  169. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/sdk/worker.py +0 -0
  170. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/sdk/wrangler.jsonc +0 -0
  171. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/wsgi/pyproject.toml +0 -0
  172. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/wsgi/tests/test_wsgi.py +0 -0
  173. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/wsgi/worker.py +0 -0
  174. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/wsgi/wrangler.jsonc +0 -0
  175. {workers_runtime_sdk-1.6.15 → workers_runtime_sdk-1.7.0}/tests/workerd-test/wsgi/wsgi.wd-test +0 -0
@@ -2,6 +2,19 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v1.7.0 (2026-08-24)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Fixes Request body being released too early
10
+ ([`84a20ac`](https://github.com/cloudflare/workers-py/commit/84a20acbfa28ea82fb69b2c279a56d9e25fd9639))
11
+
12
+ ### Features
13
+
14
+ - Asgi.entrypoint syntax sugar for nicer asgi apps
15
+ ([`5399270`](https://github.com/cloudflare/workers-py/commit/539927085a79e2d88a287cc70ccfa433ec257e1d))
16
+
17
+
5
18
  ## v1.6.15 (2026-08-21)
6
19
 
7
20
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: workers-runtime-sdk
3
- Version: 1.6.15
3
+ Version: 1.7.0
4
4
  Summary: Python SDK for Cloudflare Workers
5
5
  Project-URL: Homepage, https://github.com/cloudflare/workers-py
6
6
  Project-URL: Bug Tracker, https://github.com/cloudflare/workers-py/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "workers-runtime-sdk"
7
- version = "1.6.15"
7
+ version = "1.7.0"
8
8
  description = "Python SDK for Cloudflare Workers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -7,7 +7,7 @@ from urllib.parse import unquote
7
7
 
8
8
  import js
9
9
 
10
- from workers import Context, Request
10
+ from workers import Context, Request, WorkerEntrypoint
11
11
  from workers.utils import _to_js_headers
12
12
 
13
13
  ASGI = {"spec_version": "2.0", "version": "3.0"}
@@ -415,6 +415,18 @@ async def websocket(
415
415
  return await process_websocket(app, req, env)
416
416
 
417
417
 
418
+ def entrypoint(app: Any) -> type[WorkerEntrypoint]:
419
+ """Create the default Worker entrypoint for an ASGI application."""
420
+
421
+ class Default(WorkerEntrypoint):
422
+ async def fetch(self, request):
423
+ if (request.headers.get("upgrade") or "").lower() == "websocket":
424
+ return await websocket(app, request, self.env)
425
+ return await fetch(app, request, self.env, self.ctx)
426
+
427
+ return Default
428
+
429
+
418
430
  def __getattr__(name):
419
431
  if name == "env":
420
432
  from fastapi import Depends, Request
@@ -9,6 +9,7 @@ from .blob import Blob
9
9
  from .formdata import FormData
10
10
  from .types import FetchKwargs
11
11
  from .utils import (
12
+ _get_js_body,
12
13
  _is_js_instance,
13
14
  _js_headers_to_http_message,
14
15
  _jsnull_to_none,
@@ -36,9 +37,14 @@ class Request:
36
37
 
37
38
  if "headers" in other_options:
38
39
  other_options["headers"] = _to_js_headers(other_options["headers"])
39
- self._js_request = js.Request.new(
40
- input._js_request if isinstance(input, Request) else input, **other_options
41
- )
40
+ body = other_options.pop("body", None)
41
+ with _get_js_body(body) as js_body:
42
+ if body is not None:
43
+ other_options["body"] = js_body
44
+ self._js_request = js.Request.new(
45
+ input._js_request if isinstance(input, Request) else input,
46
+ **other_options,
47
+ )
42
48
 
43
49
  def __repr__(self):
44
50
  return (
@@ -1,17 +1,17 @@
1
1
  import json
2
- from contextlib import contextmanager
3
2
  from http import HTTPStatus
4
3
  from typing import Any, Never
5
4
 
6
5
  import js
7
6
  import pyodide.http
8
- from pyodide.ffi import JsException, JsProxy, create_proxy
7
+ from pyodide.ffi import JsException, JsProxy
9
8
 
10
9
  from .blob import Blob
11
10
  from .formdata import FormData
12
11
  from .types import Body, Headers
13
12
  from .utils import (
14
13
  RESPONSE_ACCEPTED_TYPES,
14
+ _get_js_body,
15
15
  _get_js_constructor_name,
16
16
  _is_js_instance,
17
17
  _js_headers_to_http_message,
@@ -21,23 +21,6 @@ from .utils import (
21
21
  )
22
22
 
23
23
 
24
- @contextmanager
25
- def _get_js_body(body):
26
- if isinstance(body, bytes):
27
- proxy_bytes = create_proxy(body)
28
- proxy_buffer = proxy_bytes.getBuffer()
29
- try:
30
- yield proxy_buffer.data
31
- return
32
- finally:
33
- proxy_buffer.release()
34
- proxy_bytes.destroy()
35
- if isinstance(body, FormData):
36
- yield body.js_object
37
- return
38
- yield body
39
-
40
-
41
24
  class FetchResponse(pyodide.http.FetchResponse):
42
25
  # TODO: Consider upstreaming the `body` attribute
43
26
  # TODO: Behind a compat flag make this return a native stream (StreamReader?), or perhaps
@@ -6,6 +6,7 @@ import _pyodide_entrypoint_helper
6
6
  import js
7
7
  from pyodide.ffi import (
8
8
  JsException,
9
+ create_proxy,
9
10
  destroy_proxies,
10
11
  to_js,
11
12
  )
@@ -51,6 +52,25 @@ _JS_PASSTHROUGH_TYPES = RESPONSE_ACCEPTED_TYPES | {
51
52
  }
52
53
 
53
54
 
55
+ @contextmanager
56
+ def _get_js_body(body):
57
+ from .formdata import FormData
58
+
59
+ if isinstance(body, bytes):
60
+ proxy_bytes = create_proxy(body)
61
+ proxy_buffer = proxy_bytes.getBuffer()
62
+ try:
63
+ yield proxy_buffer.data
64
+ return
65
+ finally:
66
+ proxy_buffer.release()
67
+ proxy_bytes.destroy()
68
+ if isinstance(body, FormData):
69
+ yield body.js_object
70
+ return
71
+ yield body
72
+
73
+
54
74
  def _jsnull_to_none(x):
55
75
  if x is jsnull:
56
76
  return None
@@ -46,6 +46,23 @@ async def post_json(app, path, data, **kwargs):
46
46
  )
47
47
 
48
48
 
49
+ def build_multipart_bytes(files, boundary="----WebTestBoundary"):
50
+ """Build a binary-safe multipart body from (name, filename, bytes) tuples."""
51
+ body = bytearray()
52
+ for name, filename, content in files:
53
+ if isinstance(content, str):
54
+ content = content.encode()
55
+ body.extend(f"--{boundary}\r\n".encode())
56
+ body.extend(
57
+ f'Content-Disposition: form-data; name="{name}"; filename="{filename}"\r\n'.encode()
58
+ )
59
+ body.extend(b"Content-Type: application/octet-stream\r\n\r\n")
60
+ body.extend(content)
61
+ body.extend(b"\r\n")
62
+ body.extend(f"--{boundary}--\r\n".encode())
63
+ return bytes(body), f"multipart/form-data; boundary={boundary}"
64
+
65
+
49
66
  def build_multipart(files, boundary="----WebTestBoundary"):
50
67
  """Build a multipart/form-data body from a list of (name, filename, content) tuples."""
51
68
  lines = []
@@ -0,0 +1,31 @@
1
+ """Binary I/O tests across FastAPI, Pyodide, and workerd."""
2
+
3
+ import hashlib
4
+
5
+ import pytest
6
+ from _client import build_multipart_bytes, fetch, read_json
7
+
8
+
9
+ @pytest.mark.asyncio
10
+ async def test_upload_spills_binary_file_to_virtual_disk(fastapi_app):
11
+ """UploadFile remains correct after SpooledTemporaryFile rolls to disk."""
12
+ payload = bytes(range(256)) * 5120 # 1.25 MiB, above Starlette's 1 MiB limit.
13
+ body, content_type = build_multipart_bytes(
14
+ [("file", "binary.dat", payload)], boundary="----SpoolBoundary"
15
+ )
16
+
17
+ resp = await fetch(
18
+ fastapi_app,
19
+ "/platform/upload-spooled",
20
+ method="POST",
21
+ headers={"Content-Type": content_type},
22
+ body=body,
23
+ )
24
+ assert resp.status == 200
25
+ data = await read_json(resp)
26
+ assert data == {
27
+ "size": len(payload),
28
+ "sha256": hashlib.sha256(payload).hexdigest(),
29
+ "reread_matches": True,
30
+ "rolled_to_disk": True,
31
+ }
@@ -20,6 +20,15 @@ These are relevant for Pyodide/Workers because:
20
20
 
21
21
  import pytest
22
22
  from _client import fetch, get_json, read_json
23
+ from worker import Default
24
+
25
+ from workers import WorkerEntrypoint
26
+
27
+
28
+ def test_asgi_entrypoint_factory():
29
+ assert Default.__name__ == "Default"
30
+ assert issubclass(Default, WorkerEntrypoint)
31
+
23
32
 
24
33
  # -- Path parameters ---------------------------------------------------------
25
34
 
@@ -0,0 +1,39 @@
1
+ import asyncio
2
+
3
+ import pytest
4
+ from pyodide.ffi import create_proxy
5
+ from worker import Default
6
+
7
+ from workers import Request
8
+
9
+ TIMEOUT_S = 5
10
+ _proxies = []
11
+
12
+
13
+ @pytest.mark.asyncio
14
+ async def test_generated_entrypoint_serves_fastapi_websocket():
15
+ entrypoint = object.__new__(Default)
16
+ entrypoint.env = {}
17
+ request = Request(
18
+ "http://testserver/websocket/echo", headers={"Upgrade": "websocket"}
19
+ )
20
+
21
+ response = await entrypoint.fetch(request)
22
+ assert response.status == 101
23
+
24
+ websocket = response.webSocket
25
+ websocket.accept()
26
+ message = asyncio.get_event_loop().create_future()
27
+
28
+ def onmessage(event):
29
+ if not message.done():
30
+ message.set_result(event.data)
31
+
32
+ proxy = create_proxy(onmessage)
33
+ _proxies.append(proxy)
34
+ websocket.addEventListener("message", proxy)
35
+ try:
36
+ websocket.send("hello")
37
+ assert await asyncio.wait_for(message, TIMEOUT_S) == "echo:hello"
38
+ finally:
39
+ websocket.close()
@@ -1,5 +1,6 @@
1
1
  import asyncio
2
2
  import enum
3
+ import hashlib
3
4
  import importlib.util
4
5
  from contextlib import asynccontextmanager
5
6
  from pathlib import Path
@@ -15,6 +16,7 @@ from fastapi import (
15
16
  Query,
16
17
  Request,
17
18
  UploadFile,
19
+ WebSocket,
18
20
  )
19
21
  from fastapi.exceptions import HTTPException
20
22
  from fastapi.responses import (
@@ -32,7 +34,6 @@ from pyodide.webloop import WebLoop
32
34
  from starlette.background import BackgroundTask
33
35
 
34
36
  import asgi
35
- from workers import Response, WorkerEntrypoint
36
37
 
37
38
 
38
39
  async def _noop(*args):
@@ -82,6 +83,14 @@ async def health():
82
83
  return {"ok": True}
83
84
 
84
85
 
86
+ @app.websocket("/websocket/echo")
87
+ async def websocket_echo(websocket: WebSocket):
88
+ await websocket.accept()
89
+ message = await websocket.receive_text()
90
+ await websocket.send_text(f"echo:{message}")
91
+ await websocket.close()
92
+
93
+
85
94
  # -- sync route handler (dispatched via run_in_threadpool) -------------------
86
95
  @app.get("/sync/hello")
87
96
  def sync_hello():
@@ -436,6 +445,24 @@ async def platform_lifespan_state(request: Request):
436
445
  return {"available": True, "closed": resource.closed}
437
446
 
438
447
 
448
+ # --------------------------------------------------------------------------- #
449
+ # Pyodide and Workers platform boundary routes
450
+ # --------------------------------------------------------------------------- #
451
+
452
+
453
+ @app.post("/platform/upload-spooled")
454
+ async def platform_upload_spooled(file: UploadFile = File(...)): # noqa: B008
455
+ first = await file.read()
456
+ await file.seek(0)
457
+ second = await file.read()
458
+ return {
459
+ "size": len(first),
460
+ "sha256": hashlib.sha256(first).hexdigest(),
461
+ "reread_matches": first == second,
462
+ "rolled_to_disk": bool(getattr(file.file, "_rolled", False)),
463
+ }
464
+
465
+
439
466
  @app.get("/native-file")
440
467
  async def native_file():
441
468
  """Serve a single bundled file with FastAPI's native FileResponse."""
@@ -447,17 +474,6 @@ async def native_file():
447
474
  app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
448
475
 
449
476
 
450
- @app.get("/{path:path}")
451
- async def frontend(path: str, request: Request):
452
- """Proxy static asset requests to the Workers Assets binding."""
453
- env = request.scope["env"]
454
- asset_url = f"https://assets.local/{path}"
455
- resp = await env.ASSETS.fetch(asset_url)
456
- body = await resp.bytes()
457
- headers = dict(resp.headers)
458
- return FastAPIResponse(content=body, status_code=resp.status, headers=headers)
459
-
460
-
461
477
  class ResultCollector:
462
478
  def __init__(self):
463
479
  self.results = {}
@@ -524,37 +540,40 @@ class FastAPIAppPlugin:
524
540
  return app
525
541
 
526
542
 
527
- class Default(WorkerEntrypoint):
528
- async def fetch(self, request):
529
- from urllib.parse import urlparse
530
-
531
- path = urlparse(request.url).path
532
-
533
- if path.startswith("/run-tests/"):
534
- suite_name = path[len("/run-tests/") :]
535
- return self._run_suite(suite_name)
536
-
537
- return await asgi.fetch(app, request, self.env, self.ctx)
538
-
539
- def _run_suite(self, suite_name):
540
- module = f"test_{suite_name}"
541
- if importlib.util.find_spec(module) is None:
542
- return Response.json(
543
- {"error": f"Unknown suite '{suite_name}' (no module '{module}')"},
544
- status=404,
545
- )
546
-
547
- collector = ResultCollector()
548
- saved_loop = asyncio.events._get_running_loop()
549
- try:
550
- pytest.main(
551
- ["--pyargs", module, "-p", "no:cacheprovider"],
552
- plugins=[
553
- collector,
554
- EnvPlugin(self.env),
555
- FastAPIAppPlugin(),
556
- ],
557
- )
558
- finally:
559
- asyncio.events._set_running_loop(saved_loop)
560
- return Response.json(collector.results)
543
+ @app.get("/run-tests/{suite_name:path}")
544
+ async def run_suite(suite_name: str, request: Request):
545
+ module = f"test_{suite_name}"
546
+ if importlib.util.find_spec(module) is None:
547
+ return JSONResponse(
548
+ {"error": f"Unknown suite '{suite_name}' (no module '{module}')"},
549
+ status_code=404,
550
+ )
551
+
552
+ collector = ResultCollector()
553
+ saved_loop = asyncio.events._get_running_loop()
554
+ try:
555
+ pytest.main(
556
+ ["--pyargs", module, "-p", "no:cacheprovider"],
557
+ plugins=[
558
+ collector,
559
+ EnvPlugin(request.scope["env"]),
560
+ FastAPIAppPlugin(),
561
+ ],
562
+ )
563
+ finally:
564
+ asyncio.events._set_running_loop(saved_loop)
565
+ return collector.results
566
+
567
+
568
+ @app.get("/{path:path}")
569
+ async def frontend(path: str, request: Request):
570
+ """Proxy static asset requests to the Workers Assets binding."""
571
+ env = request.scope["env"]
572
+ asset_url = f"https://assets.local/{path}"
573
+ resp = await env.ASSETS.fetch(asset_url)
574
+ body = await resp.bytes()
575
+ headers = dict(resp.headers)
576
+ return FastAPIResponse(content=body, status_code=resp.status, headers=headers)
577
+
578
+
579
+ Default = asgi.entrypoint(app)
@@ -436,6 +436,11 @@ async def test_request_unit_tests():
436
436
  blob = await req_for_blob.blob()
437
437
  assert (await blob.text()) == "foobar"
438
438
 
439
+ # Verify that Python bytes are converted without UTF-8 decoding or truncation.
440
+ binary_body = bytes(range(256))
441
+ req_for_bytes = Request("http://example.com", body=binary_body, method="POST")
442
+ assert await req_for_bytes.bytes() == binary_body
443
+
439
444
  # Verify that we can get a FormData back.
440
445
  js_form_data = js.FormData.new()
441
446
  js_form_data.append("foobar", 123)
@@ -345,7 +345,7 @@ wheels = [
345
345
 
346
346
  [[package]]
347
347
  name = "workers-runtime-sdk"
348
- version = "1.6.15"
348
+ version = "1.7.0"
349
349
  source = { editable = "." }
350
350
 
351
351
  [package.dev-dependencies]