workers-runtime-sdk 1.6.13__tar.gz → 1.6.14__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.6.13 → workers_runtime_sdk-1.6.14}/CHANGELOG.md +8 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/PKG-INFO +1 -1
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/pyproject.toml +4 -1
- workers_runtime_sdk-1.6.14/src/asgi.py +6 -0
- {workers_runtime_sdk-1.6.13/src → workers_runtime_sdk-1.6.14/src/workers}/asgi.py +15 -9
- workers_runtime_sdk-1.6.14/tests/bindings-test/pyproject.toml +5 -0
- {workers_runtime_sdk-1.6.13/tests/web-frameworks-test/fastapi-tests → workers_runtime_sdk-1.6.14/tests/bindings-test}/src/conftest.py +6 -0
- workers_runtime_sdk-1.6.14/tests/bindings-test/src/test_hyperdrive_mysql.py +208 -0
- workers_runtime_sdk-1.6.14/tests/bindings-test/src/test_hyperdrive_postgresql.py +182 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/wrangler.jsonc +12 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/conftest.py +25 -2
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/test_bindings.py +9 -1
- workers_runtime_sdk-1.6.14/tests/web-frameworks-test/fastapi-tests/src/test_error_handling.py +156 -0
- workers_runtime_sdk-1.6.14/tests/web-frameworks-test/fastapi-tests/src/test_platform_lifecycle.py +12 -0
- workers_runtime_sdk-1.6.14/tests/web-frameworks-test/fastapi-tests/src/test_response_types.py +183 -0
- workers_runtime_sdk-1.6.14/tests/web-frameworks-test/fastapi-tests/src/test_routing.py +190 -0
- workers_runtime_sdk-1.6.14/tests/web-frameworks-test/fastapi-tests/src/worker.py +560 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi/tests/test_asgi.py +7 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/uv.lock +1 -1
- workers_runtime_sdk-1.6.13/tests/bindings-test/pyproject.toml +0 -5
- workers_runtime_sdk-1.6.13/tests/web-frameworks-test/fastapi-tests/src/worker.py +0 -251
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/.gitignore +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/AGENTS.md +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/README.md +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/_cloudflare_compat_flags.pyi +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/_pyodide_entrypoint_helper.pyi +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/_workers_sdk_entropy_import_context.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/_workers_sdk_package_patches.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/_workers_sdk_patch_loader.pth +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/_workers_sdk_patch_loader.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/__init__.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/blob.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/entrypoints.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/fetch.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/formdata.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/py.typed +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/request.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/response.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/rpc.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/types.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/utils.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/workflows.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/src/workers/wsgi.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/public/data.json +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/public/hello.txt +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_analytics_engine.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_assets.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_d1.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_do.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_images.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_kv.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_mtls.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_queue.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_r2.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_ratelimit.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_vectorize.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_version_metadata.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/test_workflow.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/worker_durable_object.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/src/worker_workflow.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/test_fastapi.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/test_in_workerd.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/test_web_frameworks.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/_client.py +0 -0
- {workers_runtime_sdk-1.6.13/tests/bindings-test → workers_runtime_sdk-1.6.14/tests/web-frameworks-test/django-async}/src/conftest.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/__init__.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/api_urls.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/auth_backend.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/drf_auth.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/drf_serializers.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/drf_throttling.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/drf_views.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/forms.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/middleware.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/templatetags/__init__.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/templatetags/custom_tags.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/urls.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/django_app/views.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/templates/base.html +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/templates/context_test.html +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/templates/csrf_form.html +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/templates/hello.html +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_async_utilities.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_auth.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_caching.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_cors.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_csrf.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_drf_auth_permissions.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_drf_content_negotiation.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_drf_serializers.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_drf_throttling.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_drf_versioning.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_drf_views.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_error_handling.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_file_uploads.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_forms.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_middleware.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_pagination.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_request_response.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_sessions.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_signals.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_streaming.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_templates.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_url_routing.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/test_views_basic.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/src/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/django-async/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/public/data.json +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/public/index.html +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/public/style.css +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/src/_client.py +0 -0
- {workers_runtime_sdk-1.6.13/tests/web-frameworks-test/django-async → workers_runtime_sdk-1.6.14/tests/web-frameworks-test/fastapi-tests}/src/conftest.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/src/static/app.css +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/src/static/data.json +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/src/static/hello.txt +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/src/static/index.html +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/src/test_assets.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/src/test_staticfiles.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/src/test_sync_handlers.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/web-frameworks-test/fastapi-tests/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi/asgi.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi-ws-disconnect/asgi-ws-disconnect.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi-ws-disconnect/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi-ws-disconnect/tests/test_ws_disconnect.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi-ws-disconnect/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/asgi-ws-disconnect/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object/durable-object.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-abort/durable-object-abort.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-abort/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-abort/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-abort/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-inheritance/durable-object-inheritance.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-inheritance/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-inheritance/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-inheritance/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-websocket/durable-object-websocket.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-websocket/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-websocket/tester.js +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-websocket/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/durable-object-websocket/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/entropy-patches.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/tests/test_aiohttp_websocket.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/tests/test_langsmith.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/tests/test_numpy.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/tests/test_pydantic.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/tests/test_rust_packages.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/tests/test_ssl_avoidance.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/entropy-patches/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/python-rpc/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/python-rpc/python-rpc.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/python-rpc/worker.js +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/python-rpc/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/python-rpc/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/sdk/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/sdk/sdk.wd-test +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/sdk/server.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/sdk/tests/test_sdk.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/sdk/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/sdk/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/wsgi/pyproject.toml +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/wsgi/tests/test_wsgi.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/wsgi/worker.py +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/wsgi/wrangler.jsonc +0 -0
- {workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/workerd-test/wsgi/wsgi.wd-test +0 -0
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- version list -->
|
|
4
4
|
|
|
5
|
+
## v1.6.14 (2026-08-19)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- Fixes fastapi lifespan state not persisting
|
|
10
|
+
([`fadd19b`](https://github.com/cloudflare/workers-py/commit/fadd19bcb6ca47518d5e42562879164dd62ab404))
|
|
11
|
+
|
|
12
|
+
|
|
5
13
|
## v1.6.13 (2026-08-12)
|
|
6
14
|
|
|
7
15
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: workers-runtime-sdk
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.14
|
|
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.
|
|
7
|
+
version = "1.6.14"
|
|
8
8
|
description = "Python SDK for Cloudflare Workers"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -64,6 +64,9 @@ lint.per-file-ignores."tests/web-frameworks-test/**" = ["C901", "PLR0911", "PLR0
|
|
|
64
64
|
|
|
65
65
|
[tool.pytest.ini_options]
|
|
66
66
|
addopts = ["--ignore=tests/workerd-test", "--ignore=tests/bindings-test", "--ignore=tests/web-frameworks-test"]
|
|
67
|
+
markers = [
|
|
68
|
+
"hyperdrive: needs MySQL and PostgreSQL on localhost; skipped unless run with -m hyperdrive",
|
|
69
|
+
]
|
|
67
70
|
|
|
68
71
|
[tool.mypy]
|
|
69
72
|
packages = ["workers_runtime_sdk"]
|
|
@@ -49,7 +49,7 @@ def acquire_js_buffer(pybuffer):
|
|
|
49
49
|
buf.release()
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
def request_to_scope(req, env, ws=False):
|
|
52
|
+
def request_to_scope(req, env, ws=False, state=None):
|
|
53
53
|
from js import URL
|
|
54
54
|
|
|
55
55
|
# @app.get("/example")
|
|
@@ -74,7 +74,7 @@ def request_to_scope(req, env, ws=False):
|
|
|
74
74
|
ty = "websocket"
|
|
75
75
|
else:
|
|
76
76
|
ty = "http"
|
|
77
|
-
|
|
77
|
+
scope = {
|
|
78
78
|
"asgi": ASGI,
|
|
79
79
|
"headers": headers,
|
|
80
80
|
"http_version": "1.1",
|
|
@@ -86,6 +86,10 @@ def request_to_scope(req, env, ws=False):
|
|
|
86
86
|
"type": ty,
|
|
87
87
|
"env": env,
|
|
88
88
|
}
|
|
89
|
+
if state is not None:
|
|
90
|
+
# ASGI requires a shallow copy of lifespan state for each request.
|
|
91
|
+
scope["state"] = dict(state)
|
|
92
|
+
return scope
|
|
89
93
|
|
|
90
94
|
|
|
91
95
|
async def start_application(app):
|
|
@@ -94,6 +98,7 @@ async def start_application(app):
|
|
|
94
98
|
# don't implement it and fall back to serving requests without lifespan.
|
|
95
99
|
# https://asgi.readthedocs.io/en/latest/specs/lifespan.html
|
|
96
100
|
receive_queue = Queue()
|
|
101
|
+
state = {}
|
|
97
102
|
await receive_queue.put({"type": "lifespan.startup"})
|
|
98
103
|
|
|
99
104
|
# `startup` resolves True on `lifespan.startup.complete`, False when the app
|
|
@@ -141,7 +146,7 @@ async def start_application(app):
|
|
|
141
146
|
await app(
|
|
142
147
|
{
|
|
143
148
|
"asgi": ASGI,
|
|
144
|
-
"state":
|
|
149
|
+
"state": state,
|
|
145
150
|
"type": "lifespan",
|
|
146
151
|
},
|
|
147
152
|
receive,
|
|
@@ -168,17 +173,18 @@ async def start_application(app):
|
|
|
168
173
|
run_in_background(run_lifespan())
|
|
169
174
|
supported = await startup
|
|
170
175
|
if not supported:
|
|
171
|
-
return no_lifespan_shutdown
|
|
172
|
-
return shutdown
|
|
176
|
+
return no_lifespan_shutdown, state
|
|
177
|
+
return shutdown, state
|
|
173
178
|
|
|
174
179
|
|
|
175
|
-
async def process_request(
|
|
180
|
+
async def process_request( # noqa: PLR0913
|
|
176
181
|
app: Any,
|
|
177
182
|
req: "Request | js.Request",
|
|
178
183
|
env: Any,
|
|
179
184
|
# added for waitUntil, but not used anymore
|
|
180
185
|
# TODO(later): remove this parameter after unvendoring Python SDK from workerd
|
|
181
186
|
ctx: Context | None,
|
|
187
|
+
state: dict[str, Any] | None = None,
|
|
182
188
|
) -> js.Response:
|
|
183
189
|
from js import Response, TransformStream
|
|
184
190
|
from pyodide.ffi import create_proxy
|
|
@@ -273,7 +279,7 @@ async def process_request(
|
|
|
273
279
|
# Run the application in the background
|
|
274
280
|
async def run_app():
|
|
275
281
|
try:
|
|
276
|
-
await app(request_to_scope(req, env), receive, send)
|
|
282
|
+
await app(request_to_scope(req, env, state=state), receive, send)
|
|
277
283
|
|
|
278
284
|
# If we get here and no response has been set yet, the app didn't generate a response
|
|
279
285
|
if not result.done():
|
|
@@ -380,9 +386,9 @@ async def fetch(
|
|
|
380
386
|
app: Any, req: "Request | js.Request", env: Any, ctx: Context | None = None
|
|
381
387
|
) -> js.Response:
|
|
382
388
|
logger.debug("ASGI request: %s %s", req.method, req.url)
|
|
383
|
-
shutdown = await start_application(app)
|
|
389
|
+
shutdown, state = await start_application(app)
|
|
384
390
|
try:
|
|
385
|
-
result = await process_request(app, req, env, ctx)
|
|
391
|
+
result = await process_request(app, req, env, ctx, state=state)
|
|
386
392
|
except Exception:
|
|
387
393
|
logger.exception("ASGI request failed")
|
|
388
394
|
raise
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# pyright: reportMissingImports=false
|
|
2
|
+
import uuid
|
|
2
3
|
|
|
3
4
|
import pytest
|
|
4
5
|
|
|
@@ -8,3 +9,8 @@ from workers import env as _env
|
|
|
8
9
|
@pytest.fixture
|
|
9
10
|
def env():
|
|
10
11
|
return _env
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def unique_table_name() -> str:
|
|
15
|
+
"""Unique per call"""
|
|
16
|
+
return f"test_{uuid.uuid4().hex[:10]}"
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# pyright: reportMissingImports=false
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
This test requires a MySQL server to be running on localhost.
|
|
5
|
+
|
|
6
|
+
Run mysql with docker:
|
|
7
|
+
|
|
8
|
+
docker run -d --name mysql \
|
|
9
|
+
-e MYSQL_ROOT_PASSWORD=rootpass \
|
|
10
|
+
-e MYSQL_USER=testuser \
|
|
11
|
+
-e MYSQL_PASSWORD=testpass \
|
|
12
|
+
-e MYSQL_DATABASE=testdb \
|
|
13
|
+
-p 3306:3306 \
|
|
14
|
+
--health-cmd="mysqladmin ping -h 127.0.0.1" \
|
|
15
|
+
--health-interval=10s \
|
|
16
|
+
--health-timeout=5s \
|
|
17
|
+
--health-retries=5 \
|
|
18
|
+
mysql:8.4
|
|
19
|
+
|
|
20
|
+
Then run the test:
|
|
21
|
+
|
|
22
|
+
uv run pytest tests/test_bindings.py -m hyperdrive -k mysql
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
import sys
|
|
26
|
+
|
|
27
|
+
import pymysql
|
|
28
|
+
import pytest
|
|
29
|
+
from conftest import unique_table_name
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@pytest.fixture(autouse=True)
|
|
33
|
+
def skip_if_no_socket_support():
|
|
34
|
+
if sys.version_info.minor < 14:
|
|
35
|
+
pytest.skip("Socket support requires Python 3.14+")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _connect(env):
|
|
39
|
+
hd = env.HYPERDRIVE_MYSQL
|
|
40
|
+
return pymysql.connect(
|
|
41
|
+
host=hd.host,
|
|
42
|
+
port=int(hd.port),
|
|
43
|
+
user=hd.user,
|
|
44
|
+
password=hd.password,
|
|
45
|
+
database=hd.database,
|
|
46
|
+
unix_socket=False,
|
|
47
|
+
# Hyperdrive terminates TLS to the origin, so this hop is plaintext.
|
|
48
|
+
ssl_disabled=True,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@pytest.mark.asyncio
|
|
53
|
+
async def test_connect(env):
|
|
54
|
+
conn = _connect(env)
|
|
55
|
+
cur = conn.cursor()
|
|
56
|
+
cur.execute("SELECT 1")
|
|
57
|
+
assert cur.fetchone() == (1,)
|
|
58
|
+
conn.close()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@pytest.mark.asyncio
|
|
62
|
+
async def test_create_insert_select(env):
|
|
63
|
+
conn = _connect(env)
|
|
64
|
+
table = unique_table_name()
|
|
65
|
+
cur = conn.cursor()
|
|
66
|
+
try:
|
|
67
|
+
cur.execute(
|
|
68
|
+
f"CREATE TABLE {table} "
|
|
69
|
+
"(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), value INT)"
|
|
70
|
+
)
|
|
71
|
+
cur.execute(f"INSERT INTO {table} (name, value) VALUES (%s, %s)", ("alpha", 1))
|
|
72
|
+
cur.execute(f"INSERT INTO {table} (name, value) VALUES (%s, %s)", ("beta", 2))
|
|
73
|
+
conn.commit()
|
|
74
|
+
|
|
75
|
+
cur.execute(f"SELECT name, value FROM {table} ORDER BY name")
|
|
76
|
+
assert cur.fetchall() == (("alpha", 1), ("beta", 2))
|
|
77
|
+
finally:
|
|
78
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
79
|
+
conn.commit()
|
|
80
|
+
conn.close()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@pytest.mark.asyncio
|
|
84
|
+
async def test_update(env):
|
|
85
|
+
conn = _connect(env)
|
|
86
|
+
table = unique_table_name()
|
|
87
|
+
cur = conn.cursor()
|
|
88
|
+
try:
|
|
89
|
+
cur.execute(
|
|
90
|
+
f"CREATE TABLE {table} "
|
|
91
|
+
"(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), value INT)"
|
|
92
|
+
)
|
|
93
|
+
cur.execute(f"INSERT INTO {table} (name, value) VALUES (%s, %s)", ("alpha", 1))
|
|
94
|
+
conn.commit()
|
|
95
|
+
|
|
96
|
+
cur.execute(
|
|
97
|
+
f"UPDATE {table} SET value = value + 10 WHERE name = %s", ("alpha",)
|
|
98
|
+
)
|
|
99
|
+
conn.commit()
|
|
100
|
+
|
|
101
|
+
cur.execute(f"SELECT value FROM {table} WHERE name = %s", ("alpha",))
|
|
102
|
+
assert cur.fetchone() == (11,)
|
|
103
|
+
finally:
|
|
104
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
105
|
+
conn.commit()
|
|
106
|
+
conn.close()
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@pytest.mark.asyncio
|
|
110
|
+
async def test_delete(env):
|
|
111
|
+
conn = _connect(env)
|
|
112
|
+
table = unique_table_name()
|
|
113
|
+
cur = conn.cursor()
|
|
114
|
+
try:
|
|
115
|
+
cur.execute(
|
|
116
|
+
f"CREATE TABLE {table} (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100))"
|
|
117
|
+
)
|
|
118
|
+
cur.execute(f"INSERT INTO {table} (name) VALUES (%s)", ("alpha",))
|
|
119
|
+
cur.execute(f"INSERT INTO {table} (name) VALUES (%s)", ("beta",))
|
|
120
|
+
conn.commit()
|
|
121
|
+
|
|
122
|
+
cur.execute(f"DELETE FROM {table} WHERE name = %s", ("alpha",))
|
|
123
|
+
conn.commit()
|
|
124
|
+
|
|
125
|
+
cur.execute(f"SELECT name FROM {table}")
|
|
126
|
+
assert cur.fetchall() == (("beta",),)
|
|
127
|
+
finally:
|
|
128
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
129
|
+
conn.commit()
|
|
130
|
+
conn.close()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@pytest.mark.asyncio
|
|
134
|
+
async def test_transaction_rollback(env):
|
|
135
|
+
conn = _connect(env)
|
|
136
|
+
table = unique_table_name()
|
|
137
|
+
cur = conn.cursor()
|
|
138
|
+
try:
|
|
139
|
+
cur.execute(
|
|
140
|
+
f"CREATE TABLE {table} "
|
|
141
|
+
"(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100)) ENGINE=InnoDB"
|
|
142
|
+
)
|
|
143
|
+
conn.commit()
|
|
144
|
+
|
|
145
|
+
cur.execute(f"INSERT INTO {table} (name) VALUES (%s)", ("should_disappear",))
|
|
146
|
+
conn.rollback()
|
|
147
|
+
|
|
148
|
+
cur.execute(f"SELECT COUNT(*) FROM {table}")
|
|
149
|
+
assert cur.fetchone() == (0,)
|
|
150
|
+
finally:
|
|
151
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
152
|
+
conn.commit()
|
|
153
|
+
conn.close()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@pytest.mark.asyncio
|
|
157
|
+
async def test_multiple_data_types(env):
|
|
158
|
+
conn = _connect(env)
|
|
159
|
+
table = unique_table_name()
|
|
160
|
+
cur = conn.cursor()
|
|
161
|
+
try:
|
|
162
|
+
cur.execute(
|
|
163
|
+
f"CREATE TABLE {table} ("
|
|
164
|
+
"id INT AUTO_INCREMENT PRIMARY KEY, "
|
|
165
|
+
"text_col VARCHAR(255), "
|
|
166
|
+
"int_col INT, "
|
|
167
|
+
"float_col DOUBLE, "
|
|
168
|
+
"bool_col BOOLEAN)"
|
|
169
|
+
)
|
|
170
|
+
cur.execute(
|
|
171
|
+
f"INSERT INTO {table} (text_col, int_col, float_col, bool_col) "
|
|
172
|
+
"VALUES (%s, %s, %s, %s)",
|
|
173
|
+
("hello", 42, 3.14, True),
|
|
174
|
+
)
|
|
175
|
+
conn.commit()
|
|
176
|
+
|
|
177
|
+
cur.execute(f"SELECT text_col, int_col, float_col, bool_col FROM {table}")
|
|
178
|
+
row = cur.fetchone()
|
|
179
|
+
assert row[0] == "hello"
|
|
180
|
+
assert row[1] == 42
|
|
181
|
+
assert abs(row[2] - 3.14) < 0.001
|
|
182
|
+
assert row[3] == 1
|
|
183
|
+
finally:
|
|
184
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
185
|
+
conn.commit()
|
|
186
|
+
conn.close()
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@pytest.mark.asyncio
|
|
190
|
+
async def test_executemany(env):
|
|
191
|
+
conn = _connect(env)
|
|
192
|
+
table = unique_table_name()
|
|
193
|
+
cur = conn.cursor()
|
|
194
|
+
try:
|
|
195
|
+
cur.execute(
|
|
196
|
+
f"CREATE TABLE {table} (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100))"
|
|
197
|
+
)
|
|
198
|
+
cur.executemany(
|
|
199
|
+
f"INSERT INTO {table} (name) VALUES (%s)", [("a",), ("b",), ("c",)]
|
|
200
|
+
)
|
|
201
|
+
conn.commit()
|
|
202
|
+
|
|
203
|
+
cur.execute(f"SELECT name FROM {table} ORDER BY name")
|
|
204
|
+
assert cur.fetchall() == (("a",), ("b",), ("c",))
|
|
205
|
+
finally:
|
|
206
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
207
|
+
conn.commit()
|
|
208
|
+
conn.close()
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# pyright: reportMissingImports=false
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
This test requires a PostgreSQL server to be running on localhost.
|
|
5
|
+
|
|
6
|
+
Run postgresql with docker:
|
|
7
|
+
|
|
8
|
+
docker run -d --name postgres \
|
|
9
|
+
-e POSTGRES_USER=testuser \
|
|
10
|
+
-e POSTGRES_PASSWORD=testpass \
|
|
11
|
+
-e POSTGRES_DB=testdb \
|
|
12
|
+
-e POSTGRES_HOST_AUTH_METHOD=md5 \
|
|
13
|
+
-e POSTGRES_INITDB_ARGS="--auth-host=md5" \
|
|
14
|
+
-p 5432:5432 \
|
|
15
|
+
--health-cmd="pg_isready -U testuser -d testdb" \
|
|
16
|
+
--health-interval=10s \
|
|
17
|
+
--health-timeout=5s \
|
|
18
|
+
--health-retries=5 \
|
|
19
|
+
postgres:16
|
|
20
|
+
|
|
21
|
+
Then run the test:
|
|
22
|
+
|
|
23
|
+
uv run pytest tests/test_bindings.py -m hyperdrive -k postgresql
|
|
24
|
+
|
|
25
|
+
Note: "POSTGRES_HOST_AUTH_METHOD=md5" is required for PostgreSQL to work with pg8000, since the
|
|
26
|
+
default `scram-sha-256` is not available in the pg8000 with Python workers (missing openssl)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
import sys
|
|
30
|
+
|
|
31
|
+
import pg8000
|
|
32
|
+
import pytest
|
|
33
|
+
from conftest import unique_table_name
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.fixture(autouse=True)
|
|
37
|
+
def skip_if_no_socket_support():
|
|
38
|
+
if sys.version_info.minor < 14:
|
|
39
|
+
pytest.skip("Socket support requires Python 3.14+")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _connect(env):
|
|
43
|
+
hd = env.HYPERDRIVE_PG
|
|
44
|
+
return pg8000.connect(
|
|
45
|
+
host=hd.host,
|
|
46
|
+
port=int(hd.port),
|
|
47
|
+
user=hd.user,
|
|
48
|
+
password=hd.password,
|
|
49
|
+
database=hd.database,
|
|
50
|
+
# Hyperdrive terminates TLS to the origin, so this hop is plaintext.
|
|
51
|
+
ssl_context=False,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@pytest.mark.asyncio
|
|
56
|
+
async def test_connect(env):
|
|
57
|
+
conn = _connect(env)
|
|
58
|
+
cur = conn.cursor()
|
|
59
|
+
cur.execute("SELECT 1")
|
|
60
|
+
assert cur.fetchone() == [1]
|
|
61
|
+
conn.close()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@pytest.mark.asyncio
|
|
65
|
+
async def test_create_insert_select(env):
|
|
66
|
+
conn = _connect(env)
|
|
67
|
+
table = unique_table_name()
|
|
68
|
+
cur = conn.cursor()
|
|
69
|
+
try:
|
|
70
|
+
cur.execute(
|
|
71
|
+
f"CREATE TABLE {table} (id SERIAL PRIMARY KEY, name TEXT, value INT)"
|
|
72
|
+
)
|
|
73
|
+
cur.execute(f"INSERT INTO {table} (name, value) VALUES (%s, %s)", ("alpha", 1))
|
|
74
|
+
cur.execute(f"INSERT INTO {table} (name, value) VALUES (%s, %s)", ("beta", 2))
|
|
75
|
+
conn.commit()
|
|
76
|
+
|
|
77
|
+
cur.execute(f"SELECT name, value FROM {table} ORDER BY name")
|
|
78
|
+
assert list(cur.fetchall()) == [["alpha", 1], ["beta", 2]]
|
|
79
|
+
finally:
|
|
80
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
81
|
+
conn.commit()
|
|
82
|
+
conn.close()
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@pytest.mark.asyncio
|
|
86
|
+
async def test_update(env):
|
|
87
|
+
conn = _connect(env)
|
|
88
|
+
table = unique_table_name()
|
|
89
|
+
cur = conn.cursor()
|
|
90
|
+
try:
|
|
91
|
+
cur.execute(
|
|
92
|
+
f"CREATE TABLE {table} (id SERIAL PRIMARY KEY, name TEXT, value INT)"
|
|
93
|
+
)
|
|
94
|
+
cur.execute(f"INSERT INTO {table} (name, value) VALUES (%s, %s)", ("alpha", 1))
|
|
95
|
+
conn.commit()
|
|
96
|
+
|
|
97
|
+
cur.execute(
|
|
98
|
+
f"UPDATE {table} SET value = value + 10 WHERE name = %s", ("alpha",)
|
|
99
|
+
)
|
|
100
|
+
conn.commit()
|
|
101
|
+
|
|
102
|
+
cur.execute(f"SELECT value FROM {table} WHERE name = %s", ("alpha",))
|
|
103
|
+
assert cur.fetchone() == [11]
|
|
104
|
+
finally:
|
|
105
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
106
|
+
conn.commit()
|
|
107
|
+
conn.close()
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@pytest.mark.asyncio
|
|
111
|
+
async def test_delete(env):
|
|
112
|
+
conn = _connect(env)
|
|
113
|
+
table = unique_table_name()
|
|
114
|
+
cur = conn.cursor()
|
|
115
|
+
try:
|
|
116
|
+
cur.execute(f"CREATE TABLE {table} (id SERIAL PRIMARY KEY, name TEXT)")
|
|
117
|
+
cur.execute(f"INSERT INTO {table} (name) VALUES (%s)", ("alpha",))
|
|
118
|
+
cur.execute(f"INSERT INTO {table} (name) VALUES (%s)", ("beta",))
|
|
119
|
+
conn.commit()
|
|
120
|
+
|
|
121
|
+
cur.execute(f"DELETE FROM {table} WHERE name = %s", ("alpha",))
|
|
122
|
+
conn.commit()
|
|
123
|
+
|
|
124
|
+
cur.execute(f"SELECT name FROM {table}")
|
|
125
|
+
assert list(cur.fetchall()) == [["beta"]]
|
|
126
|
+
finally:
|
|
127
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
128
|
+
conn.commit()
|
|
129
|
+
conn.close()
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.mark.asyncio
|
|
133
|
+
async def test_transaction_rollback(env):
|
|
134
|
+
conn = _connect(env)
|
|
135
|
+
table = unique_table_name()
|
|
136
|
+
cur = conn.cursor()
|
|
137
|
+
try:
|
|
138
|
+
cur.execute(f"CREATE TABLE {table} (id SERIAL PRIMARY KEY, name TEXT)")
|
|
139
|
+
conn.commit()
|
|
140
|
+
|
|
141
|
+
cur.execute(f"INSERT INTO {table} (name) VALUES (%s)", ("should_disappear",))
|
|
142
|
+
conn.rollback()
|
|
143
|
+
|
|
144
|
+
cur.execute(f"SELECT COUNT(*) FROM {table}")
|
|
145
|
+
assert cur.fetchone() == [0]
|
|
146
|
+
finally:
|
|
147
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
148
|
+
conn.commit()
|
|
149
|
+
conn.close()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@pytest.mark.asyncio
|
|
153
|
+
async def test_multiple_data_types(env):
|
|
154
|
+
conn = _connect(env)
|
|
155
|
+
table = unique_table_name()
|
|
156
|
+
cur = conn.cursor()
|
|
157
|
+
try:
|
|
158
|
+
cur.execute(
|
|
159
|
+
f"CREATE TABLE {table} ("
|
|
160
|
+
"id SERIAL PRIMARY KEY, "
|
|
161
|
+
"text_col TEXT, "
|
|
162
|
+
"int_col INT, "
|
|
163
|
+
"float_col DOUBLE PRECISION, "
|
|
164
|
+
"bool_col BOOLEAN)"
|
|
165
|
+
)
|
|
166
|
+
cur.execute(
|
|
167
|
+
f"INSERT INTO {table} (text_col, int_col, float_col, bool_col) "
|
|
168
|
+
"VALUES (%s, %s, %s, %s)",
|
|
169
|
+
("hello", 42, 3.14, True),
|
|
170
|
+
)
|
|
171
|
+
conn.commit()
|
|
172
|
+
|
|
173
|
+
cur.execute(f"SELECT text_col, int_col, float_col, bool_col FROM {table}")
|
|
174
|
+
row = cur.fetchone()
|
|
175
|
+
assert row[0] == "hello"
|
|
176
|
+
assert row[1] == 42
|
|
177
|
+
assert abs(row[2] - 3.14) < 0.001
|
|
178
|
+
assert row[3] is True
|
|
179
|
+
finally:
|
|
180
|
+
cur.execute(f"DROP TABLE IF EXISTS {table}")
|
|
181
|
+
conn.commit()
|
|
182
|
+
conn.close()
|
{workers_runtime_sdk-1.6.13 → workers_runtime_sdk-1.6.14}/tests/bindings-test/wrangler.jsonc
RENAMED
|
@@ -49,6 +49,18 @@
|
|
|
49
49
|
"analytics_engine_datasets": [
|
|
50
50
|
{ "binding": "ANALYTICS", "dataset": "test-dataset" }
|
|
51
51
|
],
|
|
52
|
+
"hyperdrive": [
|
|
53
|
+
{
|
|
54
|
+
"binding": "HYPERDRIVE_PG",
|
|
55
|
+
"id": "00000000-0000-0000-0000-000000000001",
|
|
56
|
+
"localConnectionString": "postgres://testuser:testpass@127.0.0.1:5432/testdb"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"binding": "HYPERDRIVE_MYSQL",
|
|
60
|
+
"id": "00000000-0000-0000-0000-000000000002",
|
|
61
|
+
"localConnectionString": "mysql://testuser:testpass@127.0.0.1:3306/testdb"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
52
64
|
"images": { "binding": "IMAGES" },
|
|
53
65
|
"ratelimits": [
|
|
54
66
|
{ "name": "RATE_LIMITER", "namespace_id": "1001", "simple": { "period": 60, "limit": 100 } }
|
|
@@ -24,6 +24,22 @@ DEV_POLL_INTERVAL: float = 0.5
|
|
|
24
24
|
SUITE_CONNECT_TIMEOUT: int = 10
|
|
25
25
|
SUITE_READ_TIMEOUT: int = 300
|
|
26
26
|
|
|
27
|
+
OPT_IN_MARKERS: tuple[str, ...] = ("hyperdrive",)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def pytest_collection_modifyitems(
|
|
31
|
+
config: pytest.Config, items: list[pytest.Item]
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Skip opt-in suites unless the run explicitly asks for them via ``-m``."""
|
|
34
|
+
markexpr: str = config.getoption("markexpr")
|
|
35
|
+
for marker in OPT_IN_MARKERS:
|
|
36
|
+
if marker in markexpr:
|
|
37
|
+
continue
|
|
38
|
+
skip = pytest.mark.skip(reason=f"needs local services; run with -m {marker}")
|
|
39
|
+
for item in items:
|
|
40
|
+
if marker in item.keywords:
|
|
41
|
+
item.add_marker(skip)
|
|
42
|
+
|
|
27
43
|
|
|
28
44
|
@dataclass(frozen=True)
|
|
29
45
|
class CompatConfig:
|
|
@@ -256,12 +272,19 @@ def discover_suites(src_dir: Path) -> dict[str, list[str]]:
|
|
|
256
272
|
}
|
|
257
273
|
|
|
258
274
|
|
|
259
|
-
def register_in_worker_suites(
|
|
275
|
+
def register_in_worker_suites(
|
|
276
|
+
namespace: dict[str, Any],
|
|
277
|
+
src_dir: Path,
|
|
278
|
+
marks: dict[str, pytest.MarkDecorator] | None = None,
|
|
279
|
+
) -> None:
|
|
260
280
|
"""Define a ``TestXxx`` class in `namespace` for every suite found in `src_dir`.
|
|
261
281
|
|
|
262
282
|
Call with ``globals()`` from a test module so each in-worker test surfaces as
|
|
263
|
-
its own pytest case without manual registration.
|
|
283
|
+
its own pytest case without manual registration. `marks` applies a marker to
|
|
284
|
+
the class generated for the suite of the same name.
|
|
264
285
|
"""
|
|
265
286
|
for suite, test_names in discover_suites(src_dir).items():
|
|
266
287
|
suite_cls = make_suite_class(suite, test_names)
|
|
288
|
+
if marks and suite in marks:
|
|
289
|
+
suite_cls = marks[suite](suite_cls)
|
|
267
290
|
namespace[suite_cls.__name__] = suite_cls
|
|
@@ -18,10 +18,18 @@ from conftest import register_in_worker_suites
|
|
|
18
18
|
BINDINGS_TEST_DIR: Path = Path(__file__).parent / "bindings-test"
|
|
19
19
|
BINDINGS_SRC_DIR: Path = BINDINGS_TEST_DIR / "src"
|
|
20
20
|
|
|
21
|
+
SUITE_MARKS: dict[str, pytest.MarkDecorator] = {
|
|
22
|
+
# hyperdrive tests require external databases to be running
|
|
23
|
+
# so it is skipped by default.
|
|
24
|
+
# See each test file for details on how to run them.
|
|
25
|
+
"hyperdrive_postgresql": pytest.mark.hyperdrive,
|
|
26
|
+
"hyperdrive_mysql": pytest.mark.hyperdrive,
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
|
|
22
30
|
@pytest.fixture(scope="module")
|
|
23
31
|
def worker_project_dir() -> Path:
|
|
24
32
|
return BINDINGS_TEST_DIR
|
|
25
33
|
|
|
26
34
|
|
|
27
|
-
register_in_worker_suites(globals(), BINDINGS_SRC_DIR)
|
|
35
|
+
register_in_worker_suites(globals(), BINDINGS_SRC_DIR, marks=SUITE_MARKS)
|