Skip to content

Commit 9af3136

Browse files
authored
Support PEP 561 to opentelemetry-util-http (#3127)
1 parent cf6d45e commit 9af3136

File tree

4 files changed

+37
-21
lines changed

4 files changed

+37
-21
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2727
([#3148](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3148))
2828
- add support to Python 3.13
2929
([#3134](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3134))
30+
- `opentelemetry-util-http` Add `py.typed` file to enable PEP 561
31+
([#3127](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3127))
3032

3133
### Fixed
3234

util/opentelemetry-util-http/src/opentelemetry/util/http/__init__.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from re import IGNORECASE as RE_IGNORECASE
2020
from re import compile as re_compile
2121
from re import search
22-
from typing import Callable, Iterable, Optional
22+
from typing import Callable, Iterable
2323
from urllib.parse import urlparse, urlunparse
2424

2525
from opentelemetry.semconv.trace import SpanAttributes
@@ -121,18 +121,16 @@ def sanitize_header_values(
121121
_root = r"OTEL_PYTHON_{}"
122122

123123

124-
def get_traced_request_attrs(instrumentation):
124+
def get_traced_request_attrs(instrumentation: str) -> list[str]:
125125
traced_request_attrs = environ.get(
126-
_root.format(f"{instrumentation}_TRACED_REQUEST_ATTRS"), []
126+
_root.format(f"{instrumentation}_TRACED_REQUEST_ATTRS")
127127
)
128-
129128
if traced_request_attrs:
130-
traced_request_attrs = [
129+
return [
131130
traced_request_attr.strip()
132131
for traced_request_attr in traced_request_attrs.split(",")
133132
]
134-
135-
return traced_request_attrs
133+
return []
136134

137135

138136
def get_excluded_urls(instrumentation: str) -> ExcludeList:
@@ -193,7 +191,7 @@ def normalise_response_header_name(header: str) -> str:
193191
return f"http.response.header.{key}"
194192

195193

196-
def sanitize_method(method: Optional[str]) -> Optional[str]:
194+
def sanitize_method(method: str | None) -> str | None:
197195
if method is None:
198196
return None
199197
method = method.upper()

util/opentelemetry-util-http/src/opentelemetry/util/http/httplib.py

+29-13
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
not create spans on its own.
1818
"""
1919

20+
from __future__ import annotations
21+
2022
import contextlib
2123
import http.client
2224
import logging
2325
import socket # pylint:disable=unused-import # Used for typing
2426
import typing
25-
from typing import Collection
27+
from typing import Any, Callable, Collection, TypedDict, cast
2628

2729
import wrapt
2830

@@ -36,20 +38,22 @@
3638

3739
logger = logging.getLogger(__name__)
3840

41+
R = typing.TypeVar("R")
42+
3943

4044
class HttpClientInstrumentor(BaseInstrumentor):
4145
def instrumentation_dependencies(self) -> Collection[str]:
4246
return () # This instruments http.client from stdlib; no extra deps.
4347

44-
def _instrument(self, **kwargs):
48+
def _instrument(self, **kwargs: Any):
4549
"""Instruments the http.client module (not creating spans on its own)"""
4650
_instrument()
4751

48-
def _uninstrument(self, **kwargs):
52+
def _uninstrument(self, **kwargs: Any):
4953
_uninstrument()
5054

5155

52-
def _remove_nonrecording(spanlist: typing.List[Span]):
56+
def _remove_nonrecording(spanlist: list[Span]) -> bool:
5357
idx = len(spanlist) - 1
5458
while idx >= 0:
5559
if not spanlist[idx].is_recording():
@@ -67,7 +71,9 @@ def _remove_nonrecording(spanlist: typing.List[Span]):
6771
return True
6872

6973

70-
def trysetip(conn: http.client.HTTPConnection, loglevel=logging.DEBUG) -> bool:
74+
def trysetip(
75+
conn: http.client.HTTPConnection, loglevel: int = logging.DEBUG
76+
) -> bool:
7177
"""Tries to set the net.peer.ip semantic attribute on the current span from the given
7278
HttpConnection.
7379
@@ -110,14 +116,17 @@ def trysetip(conn: http.client.HTTPConnection, loglevel=logging.DEBUG) -> bool:
110116

111117

112118
def _instrumented_connect(
113-
wrapped, instance: http.client.HTTPConnection, args, kwargs
114-
):
119+
wrapped: Callable[..., R],
120+
instance: http.client.HTTPConnection,
121+
args: tuple[Any, ...],
122+
kwargs: dict[str, Any],
123+
) -> R:
115124
result = wrapped(*args, **kwargs)
116125
trysetip(instance, loglevel=logging.WARNING)
117126
return result
118127

119128

120-
def instrument_connect(module, name="connect"):
129+
def instrument_connect(module: type[Any], name: str = "connect"):
121130
"""Instrument additional connect() methods, e.g. for derived classes."""
122131

123132
wrapt.wrap_function_wrapper(
@@ -129,8 +138,11 @@ def instrument_connect(module, name="connect"):
129138

130139
def _instrument():
131140
def instrumented_send(
132-
wrapped, instance: http.client.HTTPConnection, args, kwargs
133-
):
141+
wrapped: Callable[..., R],
142+
instance: http.client.HTTPConnection,
143+
args: tuple[Any, ...],
144+
kwargs: dict[str, Any],
145+
) -> R:
134146
done = trysetip(instance)
135147
result = wrapped(*args, **kwargs)
136148
if not done:
@@ -147,8 +159,12 @@ def instrumented_send(
147159
# No need to instrument HTTPSConnection, as it calls super().connect()
148160

149161

150-
def _getstate() -> typing.Optional[dict]:
151-
return context.get_value(_STATE_KEY)
162+
class _ConnectionState(TypedDict):
163+
need_ip: list[Span]
164+
165+
166+
def _getstate() -> _ConnectionState | None:
167+
return cast(_ConnectionState, context.get_value(_STATE_KEY))
152168

153169

154170
@contextlib.contextmanager
@@ -163,7 +179,7 @@ def set_ip_on_next_http_connection(span: Span):
163179
finally:
164180
context.detach(token)
165181
else:
166-
spans: typing.List[Span] = state["need_ip"]
182+
spans = state["need_ip"]
167183
spans.append(span)
168184
try:
169185
yield

util/opentelemetry-util-http/src/opentelemetry/util/http/py.typed

Whitespace-only changes.

0 commit comments

Comments
 (0)