Skip to content

Commit 668f974

Browse files
committed
refactor: fix lints
1 parent cad67ed commit 668f974

File tree

3 files changed

+60
-59
lines changed

3 files changed

+60
-59
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
default_language_version:
2-
python: python3.12
2+
python: python3.10
33

44
repos:
55
- repo: https://github.com/compilerla/conventional-pre-commit

src/asgi_monitor/integrations/aiohttp.py

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,25 @@
1414
from opentelemetry.propagators.textmap import Getter
1515
from opentelemetry.semconv.metrics import MetricInstruments
1616
from opentelemetry.semconv.trace import SpanAttributes
17-
from opentelemetry.trace import Status, StatusCode, Tracer, TracerProvider
17+
from opentelemetry.trace import Status, Tracer, TracerProvider
1818

1919
from asgi_monitor.metrics import get_latest_metrics
2020
from asgi_monitor.metrics.config import BaseMetricsConfig
2121
from asgi_monitor.metrics.manager import MetricsManager, build_metrics_manager
2222

2323
__all__ = (
2424
"MetricsConfig",
25-
"build_metrics_middleware",
2625
"get_metrics",
2726
"setup_metrics",
2827
"TracingConfig",
2928
"setup_tracing",
3029
)
3130

3231

33-
OTEL_SCHEMA = "https://opentelemetry.io/schemas/1.11.0"
32+
_OTEL_SCHEMA = "https://opentelemetry.io/schemas/1.11.0"
3433

