workers-runtime-sdk 1.8.2__tar.gz → 1.8.5__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.
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/CHANGELOG.md +27 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/PKG-INFO +1 -1
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/pyproject.toml +6 -30
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/_workers_sdk_entropy_import_context.py +59 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/asgi.py +12 -3
- workers_runtime_sdk-1.8.5/tests/bindings-test/pyproject.toml +19 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_hyperdrive_mysql.py +21 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_hyperdrive_postgresql.py +65 -0
- workers_runtime_sdk-1.8.5/tests/bindings-test/src/worker.py +32 -0
- workers_runtime_sdk-1.8.5/tests/conftest.py +116 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/test_fastapi.py +1 -5
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/test_in_workerd.py +35 -13
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/pyproject.toml +4 -0
- workers_runtime_sdk-1.8.5/tests/web-frameworks-test/django-async/src/worker.py +104 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/pyproject.toml +4 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/worker.py +4 -73
- workers_runtime_sdk-1.8.5/tests/web-frameworks-test/flask-tests/pyproject.toml +8 -0
- workers_runtime_sdk-1.8.5/tests/web-frameworks-test/flask-tests/src/worker.py +5 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi/tests/test_asgi.py +46 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi-ws-disconnect/tests/test_ws_disconnect.py +12 -17
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/entropy-patches/pyproject.toml +6 -1
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/entropy-patches/tests/test_langsmith.py +0 -1
- workers_runtime_sdk-1.8.5/tests/workerd-test/entropy-patches/tests/test_litestar.py +7 -0
- workers_runtime_sdk-1.8.2/tests/workerd-test/entropy-patches/tests/test_rust_packages.py → workers_runtime_sdk-1.8.5/tests/workerd-test/entropy-patches/tests/test_mcp.py +3 -3
- workers_runtime_sdk-1.8.5/tests/workerd-test/entropy-patches/tests/test_opentelemetry.py +8 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/entropy-patches/tests/test_rust_packages.py +19 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/entropy-patches/worker.py +19 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/http-client/http-client.wd-test +45 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/http-client/origin.py +60 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/http-client/pyproject.toml +5 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/http-client/tests/test_http_client.py +162 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/http-client/tests/test_urllib_request.py +121 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/http-client/worker.py +14 -0
- workers_runtime_sdk-1.8.5/tests/workerd-test/http-client/wrangler.jsonc +5 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/uv.lock +23 -1
- workers_runtime_sdk-1.8.2/tests/bindings-test/pyproject.toml +0 -5
- workers_runtime_sdk-1.8.2/tests/bindings-test/src/worker.py +0 -186
- workers_runtime_sdk-1.8.2/tests/conftest.py +0 -290
- workers_runtime_sdk-1.8.2/tests/web-frameworks-test/django-async/src/worker.py +0 -206
- workers_runtime_sdk-1.8.2/tests/web-frameworks-test/flask-tests/pyproject.toml +0 -5
- workers_runtime_sdk-1.8.2/tests/web-frameworks-test/flask-tests/src/worker.py +0 -89
- workers_runtime_sdk-1.8.2/tests/workerd-test/entropy-patches/worker.py +0 -27
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/.gitignore +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/AGENTS.md +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/README.md +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/_cloudflare_compat_flags.pyi +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/_pyodide_entrypoint_helper.pyi +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/_workers_sdk_package_patches.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/_workers_sdk_patch_loader.pth +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/_workers_sdk_patch_loader.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/asgi.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/__init__.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/blob.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/entrypoints.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/fetch.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/formdata.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/py.typed +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/request.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/response.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/rpc.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/types.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/utils.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/workflows.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/workers/wsgi.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/public/data.json +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/public/hello.txt +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/conftest.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_analytics_engine.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_assets.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_d1.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_do.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_images.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_kv.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_mtls.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_queue.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_r2.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_ratelimit.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_vectorize.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_version_metadata.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/test_workflow.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/worker_durable_object.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/src/worker_workflow.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/bindings-test/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/test_bindings.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/test_flask.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/test_web_frameworks.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/_client.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/conftest.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/__init__.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/api_urls.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/auth_backend.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/drf_auth.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/drf_serializers.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/drf_throttling.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/drf_views.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/forms.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/middleware.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/templatetags/__init__.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/templatetags/custom_tags.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/urls.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/django_app/views.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/templates/base.html +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/templates/context_test.html +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/templates/csrf_form.html +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/templates/hello.html +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_async_utilities.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_auth.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_caching.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_cors.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_csrf.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_drf_auth_permissions.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_drf_content_negotiation.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_drf_serializers.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_drf_throttling.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_drf_versioning.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_drf_views.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_error_handling.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_file_uploads.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_forms.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_middleware.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_pagination.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_request_response.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_sessions.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_signals.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_streaming.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_templates.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_url_routing.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/src/test_views_basic.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/django-async/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/public/data.json +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/public/index.html +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/public/style.css +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/_client.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/conftest.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/static/app.css +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/static/data.json +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/static/hello.txt +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/static/index.html +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_assets.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_error_handling.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_platform_boundaries.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_platform_io.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_platform_lifecycle.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_response_types.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_routing.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_staticfiles.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_sync_handlers.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/src/test_websocket.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/fastapi-tests/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/flask-tests/src/test_response.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/web-frameworks-test/flask-tests/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi/asgi.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi-ws-disconnect/asgi-ws-disconnect.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi-ws-disconnect/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi-ws-disconnect/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/asgi-ws-disconnect/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object/durable-object.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-abort/durable-object-abort.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-abort/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-abort/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-abort/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-inheritance/durable-object-inheritance.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-inheritance/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-inheritance/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-inheritance/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-websocket/durable-object-websocket.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-websocket/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-websocket/tester.js +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-websocket/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/durable-object-websocket/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/entropy-patches/entropy-patches.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/entropy-patches/tests/test_aiohttp_websocket.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/entropy-patches/tests/test_numpy.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/entropy-patches/tests/test_pydantic.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/entropy-patches/tests/test_ssl_avoidance.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/entropy-patches/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/python-rpc/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/python-rpc/python-rpc.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/python-rpc/worker.js +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/python-rpc/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/python-rpc/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/sdk/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/sdk/sdk.wd-test +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/sdk/server.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/sdk/tests/test_sdk.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/sdk/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/sdk/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/wsgi/pyproject.toml +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/wsgi/tests/test_wsgi.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/wsgi/worker.py +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/wsgi/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/tests/workerd-test/wsgi/wsgi.wd-test +0 -0
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v1.8.5 (2026-09-17)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **runtime-sdk**: Fix top-level import for opentelemetry package
|
|
10
|
+
([#248](https://github.com/cloudflare/workers-py/pull/248),
|
|
11
|
+
[`338c12e`](https://github.com/cloudflare/workers-py/commit/338c12e5dc6aada9dd20968fdae6bb6e805ad33e))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## v1.8.4 (2026-09-08)
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
- **runtime-sdk**: Fix top-level entropy call for litestar and fix entropy tests
|
|
19
|
+
([#241](https://github.com/cloudflare/workers-py/pull/241),
|
|
20
|
+
[`99b77c7`](https://github.com/cloudflare/workers-py/commit/99b77c7658d1e4b0591233b8ce6cc179719751e3))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## v1.8.3 (2026-08-31)
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
- **runtime-sdk**: Stop losing details of ASGI lifespan failures
|
|
28
|
+
([#172](https://github.com/cloudflare/workers-py/pull/172),
|
|
29
|
+
[`c6d1f69`](https://github.com/cloudflare/workers-py/commit/c6d1f69e96fd13b5b9e41f48e70aebb7469310c8))
|
|
30
|
+
|
|
31
|
+
|
|
5
32
|
## v1.8.2 (2026-08-31)
|
|
6
33
|
|
|
7
34
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: workers-runtime-sdk
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.5
|
|
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.8.
|
|
7
|
+
version = "1.8.5"
|
|
8
8
|
description = "Python SDK for Cloudflare Workers"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -21,42 +21,18 @@ dev = [
|
|
|
21
21
|
"ruff>=0.1.0",
|
|
22
22
|
"mypy>=1.0.0",
|
|
23
23
|
"requests>=2.28.0",
|
|
24
|
+
"testlib[host]",
|
|
24
25
|
]
|
|
25
26
|
|
|
27
|
+
[tool.uv.sources]
|
|
28
|
+
testlib = { path = "../testlib", editable = true }
|
|
29
|
+
|
|
26
30
|
[project.urls]
|
|
27
31
|
"Homepage" = "https://github.com/cloudflare/workers-py"
|
|
28
32
|
"Bug Tracker" = "https://github.com/cloudflare/workers-py/issues"
|
|
29
33
|
|
|
30
34
|
[tool.ruff]
|
|
31
|
-
|
|
32
|
-
lint.select = [
|
|
33
|
-
"B0", # bugbear (all B0* checks enabled by default)
|
|
34
|
-
"B904", # bugbear (Within an except clause, raise exceptions with raise ... from err)
|
|
35
|
-
"B905", # bugbear (zip() without an explicit strict= parameter set.)
|
|
36
|
-
"C4", # flake8-comprehensions
|
|
37
|
-
"C9", # mccabe complexity
|
|
38
|
-
"E", # pycodestyles
|
|
39
|
-
"F", # pyflakes
|
|
40
|
-
"I", # isort
|
|
41
|
-
"PERF", # Perflint
|
|
42
|
-
"PGH", # pygrep-hooks
|
|
43
|
-
"PL", # Pylint
|
|
44
|
-
"UP", # pyupgrade
|
|
45
|
-
"W", # pycodestyles
|
|
46
|
-
]
|
|
47
|
-
lint.ignore = [
|
|
48
|
-
"C901", # Too complex
|
|
49
|
-
"E402",
|
|
50
|
-
"E501",
|
|
51
|
-
"E731",
|
|
52
|
-
"E741",
|
|
53
|
-
"PLR0911", # Too many return statements
|
|
54
|
-
"PLR0915", # Too many statements
|
|
55
|
-
"PLW2901",
|
|
56
|
-
"UP031",
|
|
57
|
-
"UP038", # Use X | Y instead of (X, Y)
|
|
58
|
-
]
|
|
59
|
-
lint.flake8-comprehensions.allow-dict-calls-with-keyword-arguments = true
|
|
35
|
+
extend = "../../ruff.toml"
|
|
60
36
|
lint.per-file-ignores."tests/**" = ["PLR2004", "PLR0913"]
|
|
61
37
|
lint.per-file-ignores."tests/workerd-test/**" = ["C901", "PLR0911", "PLR0912", "PLR2004", "PLW0603"]
|
|
62
38
|
lint.per-file-ignores."tests/bindings-test/**" = ["C901", "PLR0911", "PLR0912", "PLR2004", "PLW0603"]
|
{workers_runtime_sdk-1.8.2 → workers_runtime_sdk-1.8.5}/src/_workers_sdk_entropy_import_context.py
RENAMED
|
@@ -4,6 +4,7 @@ Top level entropy patches for packages
|
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
6
|
from contextlib import contextmanager
|
|
7
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
7
8
|
|
|
8
9
|
from _cloudflare.allow_entropy import (
|
|
9
10
|
allow_bad_entropy_calls,
|
|
@@ -17,6 +18,29 @@ from _cloudflare.import_patch_manager import (
|
|
|
17
18
|
)
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
@contextmanager
|
|
22
|
+
def allow_bad_entropy_calls_for_version(
|
|
23
|
+
package_name: str,
|
|
24
|
+
num_calls: int,
|
|
25
|
+
min_version: tuple[int, ...],
|
|
26
|
+
max_version: tuple[int, ...] | None = None,
|
|
27
|
+
):
|
|
28
|
+
try:
|
|
29
|
+
package_version = tuple(map(int, version(package_name).split(".")))
|
|
30
|
+
except PackageNotFoundError:
|
|
31
|
+
yield
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
if package_version < min_version or (
|
|
35
|
+
max_version is not None and package_version > max_version
|
|
36
|
+
):
|
|
37
|
+
yield
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
with allow_bad_entropy_calls(num_calls):
|
|
41
|
+
yield
|
|
42
|
+
|
|
43
|
+
|
|
20
44
|
class STATE:
|
|
21
45
|
imported_rust_package = False
|
|
22
46
|
numpy_random = None
|
|
@@ -178,3 +202,38 @@ def langsmith__internal__constants_context(module):
|
|
|
178
202
|
def langchain_openai_chat_models_base_context(module):
|
|
179
203
|
with allow_bad_entropy_calls(1):
|
|
180
204
|
yield
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@register_exec_patch("opentelemetry.context")
|
|
208
|
+
@contextmanager
|
|
209
|
+
def opentelemetry_context(module):
|
|
210
|
+
# OpenTelemetry creates three UUID-backed keys.
|
|
211
|
+
with allow_bad_entropy_calls_for_version("opentelemetry-api", 3, (1, 40, 0)):
|
|
212
|
+
yield
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
@register_exec_patch("opentelemetry.trace.propagation")
|
|
216
|
+
@contextmanager
|
|
217
|
+
def opentelemetry_trace_propagation_context(module):
|
|
218
|
+
# OpenTelemetry creates a UUID-backed key.
|
|
219
|
+
with allow_bad_entropy_calls(1):
|
|
220
|
+
yield
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@register_exec_patch("opentelemetry.baggage")
|
|
224
|
+
@contextmanager
|
|
225
|
+
def opentelemetry_baggage_context(module):
|
|
226
|
+
# OpenTelemetry creates a UUID-backed key.
|
|
227
|
+
with allow_bad_entropy_calls(1):
|
|
228
|
+
yield
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@register_exec_patch("litestar.openapi.controller")
|
|
232
|
+
@register_exec_patch("litestar.constants")
|
|
233
|
+
@contextmanager
|
|
234
|
+
def litestar_context(module):
|
|
235
|
+
# Uses os.urandom() to generate a OPENAPI_JSON_HANDLER_NAME
|
|
236
|
+
# https://github.com/litestar-org/litestar/blob/e3b6a1d103a9160a575dce01ae34839e6e9bf990/litestar/constants.py#L19
|
|
237
|
+
# https://github.com/litestar-org/litestar/blob/v2.24.0/litestar/openapi/controller.py#L27
|
|
238
|
+
with allow_bad_entropy_calls(1):
|
|
239
|
+
yield
|
|
@@ -127,7 +127,9 @@ async def start_application(app):
|
|
|
127
127
|
startup.set_result(True)
|
|
128
128
|
return
|
|
129
129
|
if got["type"] == "lifespan.startup.failed":
|
|
130
|
-
|
|
130
|
+
# `or`, not a .get default: an empty message field is legal and
|
|
131
|
+
# would otherwise produce RuntimeError('').
|
|
132
|
+
message = got.get("message") or "ASGI lifespan startup failed"
|
|
131
133
|
if not startup.done():
|
|
132
134
|
startup.set_exception(RuntimeError(message))
|
|
133
135
|
return
|
|
@@ -136,7 +138,7 @@ async def start_application(app):
|
|
|
136
138
|
shutdown_complete.set_result(None)
|
|
137
139
|
return
|
|
138
140
|
if got["type"] == "lifespan.shutdown.failed":
|
|
139
|
-
message = got.get("message"
|
|
141
|
+
message = got.get("message") or "ASGI lifespan shutdown failed"
|
|
140
142
|
if not shutdown_complete.done():
|
|
141
143
|
shutdown_complete.set_exception(RuntimeError(message))
|
|
142
144
|
return
|
|
@@ -161,8 +163,15 @@ async def start_application(app):
|
|
|
161
163
|
shutdown_complete.set_result(None)
|
|
162
164
|
except Exception as exc:
|
|
163
165
|
# Spec: an exception raised before startup is acked signals that the
|
|
164
|
-
# app doesn't support lifespan;
|
|
166
|
+
# app doesn't support lifespan; serve requests anyway. Log it, or an
|
|
167
|
+
# app that crashed mid-startup looks like one with no lifespan
|
|
168
|
+
# handler at all.
|
|
165
169
|
if not startup.done():
|
|
170
|
+
logger.debug(
|
|
171
|
+
"ASGI lifespan task raised before reporting startup; "
|
|
172
|
+
"treating the app as not supporting lifespan",
|
|
173
|
+
exc_info=exc,
|
|
174
|
+
)
|
|
166
175
|
startup.set_result(False)
|
|
167
176
|
return
|
|
168
177
|
# After a successful startup, a shutdown-phase error can't affect the
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "bindings-test"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
requires-python = ">=3.12"
|
|
5
|
+
dependencies = [
|
|
6
|
+
"pytest",
|
|
7
|
+
"pytest-asyncio<1.2.0",
|
|
8
|
+
# These are for hyperdrive tests
|
|
9
|
+
"pg8000",
|
|
10
|
+
"pymysql",
|
|
11
|
+
"aiomysql",
|
|
12
|
+
"psycopg[binary]; python_version >= '3.14'",
|
|
13
|
+
"asyncpg; python_version >= '3.14'",
|
|
14
|
+
"cryptography",
|
|
15
|
+
"testlib",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[tool.uv.sources]
|
|
19
|
+
testlib = { path = "../testlib/dist/testlib-0.0.0-py3-none-any.whl" }
|
|
@@ -24,6 +24,7 @@ uv run pytest tests/test_bindings.py -m hyperdrive -k mysql
|
|
|
24
24
|
|
|
25
25
|
import sys
|
|
26
26
|
|
|
27
|
+
import aiomysql
|
|
27
28
|
import pymysql
|
|
28
29
|
import pytest
|
|
29
30
|
from conftest import unique_table_name
|
|
@@ -58,6 +59,26 @@ async def test_connect(env):
|
|
|
58
59
|
conn.close()
|
|
59
60
|
|
|
60
61
|
|
|
62
|
+
@pytest.mark.asyncio
|
|
63
|
+
async def test_connect_aiomysql(env):
|
|
64
|
+
hd = env.HYPERDRIVE_MYSQL
|
|
65
|
+
conn = await aiomysql.connect(
|
|
66
|
+
host=hd.host,
|
|
67
|
+
port=int(hd.port),
|
|
68
|
+
user=hd.user,
|
|
69
|
+
password=hd.password,
|
|
70
|
+
db=hd.database,
|
|
71
|
+
# Hyperdrive terminates TLS to the origin, so this hop is plaintext.
|
|
72
|
+
ssl=None,
|
|
73
|
+
)
|
|
74
|
+
try:
|
|
75
|
+
async with conn.cursor() as cur:
|
|
76
|
+
await cur.execute("SELECT %s", (1,))
|
|
77
|
+
assert await cur.fetchone() == (1,)
|
|
78
|
+
finally:
|
|
79
|
+
await conn.ensure_closed()
|
|
80
|
+
|
|
81
|
+
|
|
61
82
|
@pytest.mark.asyncio
|
|
62
83
|
async def test_create_insert_select(env):
|
|
63
84
|
conn = _connect(env)
|
|
@@ -61,6 +61,71 @@ async def test_connect(env):
|
|
|
61
61
|
conn.close()
|
|
62
62
|
|
|
63
63
|
|
|
64
|
+
@pytest.mark.asyncio
|
|
65
|
+
async def test_connect_psycopg(env):
|
|
66
|
+
import psycopg # noqa: PLC0415
|
|
67
|
+
|
|
68
|
+
assert psycopg.pq.__impl__ == "binary"
|
|
69
|
+
hd = env.HYPERDRIVE_PG
|
|
70
|
+
with psycopg.connect(
|
|
71
|
+
host=hd.host,
|
|
72
|
+
port=int(hd.port),
|
|
73
|
+
user=hd.user,
|
|
74
|
+
password=hd.password,
|
|
75
|
+
dbname=hd.database,
|
|
76
|
+
# Hyperdrive terminates TLS to the origin, so this hop is plaintext.
|
|
77
|
+
sslmode="disable",
|
|
78
|
+
) as conn:
|
|
79
|
+
with conn.cursor() as cur:
|
|
80
|
+
cur.execute("SELECT %s", (1,))
|
|
81
|
+
assert cur.fetchone() == (1,)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@pytest.mark.asyncio
|
|
85
|
+
async def test_asyncpg_crud(env):
|
|
86
|
+
import asyncpg # noqa: PLC0415
|
|
87
|
+
|
|
88
|
+
hd = env.HYPERDRIVE_PG
|
|
89
|
+
conn = await asyncpg.connect(
|
|
90
|
+
host=hd.host,
|
|
91
|
+
port=int(hd.port),
|
|
92
|
+
user=hd.user,
|
|
93
|
+
password=hd.password,
|
|
94
|
+
database=hd.database,
|
|
95
|
+
# Hyperdrive terminates TLS to the origin, so this hop is plaintext.
|
|
96
|
+
ssl=False,
|
|
97
|
+
)
|
|
98
|
+
table = unique_table_name()
|
|
99
|
+
try:
|
|
100
|
+
await conn.execute(
|
|
101
|
+
f"CREATE TABLE {table} (id SERIAL PRIMARY KEY, name TEXT, value INT)"
|
|
102
|
+
)
|
|
103
|
+
await conn.execute(
|
|
104
|
+
f"INSERT INTO {table} (name, value) VALUES ($1, $2)", "alpha", 1
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
row = await conn.fetchrow(
|
|
108
|
+
f"SELECT name, value FROM {table} WHERE name = $1", "alpha"
|
|
109
|
+
)
|
|
110
|
+
assert tuple(row) == ("alpha", 1)
|
|
111
|
+
|
|
112
|
+
await conn.execute(
|
|
113
|
+
f"UPDATE {table} SET value = $1 WHERE name = $2", 11, "alpha"
|
|
114
|
+
)
|
|
115
|
+
assert (
|
|
116
|
+
await conn.fetchval(f"SELECT value FROM {table} WHERE name = $1", "alpha")
|
|
117
|
+
== 11
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
await conn.execute(f"DELETE FROM {table} WHERE name = $1", "alpha")
|
|
121
|
+
assert await conn.fetchval(f"SELECT COUNT(*) FROM {table}") == 0
|
|
122
|
+
finally:
|
|
123
|
+
try:
|
|
124
|
+
await conn.execute(f"DROP TABLE IF EXISTS {table}")
|
|
125
|
+
finally:
|
|
126
|
+
await conn.close()
|
|
127
|
+
|
|
128
|
+
|
|
64
129
|
@pytest.mark.asyncio
|
|
65
130
|
async def test_create_insert_select(env):
|
|
66
131
|
conn = _connect(env)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Bindings test worker.
|
|
2
|
+
|
|
3
|
+
Each binding suite lives in a `test_<suite>.py` module written as ordinary pytest
|
|
4
|
+
tests (see test_kv.py). The `/run-tests/<suite>` endpoint runs pytest against that
|
|
5
|
+
module inside workerd and returns per-test results as JSON, which the host-side
|
|
6
|
+
test_bindings.py maps onto individual pytest cases.
|
|
7
|
+
|
|
8
|
+
To add a new binding: create `src/test_<binding>.py` with pytest tests.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from testlib.entrypoint import TestRunnerEntrypoint
|
|
12
|
+
from worker_durable_object import (
|
|
13
|
+
TestDurableObject, # noqa: F401 - import to trigger side effect of registering the Durable Object
|
|
14
|
+
)
|
|
15
|
+
from worker_workflow import (
|
|
16
|
+
TestWorkflow, # noqa: F401 - import to trigger side effect of registering the Workflow
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
RECEIVED_MESSAGES = []
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Default(TestRunnerEntrypoint):
|
|
23
|
+
async def queue(self, batch, env, ctx):
|
|
24
|
+
for message in batch.messages:
|
|
25
|
+
RECEIVED_MESSAGES.append(
|
|
26
|
+
{
|
|
27
|
+
"id": message.id,
|
|
28
|
+
"body": message.body,
|
|
29
|
+
"attempts": message.attempts,
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
message.ack()
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Shared fixtures and helpers for the host-side test suite."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
from collections.abc import Generator
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
from testlib.host import (
|
|
12
|
+
COMPAT_CONFIGS,
|
|
13
|
+
CompatConfig,
|
|
14
|
+
configure_compatibility,
|
|
15
|
+
)
|
|
16
|
+
from testlib.host import (
|
|
17
|
+
dev_server as run_dev_server,
|
|
18
|
+
)
|
|
19
|
+
from testlib.host import (
|
|
20
|
+
register_in_worker_suites as register_testlib_suites,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
TEST_DIR: Path = Path(__file__).parent
|
|
24
|
+
WORKERS_PY: Path = TEST_DIR.parent.parent / "cli"
|
|
25
|
+
WORKERS_RUNTIME_SDK: Path = TEST_DIR.parent / "src"
|
|
26
|
+
TESTLIB: Path = TEST_DIR.parent.parent / "testlib"
|
|
27
|
+
|
|
28
|
+
DEV_STARTUP_TIMEOUT: int = 120
|
|
29
|
+
OPT_IN_MARKERS: tuple[str, ...] = ("hyperdrive",)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def pytest_collection_modifyitems(
|
|
33
|
+
config: pytest.Config, items: list[pytest.Item]
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Skip opt-in suites unless the run explicitly asks for them via ``-m``."""
|
|
36
|
+
markexpr: str = config.getoption("markexpr")
|
|
37
|
+
for marker in OPT_IN_MARKERS:
|
|
38
|
+
if marker in markexpr:
|
|
39
|
+
continue
|
|
40
|
+
skip = pytest.mark.skip(reason=f"needs local services; run with -m {marker}")
|
|
41
|
+
for item in items:
|
|
42
|
+
if marker in item.keywords:
|
|
43
|
+
item.add_marker(skip)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@pytest.fixture(scope="session", autouse=True)
|
|
47
|
+
def build_testlib():
|
|
48
|
+
subprocess.run(["uv", "build"], cwd=TESTLIB, check=True)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@pytest.fixture(
|
|
52
|
+
scope="module",
|
|
53
|
+
params=COMPAT_CONFIGS,
|
|
54
|
+
ids=[c.python_version for c in COMPAT_CONFIGS],
|
|
55
|
+
)
|
|
56
|
+
def compat_config(request: pytest.FixtureRequest) -> CompatConfig:
|
|
57
|
+
return request.param
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@pytest.fixture(scope="module")
|
|
61
|
+
def worker_project_dir() -> Path:
|
|
62
|
+
"""Worker project the `dev_server` fixture should serve.
|
|
63
|
+
|
|
64
|
+
Test modules using `dev_server` must override this fixture.
|
|
65
|
+
"""
|
|
66
|
+
raise NotImplementedError(
|
|
67
|
+
"override the `worker_project_dir` fixture in your test module"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@pytest.fixture(scope="module")
|
|
72
|
+
def dev_server(
|
|
73
|
+
tmp_path_factory: pytest.TempPathFactory,
|
|
74
|
+
worker_project_dir: Path,
|
|
75
|
+
compat_config: CompatConfig,
|
|
76
|
+
) -> Generator[str]:
|
|
77
|
+
"""Start a pywrangler dev server on a free port and yield its base URL."""
|
|
78
|
+
tmp_path = tmp_path_factory.mktemp(f"{worker_project_dir.name}_dev")
|
|
79
|
+
target = tmp_path / worker_project_dir.name
|
|
80
|
+
shutil.copytree(worker_project_dir, target, ignore=shutil.ignore_patterns(".venv"))
|
|
81
|
+
shutil.copytree(TESTLIB, tmp_path / "testlib")
|
|
82
|
+
env = os.environ | {"_PYODIDE_EXTRA_MOUNTS": str(tmp_path)}
|
|
83
|
+
|
|
84
|
+
wrangler_jsonc = target / "wrangler.jsonc"
|
|
85
|
+
configure_compatibility(wrangler_jsonc, compat_config)
|
|
86
|
+
|
|
87
|
+
pywrangler_cmd = ["uv", "run", "--no-project", "--with", WORKERS_PY, "pywrangler"]
|
|
88
|
+
|
|
89
|
+
subprocess.run(
|
|
90
|
+
[*pywrangler_cmd, "sync"],
|
|
91
|
+
cwd=target,
|
|
92
|
+
check=True,
|
|
93
|
+
env=env,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
shutil.copytree(WORKERS_RUNTIME_SDK, target / "python_modules", dirs_exist_ok=True)
|
|
97
|
+
|
|
98
|
+
with run_dev_server(
|
|
99
|
+
target,
|
|
100
|
+
tmp_path,
|
|
101
|
+
env,
|
|
102
|
+
pywrangler_cmd,
|
|
103
|
+
startup_timeout=DEV_STARTUP_TIMEOUT,
|
|
104
|
+
readiness_path="/health",
|
|
105
|
+
require_success=True,
|
|
106
|
+
log_name="dev.log",
|
|
107
|
+
) as (base_url, _):
|
|
108
|
+
yield base_url
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def register_in_worker_suites(
|
|
112
|
+
namespace: dict[str, Any],
|
|
113
|
+
src_dir: Path,
|
|
114
|
+
marks: dict[str, pytest.MarkDecorator] | None = None,
|
|
115
|
+
) -> None:
|
|
116
|
+
register_testlib_suites(namespace, src_dir, marks=marks, class_name=str.upper)
|
|
@@ -4,9 +4,6 @@ Python 3.12 (Pyodide 0.26.0a2) is excluded. The in-worker pytest suite drives
|
|
|
4
4
|
async tests via ``loop.run_until_complete``, which is a no-op on Pyodide 0.26.0a2
|
|
5
5
|
(no ``run_sync``/JSPI): async tests return unawaited futures and report false
|
|
6
6
|
passes.
|
|
7
|
-
|
|
8
|
-
Python 3.14 is excluded because pydantic_core has a circular import error on
|
|
9
|
-
the 3.14 Pyodide runtime (``validate_core_schema`` not found during module init).
|
|
10
7
|
"""
|
|
11
8
|
|
|
12
9
|
from pathlib import Path
|
|
@@ -26,9 +23,8 @@ def worker_project_dir() -> Path:
|
|
|
26
23
|
|
|
27
24
|
|
|
28
25
|
# Exclude Python 3.12 (Pyodide 0.26.0a2) for async tests.
|
|
29
|
-
# Exclude Python 3.14 due to pydantic_core circular import error on Pyodide.
|
|
30
26
|
FASTAPI_COMPAT_CONFIGS = [
|
|
31
|
-
c for c in COMPAT_CONFIGS if c.python_version not in ("3.12",
|
|
27
|
+
c for c in COMPAT_CONFIGS if c.python_version not in ("3.12",)
|
|
32
28
|
]
|
|
33
29
|
|
|
34
30
|
|
|
@@ -7,8 +7,7 @@ import pytest
|
|
|
7
7
|
from conftest import (
|
|
8
8
|
COMPAT_CONFIGS,
|
|
9
9
|
CompatConfig,
|
|
10
|
-
|
|
11
|
-
replace_compat_date,
|
|
10
|
+
configure_compatibility,
|
|
12
11
|
)
|
|
13
12
|
|
|
14
13
|
TEST_DIR = Path(__file__).parent
|
|
@@ -30,6 +29,30 @@ def discover_workerd_tests():
|
|
|
30
29
|
return cases
|
|
31
30
|
|
|
32
31
|
|
|
32
|
+
def resolve_workerd(target: Path) -> str:
|
|
33
|
+
"""Return the path to the workerd binary to use for tests.
|
|
34
|
+
|
|
35
|
+
If the ``WORKERD_PATH`` environment variable is set, it is used as-is (this
|
|
36
|
+
is useful for testing against a locally built workerd). Otherwise, workerd
|
|
37
|
+
is installed from npm into ``target`` and the installed binary is used.
|
|
38
|
+
"""
|
|
39
|
+
workerd_path = os.environ.get("WORKERD_PATH")
|
|
40
|
+
if workerd_path:
|
|
41
|
+
workerd_bin = Path(workerd_path).expanduser().resolve()
|
|
42
|
+
if not workerd_bin.is_file():
|
|
43
|
+
raise FileNotFoundError(
|
|
44
|
+
f"WORKERD_PATH is set but does not point to a file: {workerd_bin}"
|
|
45
|
+
)
|
|
46
|
+
return str(workerd_bin)
|
|
47
|
+
|
|
48
|
+
subprocess.run(
|
|
49
|
+
["npm", "i", "workerd"],
|
|
50
|
+
cwd=target,
|
|
51
|
+
check=True,
|
|
52
|
+
)
|
|
53
|
+
return "node_modules/workerd/bin/workerd"
|
|
54
|
+
|
|
55
|
+
|
|
33
56
|
def embed(dir: Path, root: Path, level: int = 0):
|
|
34
57
|
modules = []
|
|
35
58
|
module_path_root = dir
|
|
@@ -62,7 +85,7 @@ def bundle_cache_dir(tmp_path_factory):
|
|
|
62
85
|
ids=[c.python_version for c in COMPAT_CONFIGS],
|
|
63
86
|
)
|
|
64
87
|
@pytest.mark.parametrize("test_dir, wd_test_file", discover_workerd_tests())
|
|
65
|
-
def test_in_workerd( # noqa: PLR0913 (too-many-arguments)
|
|
88
|
+
def test_in_workerd( # noqa: PLR0913, PLR0917 (too-many-arguments)
|
|
66
89
|
tmp_path,
|
|
67
90
|
test_dir,
|
|
68
91
|
wd_test_file,
|
|
@@ -71,22 +94,25 @@ def test_in_workerd( # noqa: PLR0913 (too-many-arguments)
|
|
|
71
94
|
bundle_cache_dir,
|
|
72
95
|
):
|
|
73
96
|
compat_date = compat_config.compat_date
|
|
97
|
+
python_version = compat_config.python_version
|
|
74
98
|
|
|
75
99
|
# `wsgi` streams the request body via `pyodide.ffi.run_sync` (JSPI), which
|
|
76
100
|
# is only available in newer Pyodide runtimes.
|
|
77
|
-
if test_dir.name == "wsgi" and
|
|
101
|
+
if test_dir.name == "wsgi" and python_version == "3.12":
|
|
78
102
|
pytest.skip(
|
|
79
103
|
"wsgi requires pyodide.ffi.run_sync (JSPI), unavailable before 2026-01-01"
|
|
80
104
|
)
|
|
81
105
|
|
|
106
|
+
if test_dir.name == "http-client" and python_version < "3.14":
|
|
107
|
+
pytest.skip("HTTP client compatibility tests require Python 3.14 or newer")
|
|
108
|
+
|
|
82
109
|
color = pytestconfig.get_terminal_writer().hasmarkup
|
|
83
110
|
target = tmp_path / test_dir.name
|
|
84
111
|
disk_service_dir = target / DISK_SERVICE_NAME
|
|
85
112
|
shutil.copytree(test_dir, target, ignore=shutil.ignore_patterns(".venv"))
|
|
86
113
|
disk_service_dir.mkdir(exist_ok=True)
|
|
87
114
|
|
|
88
|
-
|
|
89
|
-
inject_compat_flags(target / "wrangler.jsonc", compat_config.extra_compat_flags)
|
|
115
|
+
configure_compatibility(target / "wrangler.jsonc", compat_config)
|
|
90
116
|
|
|
91
117
|
pywrangler_cmd = ["uv", "run", "--no-project", "--with", WORKERS_PY, "pywrangler"]
|
|
92
118
|
|
|
@@ -114,15 +140,11 @@ def test_in_workerd( # noqa: PLR0913 (too-many-arguments)
|
|
|
114
140
|
.replace("%COLOR", str(color).lower())
|
|
115
141
|
.replace("%COMPAT_DATE", compat_date)
|
|
116
142
|
)
|
|
117
|
-
|
|
143
|
+
configure_compatibility(wd_config, compat_config)
|
|
118
144
|
|
|
119
|
-
|
|
120
|
-
["npm", "i", "workerd"],
|
|
121
|
-
cwd=target,
|
|
122
|
-
check=True,
|
|
123
|
-
)
|
|
145
|
+
workerd_bin = resolve_workerd(target)
|
|
124
146
|
workerd_common = [
|
|
125
|
-
|
|
147
|
+
workerd_bin,
|
|
126
148
|
"test",
|
|
127
149
|
wd_test_file,
|
|
128
150
|
"--experimental",
|