corehttp 1.0.0b6__tar.gz → 1.0.0b7__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.
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/CHANGELOG.md +30 -0
- {corehttp-1.0.0b6/corehttp.egg-info → corehttp-1.0.0b7}/PKG-INFO +50 -4
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/_version.py +1 -1
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/credentials.py +14 -5
- corehttp-1.0.0b7/corehttp/instrumentation/__init__.py +9 -0
- corehttp-1.0.0b7/corehttp/instrumentation/tracing/__init__.py +14 -0
- corehttp-1.0.0b7/corehttp/instrumentation/tracing/_decorator.py +189 -0
- corehttp-1.0.0b7/corehttp/instrumentation/tracing/_models.py +72 -0
- corehttp-1.0.0b7/corehttp/instrumentation/tracing/_tracer.py +69 -0
- corehttp-1.0.0b7/corehttp/instrumentation/tracing/opentelemetry.py +277 -0
- corehttp-1.0.0b7/corehttp/instrumentation/tracing/utils.py +31 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/paging.py +13 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_aiohttp.py +17 -5
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_http_response_impl.py +7 -7
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_http_response_impl_async.py +2 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_httpx.py +8 -8
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_requests_basic.py +13 -5
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_rest_py3.py +2 -2
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/__init__.py +2 -2
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/_base.py +2 -1
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/_base_async.py +2 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/_tools.py +18 -2
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/__init__.py +2 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_authentication.py +28 -5
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_authentication_async.py +22 -3
- corehttp-1.0.0b7/corehttp/runtime/policies/_distributed_tracing.py +169 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_retry.py +7 -11
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_retry_async.py +4 -8
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_universal.py +11 -0
- corehttp-1.0.0b7/corehttp/serialization.py +358 -0
- corehttp-1.0.0b7/corehttp/settings.py +59 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/_base.py +1 -3
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/_base_async.py +1 -3
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/aiohttp/_aiohttp.py +39 -14
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/requests/_requests_basic.py +31 -16
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/utils/_utils.py +2 -1
- {corehttp-1.0.0b6 → corehttp-1.0.0b7/corehttp.egg-info}/PKG-INFO +50 -4
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/SOURCES.txt +18 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/requires.txt +3 -0
- corehttp-1.0.0b7/samples/sample_tracing.py +97 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/setup.py +6 -2
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_authentication_async.py +60 -3
- corehttp-1.0.0b7/tests/async_tests/test_tracing_decorator_async.py +131 -0
- corehttp-1.0.0b7/tests/async_tests/test_tracing_policy_async.py +68 -0
- corehttp-1.0.0b7/tests/async_tests/test_transport_async.py +121 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/conftest.py +29 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_authentication.py +59 -3
- corehttp-1.0.0b7/tests/test_settings.py +43 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_stream_generator.py +3 -2
- corehttp-1.0.0b7/tests/test_tracer_otel.py +423 -0
- corehttp-1.0.0b7/tests/test_tracing_decorator.py +122 -0
- corehttp-1.0.0b7/tests/test_tracing_policy.py +270 -0
- corehttp-1.0.0b7/tests/test_transport.py +95 -0
- corehttp-1.0.0b6/corehttp/serialization.py +0 -124
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/LICENSE +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/MANIFEST.in +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/README.md +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/_match_conditions.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/exceptions.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/py.typed +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_helpers.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/_base.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/_pipeline_client.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/_pipeline_client_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/_tools_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_base.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_base_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_utils.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/aiohttp/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/httpx/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/httpx/_httpx.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/requests/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/requests/_bigger_block_size_http_adapters.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/utils/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/utils/_enum_meta.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/dependency_links.txt +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/not-zip-safe +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/top_level.txt +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/pyproject.toml +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/samples/sample_async_pipeline_client.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/samples/sample_pipeline_client.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/setup.cfg +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/conftest.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/rest_client_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_content_length_checking_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_paging_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_pipeline_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_context_manager_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_headers_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_http_request_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_http_response_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_stream_responses_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_retry_policy_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_streaming_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_testserver_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_universal_http_async.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/_test_base.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/custom_iterator.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/download_binary.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/list_entities_json.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/query_entities_json.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/update_entity_json.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/upload_binary.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/rest_client.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_content_length_checking.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_enums.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_error_map.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_exceptions.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_paging.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_pipeline.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_requests_universal.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_context_manager.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_headers.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_http_request.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_http_response.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_query.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_stream_responses.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_retry_policy.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_serialization.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_streaming.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_testserver.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_universal_pipeline.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_user_agent_policy.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_utils.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/__init__.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/basic.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/encoding.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/errors.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/headers.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/helpers.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/multipart.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/streams.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/structures.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/urlencoded.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/xml_route.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/setup.py +0 -0
- {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/utils.py +0 -0
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
## 1.0.0b7 (2026-02-05)
|
|
4
|
+
|
|
5
|
+
### Features Added
|
|
6
|
+
|
|
7
|
+
- Native tracing support was added. [#39172](https://github.com/Azure/azure-sdk-for-python/pull/39172)
|
|
8
|
+
- The `OpenTelemetryTracer` class was added to the `corehttp.instrumentation.tracing.opentelemetry` module. This is a wrapper around the OpenTelemetry tracer that is used to create spans for SDK operations.
|
|
9
|
+
- Added a `get_tracer` method to the new `corehttp.instrumentation` module. This method returns an instance of the `OpenTelemetryTracer` class if OpenTelemetry is available.
|
|
10
|
+
- A `TracingOptions` TypedDict class was added to define the options that SDK users can use to configure tracing per-operation. These options include the ability to enable or disable tracing and set additional attributes on spans.
|
|
11
|
+
- Example usage: `client.method(tracing_options={"enabled": True, "attributes": {"foo": "bar"}})`
|
|
12
|
+
- `DistributedHttpTracingPolicy` and `distributed_trace`/`distributed_trace_async` decorators were added to support OpenTelemetry tracing for SDK operations.
|
|
13
|
+
- SDK clients can define an `_instrumentation_config` class variable to configure the OpenTelemetry tracer used in method span creation. Possible configuration options are `library_name`, `library_version`, `schema_url`, and `attributes`.
|
|
14
|
+
- Added a global settings object, `corehttp.settings`, to the `corehttp` package. This object can be used to set global settings for the `corehttp` package. Currently the only setting is `tracing_enabled` for enabling/disabling tracing. [#39172](https://github.com/Azure/azure-sdk-for-python/pull/39172)
|
|
15
|
+
- Added `start_time` and `context` keyword arguments to `OpenTelemetryTracer.start_span` and `start_as_current_span` methods.
|
|
16
|
+
- Added `set_span_error_status` static method to `OpenTelemetryTracer` for setting a span's status to ERROR.
|
|
17
|
+
- Added `is_generated_model`, `attribute_list`, and `TypeHandlerRegistry` to `corehttp.serialization` module for SDK model handling.
|
|
18
|
+
|
|
19
|
+
### Bugs Fixed
|
|
20
|
+
|
|
21
|
+
- Fixed `retry_backoff_max` being ignored in retry policies when configuring retries.
|
|
22
|
+
- Raise correct exception if transport is used while already closed.
|
|
23
|
+
- A timeout error when using the `aiohttp` transport will now be raised as a `corehttp.exceptions.ServiceResponseTimeoutError`, a subtype of the previously raised `ServiceResponseError`.
|
|
24
|
+
- When using with `aiohttp` 3.10 or later, a connection timeout error will now be raised as a `corehttp.exceptions.ServiceRequestTimeoutError`, which can be retried.
|
|
25
|
+
- Fixed leaked requests and aiohttp exceptions for streamed responses.
|
|
26
|
+
- Improved granularity of `ServiceRequestError` and `ServiceResponseError` exceptions raised in timeout scenarios from the requests and aiohttp transports.
|
|
27
|
+
- `BearerTokenCredentialPolicy` and `AsyncBearerTokenCredentialPolicy` will now properly chain exceptions raised during claims challenge handling. If a credential raises an exception when attempting to acquire a token in response to a claims challenge, that exception will be raised with the original 401 response as the cause.
|
|
28
|
+
|
|
29
|
+
### Other Changes
|
|
30
|
+
|
|
31
|
+
- Added `opentelemetry-api` as an optional dependency for tracing. [#39172](https://github.com/Azure/azure-sdk-for-python/pull/39172)
|
|
32
|
+
|
|
3
33
|
## 1.0.0b6 (2025-03-27)
|
|
4
34
|
|
|
5
35
|
### Features Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: corehttp
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0b7
|
|
4
4
|
Summary: CoreHTTP Library for Python
|
|
5
5
|
Home-page: https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/core/corehttp
|
|
6
6
|
Author: Microsoft Corporation
|
|
@@ -11,13 +11,14 @@ Classifier: Development Status :: 4 - Beta
|
|
|
11
11
|
Classifier: Programming Language :: Python
|
|
12
12
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.9
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
20
|
Classifier: License :: OSI Approved :: MIT License
|
|
20
|
-
Requires-Python: >=3.
|
|
21
|
+
Requires-Python: >=3.9
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
22
23
|
License-File: LICENSE
|
|
23
24
|
Requires-Dist: typing-extensions>=4.6.0
|
|
@@ -27,6 +28,21 @@ Provides-Extra: aiohttp
|
|
|
27
28
|
Requires-Dist: aiohttp>=3.0; extra == "aiohttp"
|
|
28
29
|
Provides-Extra: httpx
|
|
29
30
|
Requires-Dist: httpx>=0.25.0; extra == "httpx"
|
|
31
|
+
Provides-Extra: tracing
|
|
32
|
+
Requires-Dist: opentelemetry-api~=1.26; extra == "tracing"
|
|
33
|
+
Dynamic: author
|
|
34
|
+
Dynamic: author-email
|
|
35
|
+
Dynamic: classifier
|
|
36
|
+
Dynamic: description
|
|
37
|
+
Dynamic: description-content-type
|
|
38
|
+
Dynamic: home-page
|
|
39
|
+
Dynamic: keywords
|
|
40
|
+
Dynamic: license
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
Dynamic: provides-extra
|
|
43
|
+
Dynamic: requires-dist
|
|
44
|
+
Dynamic: requires-python
|
|
45
|
+
Dynamic: summary
|
|
30
46
|
|
|
31
47
|
|
|
32
48
|
# Core HTTP shared client library for Python
|
|
@@ -87,6 +103,36 @@ additional questions or comments.
|
|
|
87
103
|
|
|
88
104
|
# Release History
|
|
89
105
|
|
|
106
|
+
## 1.0.0b7 (2026-02-05)
|
|
107
|
+
|
|
108
|
+
### Features Added
|
|
109
|
+
|
|
110
|
+
- Native tracing support was added. [#39172](https://github.com/Azure/azure-sdk-for-python/pull/39172)
|
|
111
|
+
- The `OpenTelemetryTracer` class was added to the `corehttp.instrumentation.tracing.opentelemetry` module. This is a wrapper around the OpenTelemetry tracer that is used to create spans for SDK operations.
|
|
112
|
+
- Added a `get_tracer` method to the new `corehttp.instrumentation` module. This method returns an instance of the `OpenTelemetryTracer` class if OpenTelemetry is available.
|
|
113
|
+
- A `TracingOptions` TypedDict class was added to define the options that SDK users can use to configure tracing per-operation. These options include the ability to enable or disable tracing and set additional attributes on spans.
|
|
114
|
+
- Example usage: `client.method(tracing_options={"enabled": True, "attributes": {"foo": "bar"}})`
|
|
115
|
+
- `DistributedHttpTracingPolicy` and `distributed_trace`/`distributed_trace_async` decorators were added to support OpenTelemetry tracing for SDK operations.
|
|
116
|
+
- SDK clients can define an `_instrumentation_config` class variable to configure the OpenTelemetry tracer used in method span creation. Possible configuration options are `library_name`, `library_version`, `schema_url`, and `attributes`.
|
|
117
|
+
- Added a global settings object, `corehttp.settings`, to the `corehttp` package. This object can be used to set global settings for the `corehttp` package. Currently the only setting is `tracing_enabled` for enabling/disabling tracing. [#39172](https://github.com/Azure/azure-sdk-for-python/pull/39172)
|
|
118
|
+
- Added `start_time` and `context` keyword arguments to `OpenTelemetryTracer.start_span` and `start_as_current_span` methods.
|
|
119
|
+
- Added `set_span_error_status` static method to `OpenTelemetryTracer` for setting a span's status to ERROR.
|
|
120
|
+
- Added `is_generated_model`, `attribute_list`, and `TypeHandlerRegistry` to `corehttp.serialization` module for SDK model handling.
|
|
121
|
+
|
|
122
|
+
### Bugs Fixed
|
|
123
|
+
|
|
124
|
+
- Fixed `retry_backoff_max` being ignored in retry policies when configuring retries.
|
|
125
|
+
- Raise correct exception if transport is used while already closed.
|
|
126
|
+
- A timeout error when using the `aiohttp` transport will now be raised as a `corehttp.exceptions.ServiceResponseTimeoutError`, a subtype of the previously raised `ServiceResponseError`.
|
|
127
|
+
- When using with `aiohttp` 3.10 or later, a connection timeout error will now be raised as a `corehttp.exceptions.ServiceRequestTimeoutError`, which can be retried.
|
|
128
|
+
- Fixed leaked requests and aiohttp exceptions for streamed responses.
|
|
129
|
+
- Improved granularity of `ServiceRequestError` and `ServiceResponseError` exceptions raised in timeout scenarios from the requests and aiohttp transports.
|
|
130
|
+
- `BearerTokenCredentialPolicy` and `AsyncBearerTokenCredentialPolicy` will now properly chain exceptions raised during claims challenge handling. If a credential raises an exception when attempting to acquire a token in response to a claims challenge, that exception will be raised with the original 401 response as the cause.
|
|
131
|
+
|
|
132
|
+
### Other Changes
|
|
133
|
+
|
|
134
|
+
- Added `opentelemetry-api` as an optional dependency for tracing. [#39172](https://github.com/Azure/azure-sdk-for-python/pull/39172)
|
|
135
|
+
|
|
90
136
|
## 1.0.0b6 (2025-03-27)
|
|
91
137
|
|
|
92
138
|
### Features Added
|
|
@@ -68,7 +68,11 @@ class TokenCredential(Protocol, ContextManager["TokenCredential"]):
|
|
|
68
68
|
...
|
|
69
69
|
|
|
70
70
|
def close(self) -> None:
|
|
71
|
-
|
|
71
|
+
"""Close the credential, releasing any resources it holds.
|
|
72
|
+
|
|
73
|
+
:return: None
|
|
74
|
+
:rtype: None
|
|
75
|
+
"""
|
|
72
76
|
|
|
73
77
|
|
|
74
78
|
class ServiceNamedKey(NamedTuple):
|
|
@@ -93,7 +97,7 @@ class ServiceKeyCredential:
|
|
|
93
97
|
It provides the ability to update the key without creating a new client.
|
|
94
98
|
|
|
95
99
|
:param str key: The key used to authenticate to a service
|
|
96
|
-
:raises:
|
|
100
|
+
:raises TypeError: If the key is not a string.
|
|
97
101
|
"""
|
|
98
102
|
|
|
99
103
|
def __init__(self, key: str) -> None:
|
|
@@ -117,7 +121,8 @@ class ServiceKeyCredential:
|
|
|
117
121
|
to update long-lived clients.
|
|
118
122
|
|
|
119
123
|
:param str key: The key used to authenticate to a service
|
|
120
|
-
:raises
|
|
124
|
+
:raises ValueError: If the key is None or empty.
|
|
125
|
+
:raises TypeError: If the key is not a string.
|
|
121
126
|
"""
|
|
122
127
|
if not key:
|
|
123
128
|
raise ValueError("The key used for updating can not be None or empty")
|
|
@@ -132,7 +137,7 @@ class ServiceNamedKeyCredential:
|
|
|
132
137
|
|
|
133
138
|
:param str name: The name of the credential used to authenticate to a service.
|
|
134
139
|
:param str key: The key used to authenticate to a service.
|
|
135
|
-
:raises:
|
|
140
|
+
:raises TypeError: If the name or key is not a string.
|
|
136
141
|
"""
|
|
137
142
|
|
|
138
143
|
def __init__(self, name: str, key: str) -> None:
|
|
@@ -180,7 +185,11 @@ class AsyncTokenCredential(Protocol, AsyncContextManager["AsyncTokenCredential"]
|
|
|
180
185
|
...
|
|
181
186
|
|
|
182
187
|
async def close(self) -> None:
|
|
183
|
-
|
|
188
|
+
"""Close the credential, releasing any resources.
|
|
189
|
+
|
|
190
|
+
:return: None
|
|
191
|
+
:rtype: None
|
|
192
|
+
"""
|
|
184
193
|
|
|
185
194
|
async def __aexit__(
|
|
186
195
|
self,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# ------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# ------------------------------------
|
|
5
|
+
from ._models import SpanKind, Link, TracingOptions
|
|
6
|
+
from ._decorator import distributed_trace, distributed_trace_async
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"Link",
|
|
10
|
+
"SpanKind",
|
|
11
|
+
"TracingOptions",
|
|
12
|
+
"distributed_trace",
|
|
13
|
+
"distributed_trace_async",
|
|
14
|
+
]
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# ------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# ------------------------------------
|
|
5
|
+
"""The decorator to apply if you want the given method traced."""
|
|
6
|
+
from contextvars import ContextVar
|
|
7
|
+
import functools
|
|
8
|
+
from typing import Awaitable, Any, TypeVar, overload, Optional, Callable, TYPE_CHECKING
|
|
9
|
+
from typing_extensions import ParamSpec
|
|
10
|
+
|
|
11
|
+
from ._models import SpanKind
|
|
12
|
+
from ._tracer import get_tracer
|
|
13
|
+
from ...settings import settings
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from ._models import TracingOptions
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
P = ParamSpec("P")
|
|
20
|
+
T = TypeVar("T")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
# This context variable is used to determine if we are already in the span context of a decorated function.
|
|
24
|
+
_in_span_context = ContextVar("in_span_context", default=False)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@overload
|
|
28
|
+
def distributed_trace(__func: Callable[P, T]) -> Callable[P, T]:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@overload
|
|
33
|
+
def distributed_trace(**kwargs: Any) -> Callable[[Callable[P, T]], Callable[P, T]]:
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def distributed_trace(__func: Optional[Callable[P, T]] = None, **kwargs: Any) -> Any: # pylint: disable=unused-argument
|
|
38
|
+
"""Decorator to apply to an SDK method to have it traced automatically.
|
|
39
|
+
|
|
40
|
+
Span will use the method's qualified name.
|
|
41
|
+
|
|
42
|
+
Note: This decorator SHOULD NOT be used by application developers. It's intended to be called by client
|
|
43
|
+
libraries only. Application developers should use OpenTelemetry directly to instrument their applications.
|
|
44
|
+
|
|
45
|
+
:param callable __func: A function to decorate
|
|
46
|
+
|
|
47
|
+
:return: The decorated function
|
|
48
|
+
:rtype: Any
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def decorator(func: Callable[P, T]) -> Callable[P, T]:
|
|
52
|
+
|
|
53
|
+
@functools.wraps(func)
|
|
54
|
+
def wrapper_use_tracer(*args: Any, **kwargs: Any) -> T:
|
|
55
|
+
# If we are already in the span context of a decorated function, don't trace.
|
|
56
|
+
if _in_span_context.get():
|
|
57
|
+
return func(*args, **kwargs)
|
|
58
|
+
|
|
59
|
+
# This will be popped in the pipeline or transport runner.
|
|
60
|
+
tracing_options: TracingOptions = kwargs.get("tracing_options", {})
|
|
61
|
+
|
|
62
|
+
# User can explicitly disable tracing for this call
|
|
63
|
+
user_enabled = tracing_options.get("enabled")
|
|
64
|
+
if user_enabled is False:
|
|
65
|
+
return func(*args, **kwargs)
|
|
66
|
+
|
|
67
|
+
# If tracing is disabled globally and user didn't explicitly enable it, don't trace.
|
|
68
|
+
if not settings.tracing_enabled and user_enabled is None:
|
|
69
|
+
return func(*args, **kwargs)
|
|
70
|
+
|
|
71
|
+
config = {}
|
|
72
|
+
if args and hasattr(args[0], "_instrumentation_config"):
|
|
73
|
+
config = args[0]._instrumentation_config # pylint: disable=protected-access
|
|
74
|
+
|
|
75
|
+
method_tracer = get_tracer(
|
|
76
|
+
library_name=config.get("library_name"),
|
|
77
|
+
library_version=config.get("library_version"),
|
|
78
|
+
schema_url=config.get("schema_url"),
|
|
79
|
+
attributes=config.get("attributes"),
|
|
80
|
+
)
|
|
81
|
+
if not method_tracer:
|
|
82
|
+
return func(*args, **kwargs)
|
|
83
|
+
|
|
84
|
+
name = func.__qualname__
|
|
85
|
+
span_suppression_token = _in_span_context.set(True)
|
|
86
|
+
try:
|
|
87
|
+
with method_tracer.start_as_current_span(
|
|
88
|
+
name=name,
|
|
89
|
+
kind=SpanKind.INTERNAL,
|
|
90
|
+
attributes=tracing_options.get("attributes"),
|
|
91
|
+
) as span:
|
|
92
|
+
try:
|
|
93
|
+
return func(*args, **kwargs)
|
|
94
|
+
except Exception as err: # pylint: disable=broad-except
|
|
95
|
+
ex_type = type(err)
|
|
96
|
+
module = ex_type.__module__ if ex_type.__module__ != "builtins" else ""
|
|
97
|
+
error_type = f"{module}.{ex_type.__qualname__}" if module else ex_type.__qualname__
|
|
98
|
+
span.set_attribute("error.type", error_type)
|
|
99
|
+
raise
|
|
100
|
+
finally:
|
|
101
|
+
_in_span_context.reset(span_suppression_token)
|
|
102
|
+
|
|
103
|
+
return wrapper_use_tracer
|
|
104
|
+
|
|
105
|
+
return decorator if __func is None else decorator(__func)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@overload
|
|
109
|
+
def distributed_trace_async(__func: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]]:
|
|
110
|
+
pass
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@overload
|
|
114
|
+
def distributed_trace_async(**kwargs: Any) -> Callable[[Callable[P, Awaitable[T]]], Callable[P, Awaitable[T]]]:
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def distributed_trace_async( # pylint: disable=unused-argument
|
|
119
|
+
__func: Optional[Callable[P, Awaitable[T]]] = None,
|
|
120
|
+
**kwargs: Any,
|
|
121
|
+
) -> Any:
|
|
122
|
+
"""Decorator to apply to an SDK method to have it traced automatically.
|
|
123
|
+
|
|
124
|
+
Span will use the method's qualified name.
|
|
125
|
+
|
|
126
|
+
Note: This decorator SHOULD NOT be used by application developers. It's intended to be called by client
|
|
127
|
+
libraries only. Application developers should use OpenTelemetry directly to instrument their applications.
|
|
128
|
+
|
|
129
|
+
:param callable __func: A function to decorate
|
|
130
|
+
|
|
131
|
+
:return: The decorated function
|
|
132
|
+
:rtype: Any
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
def decorator(func: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]]:
|
|
136
|
+
|
|
137
|
+
@functools.wraps(func)
|
|
138
|
+
async def wrapper_use_tracer(*args: Any, **kwargs: Any) -> T:
|
|
139
|
+
# If we are already in the span context of a decorated function, don't trace.
|
|
140
|
+
if _in_span_context.get():
|
|
141
|
+
return await func(*args, **kwargs)
|
|
142
|
+
|
|
143
|
+
# This will be popped in the pipeline or transport runner.
|
|
144
|
+
tracing_options: TracingOptions = kwargs.get("tracing_options", {})
|
|
145
|
+
|
|
146
|
+
# User can explicitly disable tracing for this call
|
|
147
|
+
user_enabled = tracing_options.get("enabled")
|
|
148
|
+
if user_enabled is False:
|
|
149
|
+
return await func(*args, **kwargs)
|
|
150
|
+
|
|
151
|
+
# If tracing is disabled globally and user didn't explicitly enable it, don't trace.
|
|
152
|
+
if not settings.tracing_enabled and user_enabled is None:
|
|
153
|
+
return await func(*args, **kwargs)
|
|
154
|
+
|
|
155
|
+
config = {}
|
|
156
|
+
if args and hasattr(args[0], "_instrumentation_config"):
|
|
157
|
+
config = args[0]._instrumentation_config # pylint: disable=protected-access
|
|
158
|
+
|
|
159
|
+
method_tracer = get_tracer(
|
|
160
|
+
library_name=config.get("library_name"),
|
|
161
|
+
library_version=config.get("library_version"),
|
|
162
|
+
schema_url=config.get("schema_url"),
|
|
163
|
+
attributes=config.get("attributes"),
|
|
164
|
+
)
|
|
165
|
+
if not method_tracer:
|
|
166
|
+
return await func(*args, **kwargs)
|
|
167
|
+
|
|
168
|
+
name = func.__qualname__
|
|
169
|
+
span_suppression_token = _in_span_context.set(True)
|
|
170
|
+
try:
|
|
171
|
+
with method_tracer.start_as_current_span(
|
|
172
|
+
name=name,
|
|
173
|
+
kind=SpanKind.INTERNAL,
|
|
174
|
+
attributes=tracing_options.get("attributes"),
|
|
175
|
+
) as span:
|
|
176
|
+
try:
|
|
177
|
+
return await func(*args, **kwargs)
|
|
178
|
+
except Exception as err: # pylint: disable=broad-except
|
|
179
|
+
ex_type = type(err)
|
|
180
|
+
module = ex_type.__module__ if ex_type.__module__ != "builtins" else ""
|
|
181
|
+
error_type = f"{module}.{ex_type.__qualname__}" if module else ex_type.__qualname__
|
|
182
|
+
span.set_attribute("error.type", error_type)
|
|
183
|
+
raise
|
|
184
|
+
finally:
|
|
185
|
+
_in_span_context.reset(span_suppression_token)
|
|
186
|
+
|
|
187
|
+
return wrapper_use_tracer
|
|
188
|
+
|
|
189
|
+
return decorator if __func is None else decorator(__func)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# ------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# ------------------------------------
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Dict, Mapping, Optional, Union, Sequence, TypedDict
|
|
8
|
+
|
|
9
|
+
from ...utils import CaseInsensitiveEnumMeta
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
AttributeValue = Union[
|
|
13
|
+
str,
|
|
14
|
+
bool,
|
|
15
|
+
int,
|
|
16
|
+
float,
|
|
17
|
+
Sequence[str],
|
|
18
|
+
Sequence[bool],
|
|
19
|
+
Sequence[int],
|
|
20
|
+
Sequence[float],
|
|
21
|
+
]
|
|
22
|
+
Attributes = Mapping[str, AttributeValue]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SpanKind(Enum, metaclass=CaseInsensitiveEnumMeta):
|
|
26
|
+
"""Describes the role or kind of a span within a distributed trace.
|
|
27
|
+
|
|
28
|
+
This helps to categorize spans based on their relationship to other spans and the type
|
|
29
|
+
of operation they represent.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
UNSPECIFIED = 1
|
|
33
|
+
"""Unspecified span kind."""
|
|
34
|
+
|
|
35
|
+
SERVER = 2
|
|
36
|
+
"""Indicates that the span describes an operation that handles a remote request."""
|
|
37
|
+
|
|
38
|
+
CLIENT = 3
|
|
39
|
+
"""Indicates that the span describes a request to some remote service."""
|
|
40
|
+
|
|
41
|
+
PRODUCER = 4
|
|
42
|
+
"""Indicates that the span describes the initiation or scheduling of a local or remote operation."""
|
|
43
|
+
|
|
44
|
+
CONSUMER = 5
|
|
45
|
+
"""Indicates that the span represents the processing of an operation initiated by a producer."""
|
|
46
|
+
|
|
47
|
+
INTERNAL = 6
|
|
48
|
+
"""Indicates that the span is used internally in the application."""
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class Link:
|
|
52
|
+
"""Represents a reference from one span to another span.
|
|
53
|
+
|
|
54
|
+
:param headers: A dictionary of the request header as key value pairs.
|
|
55
|
+
:type headers: dict
|
|
56
|
+
:param attributes: Any additional attributes that should be added to link
|
|
57
|
+
:type attributes: dict
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, headers: Dict[str, str], attributes: Optional[Attributes] = None) -> None:
|
|
61
|
+
self.headers = headers
|
|
62
|
+
self.attributes = attributes
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class TracingOptions(TypedDict, total=False):
|
|
66
|
+
"""Options to configure tracing behavior for operations."""
|
|
67
|
+
|
|
68
|
+
enabled: bool
|
|
69
|
+
"""Whether tracing is enabled for the operation. By default, if the global setting is enabled, tracing is
|
|
70
|
+
enabled for all operations. This option can be used to override the global setting for a specific operation."""
|
|
71
|
+
attributes: Attributes
|
|
72
|
+
"""Attributes to include in the spans emitted for the operation."""
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# ------------------------------------
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT License.
|
|
4
|
+
# ------------------------------------
|
|
5
|
+
from typing import Optional, Union, Mapping, TYPE_CHECKING
|
|
6
|
+
from functools import lru_cache
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
try:
|
|
10
|
+
from .opentelemetry import OpenTelemetryTracer
|
|
11
|
+
except ImportError:
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_tracer_impl():
|
|
16
|
+
# Check if OpenTelemetry is available/installed.
|
|
17
|
+
try:
|
|
18
|
+
from .opentelemetry import OpenTelemetryTracer
|
|
19
|
+
|
|
20
|
+
return OpenTelemetryTracer
|
|
21
|
+
except ImportError:
|
|
22
|
+
return None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@lru_cache
|
|
26
|
+
def _get_tracer_cached(
|
|
27
|
+
library_name: Optional[str],
|
|
28
|
+
library_version: Optional[str],
|
|
29
|
+
schema_url: Optional[str],
|
|
30
|
+
attributes_key: Optional[frozenset],
|
|
31
|
+
) -> Optional["OpenTelemetryTracer"]:
|
|
32
|
+
tracer_impl = _get_tracer_impl()
|
|
33
|
+
if tracer_impl:
|
|
34
|
+
# Convert attributes_key back to dict if needed
|
|
35
|
+
attributes = dict(attributes_key) if attributes_key else None
|
|
36
|
+
return tracer_impl(
|
|
37
|
+
library_name=library_name,
|
|
38
|
+
library_version=library_version,
|
|
39
|
+
schema_url=schema_url,
|
|
40
|
+
attributes=attributes,
|
|
41
|
+
)
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_tracer(
|
|
46
|
+
*,
|
|
47
|
+
library_name: Optional[str] = None,
|
|
48
|
+
library_version: Optional[str] = None,
|
|
49
|
+
schema_url: Optional[str] = None,
|
|
50
|
+
attributes: Optional[Mapping[str, Union[str, bool, int, float]]] = None,
|
|
51
|
+
) -> Optional["OpenTelemetryTracer"]:
|
|
52
|
+
"""Get the OpenTelemetry tracer instance if available.
|
|
53
|
+
|
|
54
|
+
If OpenTelemetry is not available, this method will return None. This method caches
|
|
55
|
+
the tracer instance for each unique set of parameters.
|
|
56
|
+
|
|
57
|
+
:keyword library_name: The name of the library to use in the tracer.
|
|
58
|
+
:paramtype library_name: str
|
|
59
|
+
:keyword library_version: The version of the library to use in the tracer.
|
|
60
|
+
:paramtype library_version: str
|
|
61
|
+
:keyword schema_url: Specifies the Schema URL of the emitted spans.
|
|
62
|
+
:paramtype schema_url: str
|
|
63
|
+
:keyword attributes: Attributes to add to the emitted spans.
|
|
64
|
+
:paramtype attributes: Mapping[str, Union[str, bool, int, float]]
|
|
65
|
+
:return: The OpenTelemetry tracer instance if available.
|
|
66
|
+
:rtype: Optional[~corehttp.instrumentation.tracing.opentelemetry.OpenTelemetryTracer]
|
|
67
|
+
"""
|
|
68
|
+
attributes_key = frozenset(attributes.items()) if attributes else None
|
|
69
|
+
return _get_tracer_cached(library_name, library_version, schema_url, attributes_key)
|