35-
_duration_attrs = [
34+
35+
_DURATION_ATTRS = [
3636
SpanAttributes.HTTP_METHOD,
3737
SpanAttributes.HTTP_HOST,
3838
SpanAttributes.HTTP_SCHEME,
@@ -44,7 +44,7 @@
4444
SpanAttributes.HTTP_ROUTE,
4545
]
4646

47-
_active_requests_count_attrs = [
47+
_ACTIVE_REQUESTS_COUNT_ATTRS = [
4848
SpanAttributes.HTTP_METHOD,
4949
SpanAttributes.HTTP_HOST,
5050
SpanAttributes.HTTP_SCHEME,
@@ -64,39 +64,35 @@ def keys(self, carrier: dict) -> list:
6464
return list(carrier.keys())
6565

6666

67-
getter = AiohttpGetter()
68-
69-
7067
def _get_tracer(tracer_provider: TracerProvider | None = None) -> Tracer:
7168
return trace.get_tracer(
7269
__name__,
7370
tracer_provider=tracer_provider,
74-
schema_url=OTEL_SCHEMA,
71+
schema_url=_OTEL_SCHEMA,
7572
)
7673

7774

78-
def get_meter(
75+
def _get_meter(
7976
name: str,
80-
version: str = "",
8177
meter_provider: MeterProvider | None = None,
8278
schema_url: str | None = None,
8379
) -> Meter:
8480
if meter_provider is None:
8581
meter_provider = get_meter_provider()
86-
return meter_provider.get_meter(name, version, schema_url)
82+
return meter_provider.get_meter(name=name, schema_url=schema_url)
8783

8884

8985
def _parse_duration_attrs(req_attrs: dict[str, Any]) -> dict[str, Any]:
9086
duration_attrs = {}
91-
for attr_key in _duration_attrs:
87+
for attr_key in _DURATION_ATTRS:
9288
if req_attrs.get(attr_key) is not None:
9389
duration_attrs[attr_key] = req_attrs[attr_key]
9490
return duration_attrs
9591

9692

9793
def _parse_active_request_count_attrs(req_attrs: dict[str, Any]) -> dict[str, Any]:
9894
active_requests_count_attrs = {}
99-
for attr_key in _active_requests_count_attrs:
95+
for attr_key in _ACTIVE_REQUESTS_COUNT_ATTRS:
10096
if req_attrs.get(attr_key) is not None:
10197
active_requests_count_attrs[attr_key] = req_attrs[attr_key]
10298
return active_requests_count_attrs
@@ -107,19 +103,10 @@ def _get_default_span_details(request: Request) -> tuple[str, dict]:
107103
return span_name, {}
108104

109105

110-
def set_status_code(span: trace.Span, status_code: int) -> None:
111-
try:
112-
status_code = int(status_code)
113-
except ValueError:
114-
span.set_status(
115-
Status(
116-
StatusCode.ERROR,
117-
"Non-integer HTTP status: " + repr(status_code),
118-
)
119-
)
120-
else:
121-
span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code)
122-
span.set_status(Status(http_status_to_status_code(status_code, server_span=True)))
106+
def _set_status_code(span: trace.Span, status_code: int) -> None:
107+
status_code = int(status_code)
108+
span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code)
109+
span.set_status(Status(http_status_to_status_code(status_code, server_span=True)))
123110

124111

125112
@dataclass(slots=True, frozen=True)
@@ -144,12 +131,11 @@ class TracingConfig:
144131
https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/asgi/asgi.html
145132
"""
146133

147-
exclude_urls_env_key: str = "AIOHTTP"
134+
scope_span_details_extractor: Callable[[Request], tuple[str, dict[str, Any]]] = _get_default_span_details
148135
"""
149-
Key to use when checking whether a list of excluded urls is passed via ENV.
150-
OpenTelemetry supports excluding urls by passing an env in the format '{exclude_urls_env_key}_EXCLUDED_URLS'.
136+
Callback which should return a string and a tuple, representing the desired default span name and a dictionary
137+
with any additional span attributes to set.
151138
"""
152-
scope_span_details_extractor: Callable[[Request], tuple[str, dict[str, Any]]] = _get_default_span_details
153139

154140
meter_provider: MeterProvider | None = field(default=None)
155141
"""Optional meter provider to use."""
@@ -186,6 +172,7 @@ async def metrics_middleware(request: Request, handler: Callable) -> Any:
186172
else:
187173
after_time = time.perf_counter()
188174
status_code = response.status
175+
189176
exemplar: dict[str, str] | None = None
190177

191178
if include_trace_exemplar:
@@ -210,22 +197,22 @@ async def metrics_middleware(request: Request, handler: Callable) -> Any:
210197

211198
def build_tracing_middleware(config: TracingConfig) -> Callable[..., Coroutine]:
212199
tracer = _get_tracer(config.tracer_provider)
213-
meter = get_meter(
214-
name="AIOHTTP",
200+
meter = _get_meter(
201+
name="aiohttp",
215202
meter_provider=config.meter_provider,
216-
schema_url=OTEL_SCHEMA,
203+
schema_url=_OTEL_SCHEMA,
217204
)
218205
duration_histogram = meter.create_histogram(
219206
name=MetricInstruments.HTTP_SERVER_DURATION,
220207
unit="ms",
221208
description="Measures the duration of inbound HTTP requests.",
222209
)
223-
224210
active_requests_counter = meter.create_up_down_counter(
225211
name=MetricInstruments.HTTP_SERVER_ACTIVE_REQUESTS,
226212
unit="requests",
227213
description="measures the number of concurrent HTTP requests those are currently in flight",
228214
)
215+
getter = AiohttpGetter()
229216

230217
@middleware
231218
async def tracing_middleware(request: Request, handler: Callable) -> Any:
@@ -247,9 +234,9 @@ async def tracing_middleware(request: Request, handler: Callable) -> Any:
247234
active_requests_counter.add(1, active_requests_count_attrs)
248235
try:
249236
resp = await handler(request)
250-
set_status_code(span, resp.status)
237+
_set_status_code(span, resp.status)
251238
except HTTPException as ex:
252-
set_status_code(span, ex.status_code)
239+
_set_status_code(span, ex.status_code)
253240
raise
254241
finally:
255242
duration = max((default_timer() - start) * 1000, 0)
@@ -278,13 +265,13 @@ def setup_metrics(app: Application, config: MetricsConfig) -> None:
278265
metrics_middleware = build_metrics_middleware(
279266
metrics_manager=metrics, include_trace_exemplar=config.include_trace_exemplar
280267
)
281-
app._middlewares.append(metrics_middleware) # noqa: SLF001
268+
app.middlewares.append(metrics_middleware)
282269

283270
if config.include_metrics_endpoint:
284271
app.metrics_registry = config.registry
285272
app.openmetrics_format = config.openmetrics_format
286-
app.router.add_get(path="/metrics", handler=get_metrics, name="Get_Prometheus_metrics")
273+
app.router.add_get(path="/metrics", handler=get_metrics)
287274

288275

289276
def setup_tracing(app: Application, config: TracingConfig) -> None:
290-
app._middlewares.append(build_tracing_middleware(config)) # noqa: SLF001
277+
app.middlewares.append(build_tracing_middleware(config))

tests/integration/aiohttp/test_middlewares.py

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import asyncio
22
import json
3-
from typing import Callable, cast
3+
from typing import TYPE_CHECKING, cast
44

5+
from aiohttp.pytest_plugin import AiohttpClient
56
from aiohttp.test_utils import TestClient # noqa: TCH002
67
from aiohttp.web import Application, Request, Response, json_response
78
from aiohttp.web_exceptions import HTTPInternalServerError
89
from assertpy import assert_that
910
from prometheus_client import REGISTRY
1011

12+
if TYPE_CHECKING:
13+
from opentelemetry.sdk.trace import Span
14+
1115
from asgi_monitor.integrations.aiohttp import MetricsConfig, setup_metrics, setup_tracing
1216
from asgi_monitor.metrics import get_latest_metrics
1317
from tests.integration.factory import build_aiohttp_tracing_config
@@ -27,10 +31,10 @@ async def json_response_handler(request: Request) -> Response:
2731

2832

2933
async def raise_handler(request: Request) -> Response:
30-
raise HTTPInternalServerError()
34+
raise HTTPInternalServerError
3135

3236

33-
async def test_metrics(aiohttp_client: Callable) -> None:
37+
async def test_metrics(aiohttp_client: AiohttpClient) -> None:
3438
# Arrange
3539
expected_content_type = "text/plain; version=0.0.4; charset=utf-8"
3640

@@ -59,7 +63,7 @@ async def test_metrics(aiohttp_client: Callable) -> None:
5963
)
6064

6165

62-
async def test_metrics_global_registry(aiohttp_client: Callable) -> None:
66+
async def test_metrics_global_registry(aiohttp_client: AiohttpClient) -> None:
6367
# Arrange
6468
app = Application()
6569

@@ -85,7 +89,7 @@ async def test_metrics_global_registry(aiohttp_client: Callable) -> None:
8589
)
8690

8791

88-
async def test_metrics_get_path(aiohttp_client: Callable) -> None:
92+
async def test_metrics_get_path(aiohttp_client: AiohttpClient) -> None:
8993
# Arrange
9094
app = Application()
9195

@@ -110,7 +114,7 @@ async def test_metrics_get_path(aiohttp_client: Callable) -> None:
110114
)
111115

112116

113-
async def test_metrics_with_tracing(aiohttp_client: Callable) -> None:
117+
async def test_metrics_with_tracing(aiohttp_client: AiohttpClient) -> None:
114118
# Arrange
115119
app = Application()
116120
app.router.add_get("/", index_handler)
@@ -131,7 +135,15 @@ async def test_metrics_with_tracing(aiohttp_client: Callable) -> None:
131135
# Assert
132136
assert response.status == 200
133137
metrics = get_latest_metrics(metrics_cfg.registry, openmetrics_format=True)
134-
span = exporter.get_finished_spans()[0]
138+
span = cast("tuple[Span, Span, Span]", exporter.get_finished_spans())
139+
assert_that(span[0].attributes).is_equal_to(
140+
{
141+
"http.host": "0.0.0.0", # noqa: S104
142+
"net.host.port": 80,
143+
"http.url": "http://0.0.0.0",
144+
"http.status_code": 200,
145+
}
146+
)
135147
pattern = (
136148
r"aiohttp_request_duration_seconds_bucket\{"
137149
r'app_name="test",le="([\d.]+)",method="GET",path="\/"}\ 1.0 # \{TraceID="(\w+)"\} (\d+\.\d+) (\d+\.\d+)'
@@ -140,7 +152,7 @@ async def test_metrics_with_tracing(aiohttp_client: Callable) -> None:
140152
assert_that(metrics.payload.decode()).contains('aiohttp_app_info{app_name="test"} 1.0')
141153

142154

143-
async def test_metrics_openmetrics_with_tracing(aiohttp_client: Callable) -> None:
155+
async def test_metrics_openmetrics_with_tracing(aiohttp_client: AiohttpClient) -> None:
144156
# Arrange
145157
expected_content_type = "application/openmetrics-text; version=1.0.0; charset=utf-8"
146158

@@ -175,7 +187,7 @@ async def test_metrics_openmetrics_with_tracing(aiohttp_client: Callable) -> Non
175187
assert_that(metrics_content).contains('aiohttp_app_info{app_name="test"} 1.0')
176188

177189

178-
async def test_handle_exception(aiohttp_client: Callable) -> None:
190+
async def test_error_metrics(aiohttp_client: AiohttpClient) -> None:
179191
# Arrange
180192
expected_content_type = "text/plain; version=0.0.4; charset=utf-8"
181193

@@ -215,7 +227,7 @@ async def test_handle_exception(aiohttp_client: Callable) -> None:
215227
)
216228

217229

218-
async def test_json_response_handle(aiohttp_client: Callable) -> None:
230+
async def test_json_response_handle(aiohttp_client: AiohttpClient) -> None:
219231
# Arrange
220232
expected_content_type = "text/plain; version=0.0.4; charset=utf-8"
221233

@@ -247,7 +259,7 @@ async def test_json_response_handle(aiohttp_client: Callable) -> None:
247259
)
248260

249261

250-
async def test_error_handle_with_tracing(aiohttp_client: Callable) -> None:
262+
async def test_error_handle_with_tracing(aiohttp_client: AiohttpClient) -> None:
251263
# Arrange
252264
app = Application()
253265
app.router.add_get("/error", zero_division_handler)
@@ -275,7 +287,7 @@ async def test_error_handle_with_tracing(aiohttp_client: Callable) -> None:
275287
)
276288

277289

278-
async def test_raise_handler_with_tracing(aiohttp_client: Callable) -> None:
290+
async def test_raise_handler_with_tracing(aiohttp_client: AiohttpClient) -> None:
279291
# Arrange
280292
app = Application()
281293
app.router.add_get("/raise_handler", raise_handler)
@@ -301,7 +313,7 @@ async def test_raise_handler_with_tracing(aiohttp_client: Callable) -> None:
301313
)
302314

303315

304-
async def test_tracing(aiohttp_client: Callable) -> None:
316+
async def test_tracing(aiohttp_client: AiohttpClient) -> None:
305317
# Arrange
306318
app = Application()
307319
app.router.add_get("/", index_handler)
@@ -313,12 +325,14 @@ async def test_tracing(aiohttp_client: Callable) -> None:
313325
client: TestClient = await aiohttp_client(app)
314326
# Act
315327
response = await client.get("/")
328+
# Assert
316329
span = cast("tuple[Span, Span, Span]", exporter.get_finished_spans())
317-
assert_that(span[0].attributes).is_equal_to({
318-
'http.host': '0.0.0.0',
319-
'net.host.port': 80,
320-
'http.url': 'http://0.0.0.0',
321-
'http.status_code': 200
330+
assert_that(span[0].attributes).is_equal_to(
331+
{
332+
"http.host": "0.0.0.0", # noqa: S104
333+
"net.host.port": 80,
334+
"http.url": "http://0.0.0.0",
335+
"http.status_code": 200,
322336
}
323337
)
324338
assert response.status == 200

0 commit comments

Comments
 (0)