Skip to content

Commit 172e4cf

Browse files
committed
Add type hints to HTTPX
1 parent 490580d commit 172e4cf

File tree

2 files changed

+59
-62
lines changed
  • instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation

2 files changed

+59
-62
lines changed

instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py

Lines changed: 59 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ async def async_response_hook(span, request, response):
192192
---
193193
"""
194194

195+
from __future__ import annotations
196+
195197
import logging
196198
import typing
197199
from asyncio import iscoroutinefunction
@@ -228,7 +230,7 @@ async def async_response_hook(span, request, response):
228230
NETWORK_PEER_ADDRESS,
229231
NETWORK_PEER_PORT,
230232
)
231-
from opentelemetry.trace import SpanKind, TracerProvider, get_tracer
233+
from opentelemetry.trace import SpanKind, Tracer, TracerProvider, get_tracer
232234
from opentelemetry.trace.span import Span
233235
from opentelemetry.trace.status import StatusCode
234236
from opentelemetry.util.http import remove_url_credentials, sanitize_method
@@ -250,18 +252,16 @@ async def async_response_hook(span, request, response):
250252
class RequestInfo(typing.NamedTuple):
251253
method: bytes
252254
url: URL
253-
headers: typing.Optional[Headers]
254-
stream: typing.Optional[
255-
typing.Union[httpx.SyncByteStream, httpx.AsyncByteStream]
256-
]
257-
extensions: typing.Optional[dict]
255+
headers: Headers | None
256+
stream: httpx.SyncByteStream | httpx.AsyncByteStream | None
257+
extensions: dict[str, typing.Any] | None
258258

259259

260260
class ResponseInfo(typing.NamedTuple):
261261
status_code: int
262-
headers: typing.Optional[Headers]
262+
headers: Headers | None
263263
stream: typing.Iterable[bytes]
264-
extensions: typing.Optional[dict]
264+
extensions: dict[str, typing.Any] | None
265265

266266

267267
def _get_default_span_name(method: str) -> str:
@@ -272,11 +272,13 @@ def _get_default_span_name(method: str) -> str:
272272
return method
273273

274274

275-
def _prepare_headers(headers: typing.Optional[Headers]) -> httpx.Headers:
275+
def _prepare_headers(headers: Headers | None) -> httpx.Headers:
276276
return httpx.Headers(headers)
277277

278278

279-
def _extract_parameters(args, kwargs):
279+
def _extract_parameters(
280+
args: tuple[typing.Any, ...], kwargs: dict[str, typing.Any]
281+
):
280282
if isinstance(args[0], httpx.Request):
281283
# In httpx >= 0.20.0, handle_request receives a Request object
282284
request: httpx.Request = args[0]
@@ -309,10 +311,9 @@ def _inject_propagation_headers(headers, args, kwargs):
309311

310312

311313
def _extract_response(
312-
response: typing.Union[
313-
httpx.Response, typing.Tuple[int, Headers, httpx.SyncByteStream, dict]
314-
],
315-
) -> typing.Tuple[int, Headers, httpx.SyncByteStream, dict, str]:
314+
response: httpx.Response
315+
| tuple[int, Headers, httpx.SyncByteStream, dict[str, typing.Any]],
316+
) -> tuple[int, Headers, httpx.SyncByteStream, dict[str, typing.Any], str]:
316317
if isinstance(response, httpx.Response):
317318
status_code = response.status_code
318319
headers = response.headers
@@ -329,7 +330,7 @@ def _extract_response(
329330

330331

331332
def _apply_request_client_attributes_to_span(
332-
span_attributes: dict,
333+
span_attributes: dict[str, typing.Any],
333334
url: typing.Union[str, URL, httpx.URL],
334335
method_original: str,
335336
semconv: _HTTPStabilityMode,
@@ -405,9 +406,9 @@ class SyncOpenTelemetryTransport(httpx.BaseTransport):
405406
def __init__(
406407
self,
407408
transport: httpx.BaseTransport,
408-
tracer_provider: typing.Optional[TracerProvider] = None,
409-
request_hook: typing.Optional[RequestHook] = None,
410-
response_hook: typing.Optional[ResponseHook] = None,
409+
tracer_provider: TracerProvider | None = None,
410+
request_hook: RequestHook | None = None,
411+
response_hook: ResponseHook | None = None,
411412
):
412413
_OpenTelemetrySemanticConventionStability._initialize()
413414
self._sem_conv_opt_in_mode = _OpenTelemetrySemanticConventionStability._get_opentelemetry_stability_opt_in_mode(
@@ -424,27 +425,27 @@ def __init__(
424425
self._request_hook = request_hook
425426
self._response_hook = response_hook
426427

427-
def __enter__(self) -> "SyncOpenTelemetryTransport":
428+
def __enter__(self) -> SyncOpenTelemetryTransport:
428429
self._transport.__enter__()
429430
return self
430431

431432
def __exit__(
432433
self,
433-
exc_type: typing.Optional[typing.Type[BaseException]] = None,
434-
exc_value: typing.Optional[BaseException] = None,
435-
traceback: typing.Optional[TracebackType] = None,
434+
exc_type: type[BaseException] | None = None,
435+
exc_value: BaseException | None = None,
436+
traceback: TracebackType | None = None,
436437
) -> None:
437438
self._transport.__exit__(exc_type, exc_value, traceback)
438439

439440
# pylint: disable=R0914
440441
def handle_request(
441442
self,
442-
*args,
443-
**kwargs,
444-
) -> typing.Union[
445-
typing.Tuple[int, "Headers", httpx.SyncByteStream, dict],
446-
httpx.Response,
447-
]:
443+
*args: typing.Any,
444+
**kwargs: typing.Any,
445+
) -> (
446+
tuple[int, Headers, httpx.SyncByteStream, dict[str, typing.Any]]
447+
| httpx.Response
448+
):
448449
"""Add request info to span."""
449450
if not is_http_instrumentation_enabled():
450451
return self._transport.handle_request(*args, **kwargs)
@@ -563,11 +564,13 @@ async def __aexit__(
563564

564565
# pylint: disable=R0914
565566
async def handle_async_request(
566-
self, *args, **kwargs
567-
) -> typing.Union[
568-
typing.Tuple[int, "Headers", httpx.AsyncByteStream, dict],
569-
httpx.Response,
570-
]:
567+
self, *args: typing.Any, **kwargs: typing.Any
568+
) -> (
569+
typing.Tuple[
570+
int, Headers, httpx.AsyncByteStream, dict[str, typing.Any]
571+
]
572+
| httpx.Response
573+
):
571574
"""Add request info to span."""
572575
if not is_http_instrumentation_enabled():
573576
return await self._transport.handle_async_request(*args, **kwargs)
@@ -651,7 +654,7 @@ class HTTPXClientInstrumentor(BaseInstrumentor):
651654
def instrumentation_dependencies(self) -> typing.Collection[str]:
652655
return _instruments
653656

654-
def _instrument(self, **kwargs):
657+
def _instrument(self, **kwargs: typing.Any):
655658
"""Instruments httpx Client and AsyncClient
656659
657660
Args:
@@ -714,20 +717,20 @@ def _instrument(self, **kwargs):
714717
),
715718
)
716719

