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.
Files changed (143) hide show
  1. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/CHANGELOG.md +30 -0
  2. {corehttp-1.0.0b6/corehttp.egg-info → corehttp-1.0.0b7}/PKG-INFO +50 -4
  3. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/_version.py +1 -1
  4. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/credentials.py +14 -5
  5. corehttp-1.0.0b7/corehttp/instrumentation/__init__.py +9 -0
  6. corehttp-1.0.0b7/corehttp/instrumentation/tracing/__init__.py +14 -0
  7. corehttp-1.0.0b7/corehttp/instrumentation/tracing/_decorator.py +189 -0
  8. corehttp-1.0.0b7/corehttp/instrumentation/tracing/_models.py +72 -0
  9. corehttp-1.0.0b7/corehttp/instrumentation/tracing/_tracer.py +69 -0
  10. corehttp-1.0.0b7/corehttp/instrumentation/tracing/opentelemetry.py +277 -0
  11. corehttp-1.0.0b7/corehttp/instrumentation/tracing/utils.py +31 -0
  12. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/paging.py +13 -0
  13. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_aiohttp.py +17 -5
  14. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_http_response_impl.py +7 -7
  15. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_http_response_impl_async.py +2 -0
  16. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_httpx.py +8 -8
  17. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_requests_basic.py +13 -5
  18. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_rest_py3.py +2 -2
  19. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/__init__.py +2 -2
  20. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/_base.py +2 -1
  21. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/_base_async.py +2 -0
  22. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/_tools.py +18 -2
  23. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/__init__.py +2 -0
  24. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_authentication.py +28 -5
  25. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_authentication_async.py +22 -3
  26. corehttp-1.0.0b7/corehttp/runtime/policies/_distributed_tracing.py +169 -0
  27. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_retry.py +7 -11
  28. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_retry_async.py +4 -8
  29. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_universal.py +11 -0
  30. corehttp-1.0.0b7/corehttp/serialization.py +358 -0
  31. corehttp-1.0.0b7/corehttp/settings.py +59 -0
  32. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/_base.py +1 -3
  33. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/_base_async.py +1 -3
  34. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/aiohttp/_aiohttp.py +39 -14
  35. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/requests/_requests_basic.py +31 -16
  36. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/utils/_utils.py +2 -1
  37. {corehttp-1.0.0b6 → corehttp-1.0.0b7/corehttp.egg-info}/PKG-INFO +50 -4
  38. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/SOURCES.txt +18 -0
  39. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/requires.txt +3 -0
  40. corehttp-1.0.0b7/samples/sample_tracing.py +97 -0
  41. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/setup.py +6 -2
  42. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_authentication_async.py +60 -3
  43. corehttp-1.0.0b7/tests/async_tests/test_tracing_decorator_async.py +131 -0
  44. corehttp-1.0.0b7/tests/async_tests/test_tracing_policy_async.py +68 -0
  45. corehttp-1.0.0b7/tests/async_tests/test_transport_async.py +121 -0
  46. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/conftest.py +29 -0
  47. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_authentication.py +59 -3
  48. corehttp-1.0.0b7/tests/test_settings.py +43 -0
  49. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_stream_generator.py +3 -2
  50. corehttp-1.0.0b7/tests/test_tracer_otel.py +423 -0
  51. corehttp-1.0.0b7/tests/test_tracing_decorator.py +122 -0
  52. corehttp-1.0.0b7/tests/test_tracing_policy.py +270 -0
  53. corehttp-1.0.0b7/tests/test_transport.py +95 -0
  54. corehttp-1.0.0b6/corehttp/serialization.py +0 -124
  55. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/LICENSE +0 -0
  56. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/MANIFEST.in +0 -0
  57. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/README.md +0 -0
  58. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/__init__.py +0 -0
  59. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/_match_conditions.py +0 -0
  60. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/exceptions.py +0 -0
  61. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/py.typed +0 -0
  62. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/__init__.py +0 -0
  63. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/rest/_helpers.py +0 -0
  64. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/__init__.py +0 -0
  65. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/_base.py +0 -0
  66. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/_pipeline_client.py +0 -0
  67. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/_pipeline_client_async.py +0 -0
  68. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/pipeline/_tools_async.py +0 -0
  69. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_base.py +0 -0
  70. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_base_async.py +0 -0
  71. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/runtime/policies/_utils.py +0 -0
  72. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/__init__.py +0 -0
  73. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/aiohttp/__init__.py +0 -0
  74. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/httpx/__init__.py +0 -0
  75. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/httpx/_httpx.py +0 -0
  76. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/requests/__init__.py +0 -0
  77. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/transport/requests/_bigger_block_size_http_adapters.py +0 -0
  78. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/utils/__init__.py +0 -0
  79. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp/utils/_enum_meta.py +0 -0
  80. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/dependency_links.txt +0 -0
  81. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/not-zip-safe +0 -0
  82. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/corehttp.egg-info/top_level.txt +0 -0
  83. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/pyproject.toml +0 -0
  84. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/samples/sample_async_pipeline_client.py +0 -0
  85. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/samples/sample_pipeline_client.py +0 -0
  86. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/setup.cfg +0 -0
  87. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/conftest.py +0 -0
  88. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/rest_client_async.py +0 -0
  89. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_content_length_checking_async.py +0 -0
  90. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_paging_async.py +0 -0
  91. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_pipeline_async.py +0 -0
  92. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_context_manager_async.py +0 -0
  93. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_headers_async.py +0 -0
  94. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_http_request_async.py +0 -0
  95. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_http_response_async.py +0 -0
  96. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_rest_stream_responses_async.py +0 -0
  97. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_retry_policy_async.py +0 -0
  98. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_streaming_async.py +0 -0
  99. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_testserver_async.py +0 -0
  100. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/async_tests/test_universal_http_async.py +0 -0
  101. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/__init__.py +0 -0
  102. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/_test_base.py +0 -0
  103. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/custom_iterator.py +0 -0
  104. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/download_binary.py +0 -0
  105. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/list_entities_json.py +0 -0
  106. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/query_entities_json.py +0 -0
  107. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/update_entity_json.py +0 -0
  108. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/perf_tests/upload_binary.py +0 -0
  109. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/rest_client.py +0 -0
  110. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_content_length_checking.py +0 -0
  111. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_enums.py +0 -0
  112. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_error_map.py +0 -0
  113. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_exceptions.py +0 -0
  114. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_paging.py +0 -0
  115. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_pipeline.py +0 -0
  116. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_requests_universal.py +0 -0
  117. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_context_manager.py +0 -0
  118. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_headers.py +0 -0
  119. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_http_request.py +0 -0
  120. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_http_response.py +0 -0
  121. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_query.py +0 -0
  122. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_rest_stream_responses.py +0 -0
  123. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_retry_policy.py +0 -0
  124. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_serialization.py +0 -0
  125. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_streaming.py +0 -0
  126. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_testserver.py +0 -0
  127. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_universal_pipeline.py +0 -0
  128. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_user_agent_policy.py +0 -0
  129. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/test_utils.py +0 -0
  130. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/__init__.py +0 -0
  131. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/__init__.py +0 -0
  132. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/basic.py +0 -0
  133. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/encoding.py +0 -0
  134. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/errors.py +0 -0
  135. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/headers.py +0 -0
  136. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/helpers.py +0 -0
  137. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/multipart.py +0 -0
  138. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/streams.py +0 -0
  139. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/structures.py +0 -0
  140. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/urlencoded.py +0 -0
  141. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/coretestserver/test_routes/xml_route.py +0 -0
  142. {corehttp-1.0.0b6 → corehttp-1.0.0b7}/tests/testserver_tests/coretestserver/setup.py +0 -0
  143. {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
1
+ Metadata-Version: 2.4
2
2
  Name: corehttp
3
- Version: 1.0.0b6
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.8
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
@@ -9,4 +9,4 @@
9
9
  # regenerated.
10
10
  # --------------------------------------------------------------------------
11
11
 
12
- VERSION = "1.0.0b6"
12
+ VERSION = "1.0.0b7"
@@ -68,7 +68,11 @@ class TokenCredential(Protocol, ContextManager["TokenCredential"]):
68
68
  ...
69
69
 
70
70
  def close(self) -> None:
71
- pass
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: TypeError
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: ValueError or TypeError
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: TypeError
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
- pass
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,9 @@
1
+ # ------------------------------------
2
+ # Copyright (c) Microsoft Corporation.
3
+ # Licensed under the MIT License.
4
+ # ------------------------------------
5
+ from .tracing._tracer import get_tracer
6
+
7
+ __all__ = [
8
+ "get_tracer",
9
+ ]
@@ -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)