workers-runtime-sdk 1.6.12__tar.gz → 1.6.13__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 (167) hide show
  1. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/CHANGELOG.md +9 -0
  2. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/PKG-INFO +1 -1
  3. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/pyproject.toml +1 -1
  4. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/asgi.py +7 -4
  5. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/pyproject.toml +1 -0
  6. workers_runtime_sdk-1.6.13/tests/web-frameworks-test/fastapi-tests/src/_client.py +66 -0
  7. workers_runtime_sdk-1.6.13/tests/web-frameworks-test/fastapi-tests/src/test_sync_handlers.py +128 -0
  8. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/src/worker.py +94 -2
  9. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi/tests/test_asgi.py +9 -0
  10. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi/worker.py +26 -0
  11. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/uv.lock +1 -1
  12. workers_runtime_sdk-1.6.12/tests/web-frameworks-test/fastapi-tests/src/_client.py +0 -26
  13. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/.gitignore +0 -0
  14. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/AGENTS.md +0 -0
  15. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/README.md +0 -0
  16. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/_cloudflare_compat_flags.pyi +0 -0
  17. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/_pyodide_entrypoint_helper.pyi +0 -0
  18. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/_workers_sdk_entropy_import_context.py +0 -0
  19. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/_workers_sdk_package_patches.py +0 -0
  20. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/_workers_sdk_patch_loader.pth +0 -0
  21. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/_workers_sdk_patch_loader.py +0 -0
  22. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/__init__.py +0 -0
  23. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/blob.py +0 -0
  24. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/entrypoints.py +0 -0
  25. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/fetch.py +0 -0
  26. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/formdata.py +0 -0
  27. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/py.typed +0 -0
  28. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/request.py +0 -0
  29. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/response.py +0 -0
  30. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/rpc.py +0 -0
  31. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/types.py +0 -0
  32. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/utils.py +0 -0
  33. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/workflows.py +0 -0
  34. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/src/workers/wsgi.py +0 -0
  35. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/public/data.json +0 -0
  36. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/public/hello.txt +0 -0
  37. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/pyproject.toml +0 -0
  38. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/conftest.py +0 -0
  39. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_analytics_engine.py +0 -0
  40. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_assets.py +0 -0
  41. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_d1.py +0 -0
  42. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_do.py +0 -0
  43. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_images.py +0 -0
  44. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_kv.py +0 -0
  45. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_mtls.py +0 -0
  46. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_queue.py +0 -0
  47. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_r2.py +0 -0
  48. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_ratelimit.py +0 -0
  49. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_vectorize.py +0 -0
  50. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_version_metadata.py +0 -0
  51. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/test_workflow.py +0 -0
  52. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/worker.py +0 -0
  53. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/worker_durable_object.py +0 -0
  54. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/src/worker_workflow.py +0 -0
  55. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/bindings-test/wrangler.jsonc +0 -0
  56. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/conftest.py +0 -0
  57. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/test_bindings.py +0 -0
  58. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/test_fastapi.py +0 -0
  59. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/test_in_workerd.py +0 -0
  60. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/test_web_frameworks.py +0 -0
  61. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/pyproject.toml +0 -0
  62. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/_client.py +0 -0
  63. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/conftest.py +0 -0
  64. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/__init__.py +0 -0
  65. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/api_urls.py +0 -0
  66. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/auth_backend.py +0 -0
  67. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/drf_auth.py +0 -0
  68. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/drf_serializers.py +0 -0
  69. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/drf_throttling.py +0 -0
  70. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/drf_views.py +0 -0
  71. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/forms.py +0 -0
  72. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/middleware.py +0 -0
  73. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/templatetags/__init__.py +0 -0
  74. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/templatetags/custom_tags.py +0 -0
  75. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/urls.py +0 -0
  76. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/django_app/views.py +0 -0
  77. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/templates/base.html +0 -0
  78. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/templates/context_test.html +0 -0
  79. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/templates/csrf_form.html +0 -0
  80. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/templates/hello.html +0 -0
  81. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_async_utilities.py +0 -0
  82. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_auth.py +0 -0
  83. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_caching.py +0 -0
  84. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_cors.py +0 -0
  85. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_csrf.py +0 -0
  86. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_drf_auth_permissions.py +0 -0
  87. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_drf_content_negotiation.py +0 -0
  88. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_drf_serializers.py +0 -0
  89. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_drf_throttling.py +0 -0
  90. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_drf_versioning.py +0 -0
  91. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_drf_views.py +0 -0
  92. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_error_handling.py +0 -0
  93. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_file_uploads.py +0 -0
  94. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_forms.py +0 -0
  95. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_middleware.py +0 -0
  96. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_pagination.py +0 -0
  97. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_request_response.py +0 -0
  98. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_sessions.py +0 -0
  99. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_signals.py +0 -0
  100. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_streaming.py +0 -0
  101. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_templates.py +0 -0
  102. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_url_routing.py +0 -0
  103. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/test_views_basic.py +0 -0
  104. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/src/worker.py +0 -0
  105. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/django-async/wrangler.jsonc +0 -0
  106. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/public/data.json +0 -0
  107. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/public/index.html +0 -0
  108. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/public/style.css +0 -0
  109. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/src/conftest.py +0 -0
  110. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/src/static/app.css +0 -0
  111. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/src/static/data.json +0 -0
  112. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/src/static/hello.txt +0 -0
  113. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/src/static/index.html +0 -0
  114. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/src/test_assets.py +0 -0
  115. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/src/test_staticfiles.py +0 -0
  116. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/web-frameworks-test/fastapi-tests/wrangler.jsonc +0 -0
  117. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi/asgi.wd-test +0 -0
  118. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi/pyproject.toml +0 -0
  119. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi/wrangler.jsonc +0 -0
  120. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi-ws-disconnect/asgi-ws-disconnect.wd-test +0 -0
  121. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi-ws-disconnect/pyproject.toml +0 -0
  122. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi-ws-disconnect/tests/test_ws_disconnect.py +0 -0
  123. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi-ws-disconnect/worker.py +0 -0
  124. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/asgi-ws-disconnect/wrangler.jsonc +0 -0
  125. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object/durable-object.wd-test +0 -0
  126. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object/pyproject.toml +0 -0
  127. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object/worker.py +0 -0
  128. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object/wrangler.jsonc +0 -0
  129. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-abort/durable-object-abort.wd-test +0 -0
  130. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-abort/pyproject.toml +0 -0
  131. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-abort/worker.py +0 -0
  132. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-abort/wrangler.jsonc +0 -0
  133. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-inheritance/durable-object-inheritance.wd-test +0 -0
  134. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-inheritance/pyproject.toml +0 -0
  135. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-inheritance/worker.py +0 -0
  136. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-inheritance/wrangler.jsonc +0 -0
  137. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-websocket/durable-object-websocket.wd-test +0 -0
  138. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-websocket/pyproject.toml +0 -0
  139. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-websocket/tester.js +0 -0
  140. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-websocket/worker.py +0 -0
  141. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/durable-object-websocket/wrangler.jsonc +0 -0
  142. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/entropy-patches.wd-test +0 -0
  143. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/pyproject.toml +0 -0
  144. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/tests/test_aiohttp_websocket.py +0 -0
  145. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/tests/test_langsmith.py +0 -0
  146. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/tests/test_numpy.py +0 -0
  147. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/tests/test_pydantic.py +0 -0
  148. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/tests/test_rust_packages.py +0 -0
  149. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/tests/test_ssl_avoidance.py +0 -0
  150. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/worker.py +0 -0
  151. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/entropy-patches/wrangler.jsonc +0 -0
  152. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/python-rpc/pyproject.toml +0 -0
  153. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/python-rpc/python-rpc.wd-test +0 -0
  154. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/python-rpc/worker.js +0 -0
  155. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/python-rpc/worker.py +0 -0
  156. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/python-rpc/wrangler.jsonc +0 -0
  157. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/sdk/pyproject.toml +0 -0
  158. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/sdk/sdk.wd-test +0 -0
  159. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/sdk/server.py +0 -0
  160. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/sdk/tests/test_sdk.py +0 -0
  161. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/sdk/worker.py +0 -0
  162. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/sdk/wrangler.jsonc +0 -0
  163. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/wsgi/pyproject.toml +0 -0
  164. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/wsgi/tests/test_wsgi.py +0 -0
  165. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/wsgi/worker.py +0 -0
  166. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/wsgi/wrangler.jsonc +0 -0
  167. {workers_runtime_sdk-1.6.12 → workers_runtime_sdk-1.6.13}/tests/workerd-test/wsgi/wsgi.wd-test +0 -0