717-
def _uninstrument(self, **kwargs):
720+
def _uninstrument(self, **kwargs: typing.Any):
718721
unwrap(httpx.HTTPTransport, "handle_request")
719722
unwrap(httpx.AsyncHTTPTransport, "handle_async_request")
720723

721724
@staticmethod
722725
def _handle_request_wrapper( # pylint: disable=too-many-locals
723-
wrapped,
724-
instance,
725-
args,
726-
kwargs,
727-
tracer,
728-
sem_conv_opt_in_mode,
729-
request_hook,
730-
response_hook,
726+
wrapped: typing.Callable[..., typing.Any],
727+
instance: httpx.HTTPTransport,
728+
args: tuple[typing.Any, ...],
729+
kwargs: dict[str, typing.Any],
730+
tracer: Tracer,
731+
sem_conv_opt_in_mode: _HTTPStabilityMode,
732+
request_hook: RequestHook,
733+
response_hook: ResponseHook,
731734
):
732735
if not is_http_instrumentation_enabled():
733736
return wrapped(*args, **kwargs)
@@ -794,14 +797,14 @@ def _handle_request_wrapper( # pylint: disable=too-many-locals
794797

795798
@staticmethod
796799
async def _handle_async_request_wrapper( # pylint: disable=too-many-locals
797-
wrapped,
798-
instance,
799-
args,
800-
kwargs,
801-
tracer,
802-
sem_conv_opt_in_mode,
803-
async_request_hook,
804-
async_response_hook,
800+
wrapped: typing.Callable[..., typing.Awaitable[typing.Any]],
801+
instance: httpx.AsyncHTTPTransport,
802+
args: tuple[typing.Any, ...],
803+
kwargs: dict[str, typing.Any],
804+
tracer: Tracer,
805+
sem_conv_opt_in_mode: _HTTPStabilityMode,
806+
async_request_hook: AsyncRequestHook,
807+
async_response_hook: AsyncResponseHook,
805808
):
806809
if not is_http_instrumentation_enabled():
807810
return await wrapped(*args, **kwargs)
@@ -870,14 +873,10 @@ async def _handle_async_request_wrapper( # pylint: disable=too-many-locals
870873
@classmethod
871874
def instrument_client(
872875
cls,
873-
client: typing.Union[httpx.Client, httpx.AsyncClient],
874-
tracer_provider: TracerProvider = None,
875-
request_hook: typing.Union[
876-
typing.Optional[RequestHook], typing.Optional[AsyncRequestHook]
877-
] = None,
878-
response_hook: typing.Union[
879-
typing.Optional[ResponseHook], typing.Optional[AsyncResponseHook]
880-
] = None,
876+
client: httpx.Client | httpx.AsyncClient,
877+
tracer_provider: TracerProvider | None = None,
878+
request_hook: RequestHook | AsyncRequestHook | None = None,
879+
response_hook: ResponseHook | AsyncResponseHook | None = None,
881880
) -> None:
882881
"""Instrument httpx Client or AsyncClient
883882
@@ -975,9 +974,7 @@ def instrument_client(
975974
client._is_instrumented_by_opentelemetry = True
976975

977976
@staticmethod
978-
def uninstrument_client(
979-
client: typing.Union[httpx.Client, httpx.AsyncClient],
980-
):
977+
def uninstrument_client(client: httpx.Client | httpx.AsyncClient) -> None:
981978
"""Disables instrumentation for the given client instance
982979
983980
Args:

instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/py.typed

Whitespace-only changes.

0 commit comments

Comments
 (0)