workers-runtime-sdk 1.9.5__tar.gz → 1.9.6__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 (211) hide show
  1. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/CHANGELOG.md +9 -0
  2. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/PKG-INFO +1 -1
  3. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/pyproject.toml +1 -1
  4. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/wsgi.py +21 -6
  5. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/flask-tests/pyproject.toml +7 -1
  6. workers_runtime_sdk-1.9.6/tests/web-frameworks-test/flask-tests/src/test_stream_with_context.py +70 -0
  7. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi-ws-disconnect/tests/test_ws_disconnect.py +6 -0
  8. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/sdk/tests/test_sdk.py +1 -2
  9. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/wsgi/tests/test_wsgi.py +52 -0
  10. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/wsgi/worker.py +37 -0
  11. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/uv.lock +1 -1
  12. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/.gitignore +0 -0
  13. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/AGENTS.md +0 -0
  14. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/LICENSE +0 -0
  15. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/README.md +0 -0
  16. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/_cloudflare_compat_flags.pyi +0 -0
  17. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/_pyodide_entrypoint_helper.pyi +0 -0
  18. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/_workers_sdk_entropy_import_context.py +0 -0
  19. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/_workers_sdk_package_patches.py +0 -0
  20. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/_workers_sdk_patch_loader.pth +0 -0
  21. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/_workers_sdk_patch_loader.py +0 -0
  22. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/asgi.py +0 -0
  23. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/__init__.py +0 -0
  24. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/asgi.py +0 -0
  25. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/blob.py +0 -0
  26. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/entrypoints.py +0 -0
  27. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/fetch.py +0 -0
  28. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/formdata.py +0 -0
  29. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/gateway/__init__.py +0 -0
  30. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/gateway/options.py +0 -0
  31. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/py.typed +0 -0
  32. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/request.py +0 -0
  33. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/response.py +0 -0
  34. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/rpc.py +0 -0
  35. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/types.py +0 -0
  36. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/utils.py +0 -0
  37. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/workflows.js +0 -0
  38. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/src/workers/workflows.py +0 -0
  39. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/public/data.json +0 -0
  40. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/public/hello.txt +0 -0
  41. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/pyproject.toml +0 -0
  42. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/conftest.py +0 -0
  43. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_analytics_engine.py +0 -0
  44. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_assets.py +0 -0
  45. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_d1.py +0 -0
  46. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_do.py +0 -0
  47. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_hyperdrive_mysql.py +0 -0
  48. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_hyperdrive_postgresql.py +0 -0
  49. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_images.py +0 -0
  50. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_kv.py +0 -0
  51. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_mtls.py +0 -0
  52. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_queue.py +0 -0
  53. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_r2.py +0 -0
  54. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_ratelimit.py +0 -0
  55. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_vectorize.py +0 -0
  56. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_version_metadata.py +0 -0
  57. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/test_workflow.py +0 -0
  58. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/worker.py +0 -0
  59. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/worker_durable_object.py +0 -0
  60. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/src/worker_workflow.py +0 -0
  61. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/bindings-test/wrangler.jsonc +0 -0
  62. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/conftest.py +0 -0
  63. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/test_bindings.py +0 -0
  64. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/test_django.py +0 -0
  65. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/test_django_databases.py +0 -0
  66. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/test_fastapi.py +0 -0
  67. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/test_flask.py +0 -0
  68. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/test_in_workerd.py +0 -0
  69. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/pyproject.toml +0 -0
  70. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/_client.py +0 -0
  71. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/conftest.py +0 -0
  72. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/__init__.py +0 -0
  73. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/api_urls.py +0 -0
  74. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/auth_backend.py +0 -0
  75. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/drf_auth.py +0 -0
  76. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/drf_serializers.py +0 -0
  77. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/drf_throttling.py +0 -0
  78. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/drf_views.py +0 -0
  79. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/forms.py +0 -0
  80. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/middleware.py +0 -0
  81. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/templatetags/__init__.py +0 -0
  82. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/templatetags/custom_tags.py +0 -0
  83. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/urls.py +0 -0
  84. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/django_app/views.py +0 -0
  85. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/templates/base.html +0 -0
  86. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/templates/context_test.html +0 -0
  87. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/templates/csrf_form.html +0 -0
  88. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/templates/hello.html +0 -0
  89. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_async_utilities.py +0 -0
  90. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_auth.py +0 -0
  91. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_caching.py +0 -0
  92. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_cors.py +0 -0
  93. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_csrf.py +0 -0
  94. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_drf_auth_permissions.py +0 -0
  95. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_drf_content_negotiation.py +0 -0
  96. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_drf_serializers.py +0 -0
  97. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_drf_throttling.py +0 -0
  98. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_drf_versioning.py +0 -0
  99. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_drf_views.py +0 -0
  100. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_error_handling.py +0 -0
  101. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_file_uploads.py +0 -0
  102. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_forms.py +0 -0
  103. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_middleware.py +0 -0
  104. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_pagination.py +0 -0
  105. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_request_response.py +0 -0
  106. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_sessions.py +0 -0
  107. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_signals.py +0 -0
  108. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_streaming.py +0 -0
  109. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_templates.py +0 -0
  110. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_url_routing.py +0 -0
  111. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/test_views_basic.py +0 -0
  112. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/src/worker.py +0 -0
  113. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-async/wrangler.jsonc +0 -0
  114. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-databases/pyproject.toml +0 -0
  115. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-databases/src/django_db_config.py +0 -0
  116. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-databases/src/django_db_helpers.py +0 -0
  117. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-databases/src/test_mysql.py +0 -0
  118. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-databases/src/test_postgresql.py +0 -0
  119. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-databases/src/worker.py +0 -0
  120. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/django-databases/wrangler.jsonc +0 -0
  121. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/public/data.json +0 -0
  122. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/public/index.html +0 -0
  123. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/public/style.css +0 -0
  124. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/pyproject.toml +0 -0
  125. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/_client.py +0 -0
  126. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/conftest.py +0 -0
  127. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/static/app.css +0 -0
  128. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/static/data.json +0 -0
  129. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/static/hello.txt +0 -0
  130. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/static/index.html +0 -0
  131. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_assets.py +0 -0
  132. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_error_handling.py +0 -0
  133. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_platform_boundaries.py +0 -0
  134. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_platform_io.py +0 -0
  135. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_platform_lifecycle.py +0 -0
  136. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_response_types.py +0 -0
  137. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_routing.py +0 -0
  138. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_staticfiles.py +0 -0
  139. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_sync_handlers.py +0 -0
  140. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/test_websocket.py +0 -0
  141. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/src/worker.py +0 -0
  142. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/fastapi-tests/wrangler.jsonc +0 -0
  143. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/flask-tests/src/test_response.py +0 -0
  144. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/flask-tests/src/worker.py +0 -0
  145. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/web-frameworks-test/flask-tests/wrangler.jsonc +0 -0
  146. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi/asgi.wd-test +0 -0
  147. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi/pyproject.toml +0 -0
  148. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi/tests/test_asgi.py +0 -0
  149. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi/worker.py +0 -0
  150. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi/wrangler.jsonc +0 -0
  151. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi-ws-disconnect/asgi-ws-disconnect.wd-test +0 -0
  152. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi-ws-disconnect/pyproject.toml +0 -0
  153. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi-ws-disconnect/worker.py +0 -0
  154. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/asgi-ws-disconnect/wrangler.jsonc +0 -0
  155. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object/durable-object.wd-test +0 -0
  156. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object/pyproject.toml +0 -0
  157. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object/worker.py +0 -0
  158. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object/wrangler.jsonc +0 -0
  159. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-abort/durable-object-abort.wd-test +0 -0
  160. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-abort/pyproject.toml +0 -0
  161. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-abort/worker.py +0 -0
  162. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-abort/wrangler.jsonc +0 -0
  163. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-inheritance/durable-object-inheritance.wd-test +0 -0
  164. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-inheritance/pyproject.toml +0 -0
  165. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-inheritance/worker.py +0 -0
  166. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-inheritance/wrangler.jsonc +0 -0
  167. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-websocket/durable-object-websocket.wd-test +0 -0
  168. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-websocket/pyproject.toml +0 -0
  169. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-websocket/tester.js +0 -0
  170. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-websocket/worker.py +0 -0
  171. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/durable-object-websocket/wrangler.jsonc +0 -0
  172. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/entropy-patches.wd-test +0 -0
  173. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/pyproject.toml +0 -0
  174. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_aiohttp_websocket.py +0 -0
  175. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_boto3.py +0 -0
  176. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_jsonschema.py +0 -0
  177. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_langsmith.py +0 -0
  178. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_litestar.py +0 -0
  179. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_mcp.py +0 -0
  180. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_numpy.py +0 -0
  181. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_opentelemetry.py +0 -0
  182. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_pydantic.py +0 -0
  183. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_rust_packages.py +0 -0
  184. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/tests/test_ssl_avoidance.py +0 -0
  185. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/worker.py +0 -0
  186. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/entropy-patches/wrangler.jsonc +0 -0
  187. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/http-client/http-client.wd-test +0 -0
  188. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/http-client/origin.py +0 -0
  189. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/http-client/pyproject.toml +0 -0
  190. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/http-client/tests/test_http_client.py +0 -0
  191. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/http-client/tests/test_urllib_request.py +0 -0
  192. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/http-client/worker.py +0 -0
  193. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/http-client/wrangler.jsonc +0 -0
  194. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/python-rpc/pyproject.toml +0 -0
  195. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/python-rpc/python-rpc.wd-test +0 -0
  196. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/python-rpc/worker.js +0 -0
  197. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/python-rpc/worker.py +0 -0
  198. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/python-rpc/wrangler.jsonc +0 -0
  199. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/sdk/pyproject.toml +0 -0
  200. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/sdk/sdk.wd-test +0 -0
  201. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/sdk/server.py +0 -0
  202. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/sdk/worker.py +0 -0
  203. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/sdk/wrangler.jsonc +0 -0
  204. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/workflow/pyproject.toml +0 -0
  205. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/workflow/worker.js +0 -0
  206. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/workflow/worker.py +0 -0
  207. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/workflow/workflow.wd-test +0 -0
  208. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/workflow/wrangler.jsonc +0 -0
  209. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/wsgi/pyproject.toml +0 -0
  210. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/wsgi/wrangler.jsonc +0 -0
  211. {workers_runtime_sdk-1.9.5 → workers_runtime_sdk-1.9.6}/tests/workerd-test/wsgi/wsgi.wd-test +0 -0