@@ -2,6 +2,15 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v1.6.13 (2026-08-12)
6
+
7
+ ### Bug Fixes
8
+
9
+ - **runtime-sdk**: Preserve repeated response headers (multiple `Set-Cookie`)
10
+ ([#167](https://github.com/cloudflare/workers-py/pull/167),
11
+ [`f68bf6d`](https://github.com/cloudflare/workers-py/commit/f68bf6d622c896b6c61fe3c615d43d6e9b05d19b))
12
+
13
+
5
14
  ## v1.6.12 (2026-08-11)
6
15
 
7
16
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: workers-runtime-sdk
3
- Version: 1.6.12
3
+ Version: 1.6.13
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.12"
7
+ version = "1.6.13"
8
8
  description = "Python SDK for Cloudflare Workers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -8,6 +8,7 @@ from urllib.parse import unquote
8
8
  import js
9
9
 
10
10
  from workers import Context, Request
11
+ from workers.utils import _to_js_headers
11
12
 
12
13
  ASGI = {"spec_version": "2.0", "version": "3.0"}
13
14
  NULL_BODY_STATUSES = frozenset({101, 103, 204, 205, 304})
@@ -179,7 +180,7 @@ async def process_request(
179
180
  # TODO(later): remove this parameter after unvendoring Python SDK from workerd
180
181
  ctx: Context | None,
181
182
  ) -> js.Response:
182
- from js import Object, Response, TransformStream
183
+ from js import Response, TransformStream
183
184
  from pyodide.ffi import create_proxy
184
185
 
185
186
  status = None
@@ -221,6 +222,8 @@ async def process_request(
221
222
  if got["type"] == "http.response.start":
222
223
  status = got["status"]
223
224
  # Like above, we need to convert byte-pairs into string explicitly.
225
+ # A response header name may repeat (multiple Set-Cookie), so this
226
+ # must stay a sequence of pairs, not a name-keyed mapping.
224
227
  headers = [(k.decode(), v.decode()) for k, v in got.get("headers", [])]
225
228
 
226
229
  elif got["type"] == "http.response.body":
@@ -243,7 +246,7 @@ async def process_request(
243
246
  readable = transform_stream.readable
244
247
  writer = transform_stream.writable.getWriter()
245
248
  resp = Response.new(
246
- readable, headers=Object.fromEntries(headers), status=status
249
+ readable, headers=_to_js_headers(headers), status=status
247
250
  )
248
251
  result.set_result(resp)
249
252
  with acquire_js_buffer(body) as jsbytes:
@@ -252,7 +255,7 @@ async def process_request(
252
255
  # 101/103/204/205/304 must not carry a body per the Fetch spec.
253
256
  # https://fetch.spec.whatwg.org/#null-body-status
254
257
  resp = Response.new(
255
- None, headers=Object.fromEntries(headers), status=status
258
+ None, headers=_to_js_headers(headers), status=status
256
259
  )
257
260
  result.set_result(resp)
258
261
  finished_response.set()
@@ -262,7 +265,7 @@ async def process_request(
262
265
  buf = px.getBuffer()
263
266
  px.destroy()
264
267
  resp = Response.new(
265
- buf.data, headers=Object.fromEntries(headers), status=status
268
+ buf.data, headers=_to_js_headers(headers), status=status
266
269
  )
267
270
  result.set_result(resp)
268
271
  finished_response.set()
@@ -4,6 +4,7 @@ version = "0.1.0"
4
4
  requires-python = ">=3.12"
5
5
  dependencies = [
6
6
  "fastapi",
7
+ "python-multipart",
7
8
  "pytest",
8
9
  "pytest-asyncio<1.2.0",
9
10
  ]
@@ -0,0 +1,66 @@
1
+ import json as _json
2
+
3
+ import asgi
4
+ from workers import Request
5
+
6
+ BASE_URL = "http://testserver"
7
+
8
+
9
+ def _with_content_length(headers, body):
10
+ """Ensure Content-Length is present when a body is provided."""
11
+ hdrs = dict(headers or {})
12
+ if body is not None and not any(k.lower() == "content-length" for k in hdrs):
13
+ length = len(body.encode() if isinstance(body, str) else body)
14
+ hdrs["Content-Length"] = str(length)
15
+ return hdrs
16
+
17
+
18
+ async def fetch(app, path, env=None, method="GET", headers=None, body=None):
19
+ request = Request(
20
+ f"{BASE_URL}{path}",
21
+ method=method,
22
+ headers=_with_content_length(headers, body),
23
+ body=body,
24
+ )
25
+ return await asgi.fetch(app, request, env or {})
26
+
27
+
28
+ async def read_json(response):
29
+ text = await response.text()
30
+ return _json.loads(text) if text else None
31
+
32
+
33
+ async def get_json(app, path, **kwargs):
34
+ response = await fetch(app, path, **kwargs)
35
+ return response, await read_json(response)
36
+
37
+
38
+ async def post_json(app, path, data, **kwargs):
39
+ return await fetch(
40
+ app,
41
+ path,
42
+ method="POST",
43
+ headers={"Content-Type": "application/json"},
44
+ body=_json.dumps(data),
45
+ **kwargs,
46
+ )
47
+
48
+
49
+ def build_multipart(files, boundary="----WebTestBoundary"):
50
+ """Build a multipart/form-data body from a list of (name, filename, content) tuples."""
51
+ lines = []
52
+ for name, filename, content in files:
53
+ if isinstance(content, bytes):
54
+ content = content.decode()
55
+ lines.append(f"--{boundary}")
56
+ lines.append(
57
+ f'Content-Disposition: form-data; name="{name}"; filename="{filename}"'
58
+ )
59
+ lines.append("Content-Type: application/octet-stream")
60
+ lines.append("")
61
+ lines.append(content)
62
+ lines.append(f"--{boundary}--")
63
+ lines.append("")
64
+ body = "\r\n".join(lines)
65
+ content_type = f"multipart/form-data; boundary={boundary}"
66
+ return body, content_type
@@ -0,0 +1,128 @@
1
+ """Tests for FastAPI features that rely on anyio.to_thread.run_sync.
2
+
3
+ The workers runtime is single-threaded, so ``anyio.to_thread.run_sync`` is
4
+ patched to run the callable inline. Without the patch every test in this file
5
+ would fail with ``RuntimeError: can't start new thread``.
6
+
7
+ Covered call-sites:
8
+ - Sync ``def`` route handlers (``starlette.routing`` / ``fastapi.routing``)
9
+ - Sync dependencies (``fastapi.dependencies.utils``)
10
+ - Sync ``BackgroundTask`` (``starlette.background``)
11
+ - Sync-iterator ``StreamingResponse`` (``starlette.concurrency.iterate_in_threadpool``)
12
+ - ``UploadFile.read`` (``starlette.datastructures``)
13
+ """
14
+
15
+ import pytest
16
+ from _client import build_multipart, fetch, get_json, read_json
17
+
18
+ # -- sync route handlers -----------------------------------------------------
19
+
20
+
21
+ @pytest.mark.asyncio
22
+ async def test_sync_handler_returns_json(fastapi_app):
23
+ """A plain ``def`` route handler returns a JSON response."""
24
+ resp, data = await get_json(fastapi_app, "/sync/hello")
25
+ assert resp.status == 200
26
+ assert data["message"] == "sync hello"
27
+
28
+
29
+ @pytest.mark.asyncio
30
+ async def test_sync_post_handler(fastapi_app):
31
+ """A sync POST handler receives the request and responds."""
32
+ resp = await fetch(fastapi_app, "/sync/echo", method="POST", body="hi")
33
+ assert resp.status == 200
34
+ data = await read_json(resp)
35
+ assert data["method"] == "POST"
36
+
37
+
38
+ # -- sync dependency ----------------------------------------------------------
39
+
40
+
41
+ @pytest.mark.asyncio
42
+ async def test_sync_dependency(fastapi_app):
43
+ """An async handler that depends on a sync ``def`` dependency."""
44
+ resp, data = await get_json(fastapi_app, "/sync/dep")
45
+ assert resp.status == 200
46
+ assert data["greeting"] == "hello from sync dep"
47
+
48
+
49
+ # -- sync background task -----------------------------------------------------
50
+
51
+
52
+ @pytest.mark.asyncio
53
+ async def test_sync_background_task(fastapi_app):
54
+ """A sync function passed to ``BackgroundTask`` runs to completion."""
55
+ resp, data = await get_json(fastapi_app, "/sync/background/run")
56
+ assert resp.status == 200
57
+ assert data["submitted"] is True
58
+
59
+ # The background task runs inline (patched), so by the time the response
60
+ # is fully sent the side-effect should already be visible.
61
+ resp2, data2 = await get_json(fastapi_app, "/sync/background/check")
62
+ assert resp2.status == 200
63
+ assert data2["bg_ran"] is True
64
+
65
+
66
+ # -- sync-iterator streaming response ----------------------------------------
67
+
68
+
69
+ @pytest.mark.asyncio
70
+ async def test_sync_streaming_response(fastapi_app):
71
+ """StreamingResponse backed by a sync generator delivers all chunks."""
72
+ resp = await fetch(fastapi_app, "/sync/stream")
73
+ assert resp.status == 200
74
+ body = await resp.text()
75
+ for i in range(5):
76
+ assert f"chunk-{i}" in body
77
+
78
+
79
+ @pytest.mark.asyncio
80
+ async def test_sync_streaming_content_type(fastapi_app):
81
+ """StreamingResponse preserves the declared media type."""
82
+ resp = await fetch(fastapi_app, "/sync/stream")
83
+ assert resp.status == 200
84
+ assert "text/plain" in resp.headers.get("content-type")
85
+
86
+
87
+ # -- file upload (UploadFile) -------------------------------------------------
88
+
89
+
90
+ @pytest.mark.asyncio
91
+ async def test_single_file_upload(fastapi_app):
92
+ """A single file upload is received and its content is echoed back."""
93
+ body, content_type = build_multipart([("file", "greet.txt", "hello world")])
94
+ resp = await fetch(
95
+ fastapi_app,
96
+ "/upload/single",
97
+ method="POST",
98
+ headers={"Content-Type": content_type},
99
+ body=body,
100
+ )
101
+ assert resp.status == 200
102
+ data = await read_json(resp)
103
+ assert data["filename"] == "greet.txt"
104
+ assert data["size"] > 0
105
+ assert "hello world" in data["text"]
106
+
107
+
108
+ @pytest.mark.asyncio
109
+ async def test_multiple_file_upload(fastapi_app):
110
+ """Multiple files are received and their metadata is echoed back."""
111
+ body, content_type = build_multipart(
112
+ [
113
+ ("files", "one.txt", "first"),
114
+ ("files", "two.txt", "second"),
115
+ ]
116
+ )
117
+ resp = await fetch(
118
+ fastapi_app,
119
+ "/upload/multiple",
120
+ method="POST",
121
+ headers={"Content-Type": content_type},
122
+ body=body,
123
+ )
124
+ assert resp.status == 200
125
+ data = await read_json(resp)
126
+ assert len(data) == 2
127
+ assert [f["filename"] for f in data] == ["one.txt", "two.txt"]
128
+ assert all(f["size"] > 0 for f in data)
@@ -3,11 +3,12 @@ import importlib.util
3
3
  from pathlib import Path
4
4
 
5
5
  import pytest
6
- from fastapi import FastAPI, Request
7
- from fastapi.responses import FileResponse
6
+ from fastapi import Depends, FastAPI, File, Request, UploadFile
7
+ from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
8
8
  from fastapi.responses import Response as FastAPIResponse
9
9
  from fastapi.staticfiles import StaticFiles
10
10
  from pyodide.webloop import WebLoop
11
+ from starlette.background import BackgroundTask
11
12
 
12
13
  import asgi
13
14
  from workers import Response, WorkerEntrypoint
@@ -24,6 +25,16 @@ STATIC_DIR = Path(__file__).parent / "static"
24
25
 
25
26
  app = FastAPI()
26
27
 
28
+ # --------------------------------------------------------------------------- #
29
+ # Shared mutable state used to verify side-effects (e.g. background tasks).
30
+ # --------------------------------------------------------------------------- #
31
+ _side_effects: dict = {}
32
+
33
+
34
+ # --------------------------------------------------------------------------- #
35
+ # Routes exercising the anyio.to_thread.run_sync patch
36
+ # --------------------------------------------------------------------------- #
37
+
27
38
 
28
39
  @app.get("/api/hello")
29
40
  async def api_hello():
@@ -35,6 +46,87 @@ async def health():
35
46
  return {"ok": True}
36
47
 
37
48
 
49
+ # -- sync route handler (dispatched via run_in_threadpool) -------------------
50
+ @app.get("/sync/hello")
51
+ def sync_hello():
52
+ """A plain `def` (non-async) route handler."""
53
+ return {"message": "sync hello"}
54
+
55
+
56
+ @app.post("/sync/echo")
57
+ def sync_echo(request: Request):
58
+ """Sync POST handler that reads the body."""
59
+ # request.body() is async; the sync handler can still return a dict.
60
+ return {"method": request.method}
61
+
62
+
63
+ # -- sync dependency ---------------------------------------------------------
64
+ def _get_greeting():
65
+ """A plain `def` dependency (not async)."""
66
+ return "hello from sync dep"
67
+
68
+
69
+ @app.get("/sync/dep")
70
+ async def sync_dep_route(greeting: str = Depends(_get_greeting)):
71
+ """Async handler with a sync dependency."""
72
+ return {"greeting": greeting}
73
+
74
+
75
+ # -- sync background task ----------------------------------------------------
76
+ def _bg_task():
77
+ """Sync function executed as a BackgroundTask."""
78
+ _side_effects["bg_ran"] = True
79
+
80
+
81
+ @app.get("/sync/background/run")
82
+ async def sync_background_run():
83
+ """Fire a sync background task and return immediately."""
84
+ _side_effects.pop("bg_ran", None)
85
+ return JSONResponse({"submitted": True}, background=BackgroundTask(_bg_task))
86
+
87
+
88
+ @app.get("/sync/background/check")
89
+ async def sync_background_check():
90
+ """Return whether the background task has executed."""
91
+ return {"bg_ran": _side_effects.get("bg_ran", False)}
92
+
93
+
94
+ # -- sync iterator streaming response ---------------------------------------
95
+ def _sync_chunks():
96
+ """A plain generator (not async) yielding text chunks."""
97
+ for i in range(5):
98
+ yield f"chunk-{i}\n"
99
+
100
+
101
+ @app.get("/sync/stream")
102
+ async def sync_stream():
103
+ """StreamingResponse backed by a sync iterator."""
104
+ return StreamingResponse(_sync_chunks(), media_type="text/plain")
105
+
106
+
107
+ # -- file upload (UploadFile.read/write/seek go through run_in_threadpool) ---
108
+ @app.post("/upload/single")
109
+ async def upload_single(file: UploadFile = File(...)): # noqa: B008
110
+ """Accept a single file upload and echo its metadata + content."""
111
+ content = await file.read()
112
+ return {
113
+ "filename": file.filename,
114
+ "content_type": file.content_type,
115
+ "size": len(content),
116
+ "text": content.decode(errors="replace"),
117
+ }
118
+
119
+
120
+ @app.post("/upload/multiple")
121
+ async def upload_multiple(files: list[UploadFile] = File(...)): # noqa: B008
122
+ """Accept multiple file uploads and echo their metadata."""
123
+ result = []
124
+ for f in files:
125
+ data = await f.read()
126
+ result.append({"filename": f.filename, "size": len(data)})
127
+ return result
128
+
129
+
38
130
  @app.get("/native-file")
39
131
  async def native_file():
40
132
  """Serve a single bundled file with FastAPI's native FileResponse."""
@@ -412,3 +412,12 @@ async def test_late_stream_failure_terminates_response():
412
412
  )
413
413
  body = await asyncio.wait_for(response.text(), timeout=5)
414
414
  assert body == "chunk-1"
415
+
416
+
417
+ @pytest.mark.asyncio
418
+ async def test_multiple_set_cookie_headers_survive():
419
+ response = await env.SELF.fetch("http://example.com/multi-cookie")
420
+ assert response.headers.get_all("set-cookie") == [
421
+ "first=1; Path=/",
422
+ "second=2; Path=/",
423
+ ]
@@ -233,11 +233,35 @@ class ScopeEchoApp:
233
233
  await send({"type": "http.response.body", "body": body})
234
234
 
235
235
 
236
+ class MultiCookieApp:
237
+ """Sends two Set-Cookie headers; both must reach the client."""
238
+
239
+ async def __call__(self, scope, receive, send):
240
+ if scope["type"] == "lifespan":
241
+ message = await receive()
242
+ if message["type"] == "lifespan.startup":
243
+ await send({"type": "lifespan.startup.complete"})
244
+ return
245
+ await receive()
246
+ await send(
247
+ {
248
+ "type": "http.response.start",
249
+ "status": 200,
250
+ "headers": [
251
+ (b"set-cookie", b"first=1; Path=/"),
252
+ (b"set-cookie", b"second=2; Path=/"),
253
+ ],
254
+ }
255
+ )
256
+ await send({"type": "http.response.body", "body": b"ok"})
257
+
258
+
236
259
  app = HeaderEchoApp()
237
260
  sse_app = SSEApp()
238
261
  streaming_app = StreamingApp()
239
262
  scope_echo_app = ScopeEchoApp()
240
263
  late_failure_stream_app = LateFailureStreamApp()
264
+ multi_cookie_app = MultiCookieApp()
241
265
 
242
266
  example_hdr = {"Header1": "Value1", "Header2": "Value2"}
243
267
 
@@ -259,6 +283,8 @@ class Default(WorkerEntrypoint):
259
283
  return await asgi.fetch(
260
284
  late_failure_stream_app, request, self.env, self.ctx
261
285
  )
286
+ elif path == "/multi-cookie":
287
+ return await asgi.fetch(multi_cookie_app, request, self.env, self.ctx)
262
288
 
263
289
  return await asgi.fetch(app, request, self.env, self.ctx)
264
290
 
@@ -345,7 +345,7 @@ wheels = [
345
345
 
346
346
  [[package]]
347
347
  name = "workers-runtime-sdk"
348
- version = "1.6.12"
348
+ version = "1.6.13"
349
349
  source = { editable = "." }
350
350
 
351
351
  [package.dev-dependencies]
@@ -1,26 +0,0 @@
1
- import json as _json
2
-
3
- import asgi
4
- from workers import Request
5
-
6
- BASE_URL = "http://testserver"
7
-
8
-
9
- async def fetch(app, path, env=None, method="GET", headers=None, body=None):
10
- request = Request(
11
- f"{BASE_URL}{path}",
12
- method=method,
13
- headers=dict(headers or {}),
14
- body=body,
15
- )
16
- return await asgi.fetch(app, request, env or {})
17
-
18
-
19
- async def read_json(response):
20
- text = await response.text()
21
- return _json.loads(text) if text else None
22
-
23
-
24
- async def get_json(app, path, **kwargs):
25
- response = await fetch(app, path, **kwargs)
26
- return response, await read_json(response)