clientwright 0.4.1__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {clientwright-0.4.1 → clientwright-0.5.0}/CHANGELOG.md +7 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/PKG-INFO +15 -1
- {clientwright-0.4.1 → clientwright-0.5.0}/README.md +11 -0
- clientwright-0.5.0/clientwright/__version__.py +1 -0
- clientwright-0.5.0/clientwright/contrib/servicewright.py +47 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/pyproject.toml +3 -2
- clientwright-0.5.0/tests/integration/contrib/test_servicewright.py +29 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/test_bare_install.py +15 -0
- clientwright-0.5.0/tests/unit/contrib/test_servicewright.py +23 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/test_sdk_imports_are_guarded.py +1 -0
- clientwright-0.4.1/clientwright/__version__.py +0 -1
- {clientwright-0.4.1 → clientwright-0.5.0}/.gitignore +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/LICENSE +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/_httpx_shared.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/_lazy.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/_imports.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/adapter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/capabilities.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/classify.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/errors.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/middleware.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/normalize.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/options.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/trace.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/aiohttp/views.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/_imports.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/adapter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/capabilities.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/classify.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/errors.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/normalize.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/normalize_sync.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/transport.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx/views.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/_imports.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/adapter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/capabilities.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/classify.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/errors.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/normalize.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/normalize_sync.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/transport.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/httpx2/views.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/_metrics/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/_metrics/prometheus.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/_tracing/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/_tracing/otel.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/requests/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/requests/_imports.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/requests/adapter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/requests/capabilities.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/requests/classify.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/requests/errors.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/requests/normalize.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/requests/views.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/urllib3/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/urllib3/_imports.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/urllib3/adapter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/urllib3/capabilities.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/urllib3/classify.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/urllib3/errors.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/urllib3/normalize.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/urllib3/views.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/contrib/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/contrib/deadline.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/contrib/dishka.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/contrib/settings.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/balancer/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/balancer/policy.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/capabilities.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/config.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/contracts/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/contracts/adapter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/contracts/context.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/contracts/message.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/contracts/observability.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/contracts/settings.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/engine/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/engine/aio.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/engine/base.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/engine/redirects.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/engine/suppress.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/engine/sync.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/errors.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/model.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/native.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/options.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/plan.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/policy/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/policy/budget.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/policy/circuit.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/policy/concurrency.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/policy/retry.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/policy/timeout.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/registry.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/telemetry/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/telemetry/emitter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/telemetry/names.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/telemetry/null.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/telemetry/redaction.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/testing/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/testing/doubles.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/core/testing/origin.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/clientwright/py.typed +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/conftest.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/helpers/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/helpers/drivers.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/helpers/engine.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/helpers/telemetry.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/helpers/views.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/adapters/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/adapters/test_aiohttp.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/adapters/test_httpx2.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/adapters/test_httpx_async.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/adapters/test_httpx_sync.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/adapters/test_requests.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/adapters/test_urllib3.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/chaos/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/chaos/test_faults.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/chaos/test_origin_faults.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/conftest.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/contrib/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/contrib/test_deadline.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/contrib/test_dishka.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/parity/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/integration/parity/test_semantics.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/live/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/live/conftest.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/live/test_public_endpoints.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/live/test_tls_and_dns.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/aiohttp/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/aiohttp/test_build.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/aiohttp/test_normalize.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/aiohttp/test_trace.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/aiohttp/test_units.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/conftest.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/httpx/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/httpx/test_units.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/httpx2/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/httpx2/test_units.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/observability/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/observability/test_exports.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/observability/test_otel.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/observability/test_prometheus.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/requests/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/requests/test_adapter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/requests/test_normalize.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/requests/test_units.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/test_httpx_family_parity.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/test_httpx_shared.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/urllib3/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/urllib3/test_adapter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/urllib3/test_normalize.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/urllib3/test_units.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/contrib/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/contrib/test_deadline.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/contrib/test_deadline_context.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/contrib/test_dishka.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/contrib/test_settings.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/engine/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/engine/test_aio.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/engine/test_base.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/engine/test_redirects.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/engine/test_suppress.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/engine/test_sync.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/test_budget.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/test_circuit.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/test_circuit_properties.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/test_concurrency.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/test_retry.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/test_retry_properties.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/test_timeout.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/policy/test_timeout_properties.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/telemetry/__init__.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/telemetry/test_emitter.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/telemetry/test_masking.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/telemetry/test_redaction.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/telemetry/test_redaction_properties.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_balancer.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_capabilities.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_capabilities_properties.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_config.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_enum_coercion.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_errors.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_model.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_options.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_plan.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_registry.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/test_settings.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/test_docs_snippets.py +0 -0
- {clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/test_version.py +0 -0
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.0](https://github.com/bedrock-python/clientwright/compare/clientwright-v0.4.1...clientwright-v0.5.0) (2026-09-15)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* clientwright.contrib.servicewright behind a [servicewright] extra ([777c5f3](https://github.com/bedrock-python/clientwright/commit/777c5f3d0fb3cf35f2c3d08ede87058fa022b4f2)), closes [#41](https://github.com/bedrock-python/clientwright/issues/41)
|
|
9
|
+
|
|
3
10
|
## [0.4.1](https://github.com/bedrock-python/clientwright/compare/clientwright-v0.4.0...clientwright-v0.4.1) (2026-09-14)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: clientwright
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: HTTP client platform: one resilience and observability core with adapters for httpx, aiohttp, requests, urllib3 and friends
|
|
5
5
|
Project-URL: Repository, https://github.com/bedrock-python/clientwright
|
|
6
6
|
Project-URL: Documentation, https://bedrock-python.github.io/clientwright/
|
|
@@ -35,6 +35,7 @@ Requires-Dist: prometheus-client>=0.20; extra == 'all'
|
|
|
35
35
|
Requires-Dist: pydantic-settings<3,>=2.3; extra == 'all'
|
|
36
36
|
Requires-Dist: pydantic<3,>=2; extra == 'all'
|
|
37
37
|
Requires-Dist: requests<3,>=2.32; extra == 'all'
|
|
38
|
+
Requires-Dist: servicewright<1,>=0.1; extra == 'all'
|
|
38
39
|
Requires-Dist: urllib3<3,>=2.2; extra == 'all'
|
|
39
40
|
Provides-Extra: deadline
|
|
40
41
|
Requires-Dist: deadline-budget<1,>=0.1; extra == 'deadline'
|
|
@@ -51,6 +52,8 @@ Requires-Dist: opentelemetry-api>=1.26; extra == 'observability'
|
|
|
51
52
|
Requires-Dist: prometheus-client>=0.20; extra == 'observability'
|
|
52
53
|
Provides-Extra: requests
|
|
53
54
|
Requires-Dist: requests<3,>=2.32; extra == 'requests'
|
|
55
|
+
Provides-Extra: servicewright
|
|
56
|
+
Requires-Dist: servicewright<1,>=0.1; extra == 'servicewright'
|
|
54
57
|
Provides-Extra: settings
|
|
55
58
|
Requires-Dist: pydantic-settings<3,>=2.3; extra == 'settings'
|
|
56
59
|
Requires-Dist: pydantic<3,>=2; extra == 'settings'
|
|
@@ -211,6 +214,17 @@ with use_budget(BudgetContext.create(total_seconds=5.0)):
|
|
|
211
214
|
await client.get("/users") # runs with what is left of those 5 seconds
|
|
212
215
|
```
|
|
213
216
|
|
|
217
|
+
## Request context
|
|
218
|
+
|
|
219
|
+
With `clientwright[servicewright]`, the ids servicewright bound for the unit of
|
|
220
|
+
work being served travel to the upstream as headers:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
from clientwright.contrib.servicewright import servicewright_headers
|
|
224
|
+
|
|
225
|
+
deps = AdapterDeps(header_providers=servicewright_headers()) # x-request-id, x-user-id, ...
|
|
226
|
+
```
|
|
227
|
+
|
|
214
228
|
## From the environment
|
|
215
229
|
|
|
216
230
|
With `clientwright[settings]`, `ClientConfig` and every sub-config exist as pydantic
|
|
@@ -149,6 +149,17 @@ with use_budget(BudgetContext.create(total_seconds=5.0)):
|
|
|
149
149
|
await client.get("/users") # runs with what is left of those 5 seconds
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
+
## Request context
|
|
153
|
+
|
|
154
|
+
With `clientwright[servicewright]`, the ids servicewright bound for the unit of
|
|
155
|
+
work being served travel to the upstream as headers:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from clientwright.contrib.servicewright import servicewright_headers
|
|
159
|
+
|
|
160
|
+
deps = AdapterDeps(header_providers=servicewright_headers()) # x-request-id, x-user-id, ...
|
|
161
|
+
```
|
|
162
|
+
|
|
152
163
|
## From the environment
|
|
153
164
|
|
|
154
165
|
With `clientwright[settings]`, `ClientConfig` and every sub-config exist as pydantic
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.5.0" # x-release-please-version
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""servicewright integration (``[servicewright]`` extra).
|
|
2
|
+
|
|
3
|
+
servicewright binds the ids of the unit of work being served (``request_id``,
|
|
4
|
+
``user_id``, ``tenant_id``, ``trace_id``) into its request context, and
|
|
5
|
+
``servicewright.propagation_metadata`` reads them back as outbound headers.
|
|
6
|
+
That function already satisfies clientwright's ``HeaderProvider`` protocol
|
|
7
|
+
bare; this module names the join so no service writes it by hand::
|
|
8
|
+
|
|
9
|
+
from clientwright.contrib.servicewright import servicewright_headers
|
|
10
|
+
|
|
11
|
+
deps = AdapterDeps(header_providers=servicewright_headers())
|
|
12
|
+
client = build("httpx", config, deps)
|
|
13
|
+
|
|
14
|
+
await client.get("/users") # carries x-request-id and friends, when bound
|
|
15
|
+
|
|
16
|
+
Outside a bound context the provider returns nothing and the request goes out
|
|
17
|
+
as before. The helper returns the providers tuple rather than a whole
|
|
18
|
+
``AdapterDeps`` so it composes with everything else injected there -
|
|
19
|
+
``contrib.deadline`` included - instead of competing with it.
|
|
20
|
+
|
|
21
|
+
Unlike ``contrib.deadline`` there is nothing structural to type here; the real
|
|
22
|
+
function is the point, so servicewright is imported at module import time and
|
|
23
|
+
a missing extra fails right here with an install hint.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
from servicewright import propagation_metadata
|
|
30
|
+
except ImportError as exc: # pragma: no cover - exercised only without the extra
|
|
31
|
+
raise ImportError("servicewright integration requires clientwright[servicewright]; install it.") from exc
|
|
32
|
+
|
|
33
|
+
from ..core.contracts.context import HeaderProvider
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def servicewright_headers() -> tuple[HeaderProvider, ...]:
|
|
37
|
+
"""The header providers carrying servicewright's request context upstream.
|
|
38
|
+
|
|
39
|
+
``(propagation_metadata,)`` under servicewright's standard mapping - the
|
|
40
|
+
request, user, tenant and trace ids as ``x-request-id``, ``x-user-id``,
|
|
41
|
+
``x-tenant-id`` and ``x-trace-id``. For a different mapping build the tuple
|
|
42
|
+
yourself: ``(partial(propagation_metadata, keys),)``.
|
|
43
|
+
"""
|
|
44
|
+
return (propagation_metadata,)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
__all__ = ["servicewright_headers"]
|
|
@@ -58,7 +58,8 @@ observability = ["clientwright[metrics,tracing]"]
|
|
|
58
58
|
deadline = ["deadline-budget>=0.1,<1"]
|
|
59
59
|
dishka = ["dishka>=1.4"]
|
|
60
60
|
settings = ["pydantic>=2,<3", "pydantic-settings>=2.3,<3"]
|
|
61
|
-
|
|
61
|
+
servicewright = ["servicewright>=0.1,<1"]
|
|
62
|
+
all = ["clientwright[httpx,httpx2,aiohttp,requests,urllib3,observability,deadline,dishka,settings,servicewright]"]
|
|
62
63
|
|
|
63
64
|
[dependency-groups]
|
|
64
65
|
test = [
|
|
@@ -180,7 +181,7 @@ source_modules = ["clientwright.core"]
|
|
|
180
181
|
forbidden_modules = [
|
|
181
182
|
"httpx", "httpx2", "aiohttp", "requests", "urllib3", "niquests",
|
|
182
183
|
"tornado", "aiosonic", "pydantic", "dishka", "prometheus_client",
|
|
183
|
-
"opentelemetry", "structlog", "sentry_sdk",
|
|
184
|
+
"opentelemetry", "structlog", "sentry_sdk", "servicewright",
|
|
184
185
|
]
|
|
185
186
|
|
|
186
187
|
# _httpx_shared is deliberately OUTSIDE this list: it is the one sanctioned
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""servicewright's request context flowing through the engine against a real origin."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
httpx = pytest.importorskip("httpx", reason="requires the [httpx] extra")
|
|
8
|
+
servicewright = pytest.importorskip("servicewright", reason="requires the [servicewright] extra")
|
|
9
|
+
|
|
10
|
+
import clientwright # noqa: E402
|
|
11
|
+
from clientwright import AdapterDeps # noqa: E402
|
|
12
|
+
from clientwright.contrib.servicewright import servicewright_headers # noqa: E402
|
|
13
|
+
from clientwright.core.testing import OriginServer # noqa: E402
|
|
14
|
+
|
|
15
|
+
from ..conftest import base_config # noqa: E402
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async def test__bound_context__travels_as_headers_and_only_while_bound(origin: OriginServer) -> None:
|
|
19
|
+
wired = AdapterDeps(header_providers=servicewright_headers())
|
|
20
|
+
client = clientwright.build("httpx", base_config(origin), wired)
|
|
21
|
+
assert isinstance(client, httpx.AsyncClient)
|
|
22
|
+
with servicewright.bind_context(request_id="rid-1", tenant_id="acme"):
|
|
23
|
+
bound = (await client.get("/echo")).json()["headers"]
|
|
24
|
+
outside = (await client.get("/echo")).json()["headers"]
|
|
25
|
+
await client.aclose()
|
|
26
|
+
assert bound["x-request-id"] == "rid-1"
|
|
27
|
+
assert bound["x-tenant-id"] == "acme"
|
|
28
|
+
assert "x-request-id" not in outside
|
|
29
|
+
assert "x-tenant-id" not in outside
|
|
@@ -25,6 +25,7 @@ BLOCKED = (
|
|
|
25
25
|
"deadline_budget",
|
|
26
26
|
"pydantic",
|
|
27
27
|
"pydantic_settings",
|
|
28
|
+
"servicewright",
|
|
28
29
|
)
|
|
29
30
|
|
|
30
31
|
BLOCKER = """
|
|
@@ -163,3 +164,17 @@ def test__settings_models_without_the_extra__fail_with_the_install_hint() -> Non
|
|
|
163
164
|
"""
|
|
164
165
|
)
|
|
165
166
|
assert "clientwright[settings]" in output
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test__contrib_servicewright_without_the_extra__fails_with_the_install_hint() -> None:
|
|
170
|
+
output = run_probe(
|
|
171
|
+
"""
|
|
172
|
+
try:
|
|
173
|
+
import clientwright.contrib.servicewright
|
|
174
|
+
except ImportError as error:
|
|
175
|
+
print(error)
|
|
176
|
+
else:
|
|
177
|
+
print("NO ERROR")
|
|
178
|
+
"""
|
|
179
|
+
)
|
|
180
|
+
assert "clientwright[servicewright]" in output
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""contrib units: the servicewright header providers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
servicewright = pytest.importorskip("servicewright", reason="requires the [servicewright] extra")
|
|
8
|
+
|
|
9
|
+
from clientwright import HeaderProvider # noqa: E402
|
|
10
|
+
from clientwright.contrib.servicewright import servicewright_headers # noqa: E402
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test__providers__are_the_bare_function_and_satisfy_the_protocol() -> None:
|
|
14
|
+
providers = servicewright_headers()
|
|
15
|
+
assert providers == (servicewright.propagation_metadata,)
|
|
16
|
+
assert all(isinstance(provider, HeaderProvider) for provider in providers)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test__provider__reads_the_bound_context_and_nothing_outside_it() -> None:
|
|
20
|
+
(provider,) = servicewright_headers()
|
|
21
|
+
with servicewright.bind_context(request_id="rid-1", user_id="u-9"):
|
|
22
|
+
assert provider() == {"x-request-id": "rid-1", "x-user-id": "u-9"}
|
|
23
|
+
assert provider() == {}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.4.1" # x-release-please-version
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/_metrics/__init__.py
RENAMED
|
File without changes
|
{clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/_metrics/prometheus.py
RENAMED
|
File without changes
|
{clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/_tracing/__init__.py
RENAMED
|
File without changes
|
{clientwright-0.4.1 → clientwright-0.5.0}/clientwright/adapters/observability/_tracing/otel.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/adapters/observability/test_prometheus.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clientwright-0.4.1 → clientwright-0.5.0}/tests/unit/core/telemetry/test_redaction_properties.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|