@@ -2,6 +2,15 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v1.9.6 (2026-11-04)
6
+
7
+ ### Bug Fixes
8
+
9
+ - **runtime-sdk**: Fix contextvars not being properly shared in WSGI streaming response
10
+ ([#288](https://github.com/cloudflare/workers-py/pull/288),
11
+ [`7cc6cbd`](https://github.com/cloudflare/workers-py/commit/7cc6cbd9253cc581dbb53e9254aa063b643f1183))
12
+
13
+
5
14
  ## v1.9.5 (2026-10-20)
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.9.5
3
+ Version: 1.9.6
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.9.5"
7
+ version = "1.9.6"
8
8
  description = "Python SDK for Cloudflare Workers"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,3 +1,4 @@
1
+ import contextvars
1
2
  import io
2
3
  import logging
3
4
  import sys
@@ -222,6 +223,14 @@ def _close_iterable(iterable: Any) -> None:
222
223
  _END = object()
223
224
 
224
225
 
226
+ def _iter_in_context(
227
+ context: contextvars.Context, iterator: "Iterator[Any]"
228
+ ) -> "Iterator[Any]":
229
+ """Make sure every chunk is produced in the given context."""
230
+ while (chunk := context.run(next, iterator, _END)) is not _END:
231
+ yield chunk
232
+
233
+
225
234
  def _make_streaming_response(
226
235
  status: str,
227
236
  headers: "list[tuple[str, str]]",
@@ -333,15 +342,21 @@ def process_request(
333
342
  response_state["headers"] = response_headers
334
343
  return write
335
344
 
336
- result = app(environ, start_response)
337
- result_iter = iter(result)
345
+ # Make sure a single context is used per response.
346
+ # Otherwise, stack switching could cause context variables set by the app
347
+ # to be lost when the iterable is consumed.
348
+ context = contextvars.copy_context()
349
+ result = context.run(app, environ, start_response)
350
+ result_iter = _iter_in_context(context, context.run(iter, result))
338
351
 
339
352
  def close_all() -> None:
340
- _close_iterable(result)
341
353
  try:
342
- environ["wsgi.input"].close()
343
- except Exception: # noqa: BLE001 - best-effort cleanup
344
- logger.exception("Failed to close wsgi.input")
354
+ context.run(_close_iterable, result)
355
+ finally:
356
+ try:
357
+ environ["wsgi.input"].close()
358
+ except Exception: # noqa: BLE001 - best-effort cleanup
359
+ logger.exception("Failed to close wsgi.input")
345
360
 
346
361
  # WSGI apps must call start_response before yielding the first body chunk,
347
362
  # but some defer it until the first non-empty chunk is produced. Pull that
@@ -2,7 +2,13 @@
2
2
  name = "flask-tests"
3
3
  version = "0.1.0"
4
4
  requires-python = ">=3.12"
5
- dependencies = ["flask", "pytest", "testlib", "workers-runtime-sdk"]
5
+ dependencies = [
6
+ "flask",
7
+ "pytest",
8
+ "pytest-asyncio<1.2.0",
9
+ "testlib",
10
+ "workers-runtime-sdk",
11
+ ]
6
12
 
7
13
  [tool.uv.sources]
8
14
  testlib = { path = "../packages/testlib" }
@@ -0,0 +1,70 @@
1
+ import asyncio
2
+
3
+ import js
4
+ import pytest
5
+ from flask import (
6
+ Flask,
7
+ Response,
8
+ has_request_context,
9
+ request,
10
+ stream_with_context,
11
+ )
12
+
13
+ from workers import wsgi
14
+
15
+ app = Flask(__name__)
16
+ # Request values whose stream_with_context generator has run its cleanup.
17
+ closed: list[str] = []
18
+
19
+
20
+ @app.get("/stream")
21
+ def stream():
22
+ @stream_with_context
23
+ def body():
24
+ value = request.args["value"]
25
+ try:
26
+ yield "flask:"
27
+ yield request.args["value"]
28
+ finally:
29
+ closed.append(value)
30
+
31
+ return Response(body(), content_type="text/plain")
32
+
33
+
34
+ async def fetch(value):
35
+ req = js.Request.new(f"http://example.com/stream?value={value}")
36
+ return await wsgi.fetch(app, req, {})
37
+
38
+
39
+ @pytest.fixture(autouse=True)
40
+ def clear_closed():
41
+ closed.clear()
42
+
43
+
44
+ @pytest.mark.asyncio
45
+ async def test_stream_with_context():
46
+ response = await fetch("stream-body")
47
+ assert response.status == 200
48
+ # The request context pushed while priming the body must stay in the
49
+ # response's own context instead of leaking into the caller's.
50
+ assert not has_request_context()
51
+ assert await response.text() == "flask:stream-body"
52
+ assert closed == ["stream-body"]
53
+
54
+
55
+ @pytest.mark.asyncio
56
+ async def test_concurrent_stream_with_context():
57
+ responses = await asyncio.gather(fetch("first"), fetch("second"))
58
+ bodies = await asyncio.gather(*(response.text() for response in responses))
59
+ assert bodies == ["flask:first", "flask:second"]
60
+ assert sorted(closed) == ["first", "second"]
61
+
62
+
63
+ @pytest.mark.asyncio
64
+ async def test_cancelled_stream_with_context():
65
+ response = await fetch("cancel")
66
+ reader = response.body.getReader()
67
+ first = await reader.read()
68
+ assert first.value.to_bytes() == b"flask:"
69
+ await reader.cancel()
70
+ assert closed == ["cancel"]
@@ -99,10 +99,16 @@ async def _ws_session(path):
99
99
  # Without this the payload arrives as a Blob, which cannot be read
100
100
  # synchronously in the message callback.
101
101
  ws.binaryType = "arraybuffer"
102
+ # The app runs on this test's event loop, which pytest-asyncio closes when
103
+ # the test ends, cancelling an app still awaiting the disconnect. Its
104
+ # server socket then never closes, and workerd keeps the request open
105
+ # waiting for it, so wait for the server's close before returning.
106
+ closed = _listen(ws, "close")
102
107
  try:
103
108
  yield ws
104
109
  finally:
105
110
  ws.close()
111
+ await asyncio.wait_for(closed, TIMEOUT_S)
106
112
 
107
113
 
108
114
  @pytest.mark.asyncio
@@ -498,8 +498,7 @@ async def test_response_unit_tests():
498
498
  response_json = Response.json([1, 2, 3])
499
499
  assert await response_json.text() == "[1, 2, 3]"
500
500
  assert (
501
- repr(response_json)
502
- == "Response(status=200, status_text='OK', content_type='application/json')"
501
+ repr(response_json) == "Response(status=200, content_type='application/json')"
503
502
  )
504
503
 
505
504
  response_json = Response.from_json([1, 2, 3])
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import gzip
2
3
  import json
3
4
 
@@ -5,9 +6,11 @@ import js
5
6
  import pytest
6
7
  from pyodide.ffi import to_js
7
8
  from worker import (
9
+ CONTEXTVAR_CLOSE_RESULTS,
8
10
  ENCODED_RESPONSE_PAYLOAD,
9
11
  STREAMING_CHUNK_SIZE,
10
12
  STREAMING_NUM_CHUNKS,
13
+ contextvar_streaming_app,
11
14
  crash_app,
12
15
  example_hdr,
13
16
  header_echo_app,
@@ -105,6 +108,55 @@ async def test_streaming(endpoint):
105
108
  assert all(b == expected_byte for b in body_bytes[start:end])
106
109
 
107
110
 
111
+ async def read_all(response) -> bytes:
112
+ reader = response.body.getReader()
113
+ body = b""
114
+ while True:
115
+ result = await reader.read()
116
+ if result.done:
117
+ return body
118
+ body += result.value.to_bytes()
119
+
120
+
121
+ @pytest.mark.asyncio
122
+ async def test_streaming_preserves_contextvars():
123
+ response = await env.SELF.fetch(
124
+ "http://example.com/stream-contextvar?value=complete"
125
+ )
126
+ assert response.status == 200
127
+ assert await read_all(response) == b"value:" + b"complete" * STREAMING_NUM_CHUNKS
128
+ assert CONTEXTVAR_CLOSE_RESULTS.pop("complete") == ["ok"]
129
+
130
+
131
+ @pytest.mark.asyncio
132
+ async def test_concurrent_streams_keep_separate_contextvars():
133
+ responses = await asyncio.gather(
134
+ env.SELF.fetch("http://example.com/stream-contextvar?value=first"),
135
+ env.SELF.fetch("http://example.com/stream-contextvar?value=second"),
136
+ )
137
+ bodies = await asyncio.gather(*(read_all(response) for response in responses))
138
+
139
+ assert bodies == [
140
+ b"value:" + b"first" * STREAMING_NUM_CHUNKS,
141
+ b"value:" + b"second" * STREAMING_NUM_CHUNKS,
142
+ ]
143
+ assert CONTEXTVAR_CLOSE_RESULTS.pop("first") == ["ok"]
144
+ assert CONTEXTVAR_CLOSE_RESULTS.pop("second") == ["ok"]
145
+
146
+
147
+ @pytest.mark.asyncio
148
+ async def test_cancelled_stream_closes_in_app_context():
149
+ req = js.Request.new("http://example.com/stream-contextvar?value=cancel")
150
+ response = await wsgi.fetch(contextvar_streaming_app, req, env)
151
+
152
+ reader = response.body.getReader()
153
+ first = await reader.read()
154
+ assert first.value.to_bytes() == b"value:"
155
+ await reader.cancel()
156
+
157
+ assert CONTEXTVAR_CLOSE_RESULTS.pop("cancel") == ["ok"]
158
+
159
+
108
160
  @pytest.mark.asyncio
109
161
  async def test_app_exception_is_raised():
110
162
  req = js.Request.new("http://example.com/crash-test")
@@ -1,6 +1,8 @@
1
1
  import asyncio
2
+ import contextvars
2
3
  import gzip
3
4
  import os
5
+ from urllib.parse import parse_qs
4
6
 
5
7
  from pyodide.ffi import run_sync
6
8
  from testlib.entrypoint import run_pytest
@@ -92,6 +94,40 @@ def streaming_app_stack_switch(environ, start_response):
92
94
  return generate()
93
95
 
94
96
 
97
+ REQUEST_VALUE: contextvars.ContextVar[str] = contextvars.ContextVar("request_value")
98
+ # Outcome of resetting REQUEST_VALUE when each response generator closes, keyed
99
+ # by request value: "ok", or the repr of the exception raised by reset().
100
+ CONTEXTVAR_CLOSE_RESULTS: dict[str, list[str]] = {}
101
+
102
+
103
+ def contextvar_streaming_app(environ, start_response):
104
+ """WSGI app whose body generator depends on a ContextVar set by the app.
105
+
106
+ Mirrors what Flask's ``stream_with_context`` does: state set in a ContextVar
107
+ while the app runs must stay visible while the body is iterated, and the
108
+ token must be reset in the same context when the iterable is closed.
109
+ """
110
+ value = parse_qs(environ["QUERY_STRING"])["value"][0]
111
+ token = REQUEST_VALUE.set(value)
112
+ start_response("200 OK", [("Content-Type", "text/plain")])
113
+
114
+ def generate():
115
+ try:
116
+ yield b"value:"
117
+ for _ in range(STREAMING_NUM_CHUNKS):
118
+ run_sync(asyncio.sleep(0))
119
+ yield REQUEST_VALUE.get().encode()
120
+ finally:
121
+ try:
122
+ REQUEST_VALUE.reset(token)
123
+ result = "ok"
124
+ except Exception as exc: # noqa: BLE001 - recorded for the test
125
+ result = repr(exc)
126
+ CONTEXTVAR_CLOSE_RESULTS.setdefault(value, []).append(result)
127
+
128
+ return generate()
129
+
130
+
95
131
  ENCODED_RESPONSE_PAYLOAD = b'{"message":"already encoded by the app"}' * 64
96
132
 
97
133
 
@@ -139,6 +175,7 @@ class Default(WorkerEntrypoint):
139
175
  "/cookies": cookies_app,
140
176
  "/stream": streaming_app,
141
177
  "/stream-stack-switch": streaming_app_stack_switch,
178
+ "/stream-contextvar": contextvar_streaming_app,
142
179
  }.get(path, header_echo_app)
143
180
 
144
181
  if path.startswith("/encoded/"):
@@ -376,7 +376,7 @@ wheels = [
376
376
 
377
377
  [[package]]
378
378
  name = "workers-runtime-sdk"
379
- version = "1.9.5"
379
+ version = "1.9.6"
380
380
  source = { editable = "." }
381
381
 
382
382
  [package.dev-dependencies]