Skip to content

Commit 5d2ee24

Browse files
committed
nit: address PR comments
1 parent 2d5bf72 commit 5d2ee24

File tree

3 files changed

+42
-93
lines changed

3 files changed

+42
-93
lines changed

sentry_sdk/integrations/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ def iter_default_integrations(
9494
"sentry_sdk.integrations.openai.OpenAIIntegration",
9595
"sentry_sdk.integrations.openai_agents.OpenAIAgentsIntegration",
9696
"sentry_sdk.integrations.pydantic_ai.PydanticAIIntegration",
97-
"sentry_sdk.integrations.pyreqwest.PyreqwestIntegration",
9897
"sentry_sdk.integrations.pymongo.PyMongoIntegration",
9998
"sentry_sdk.integrations.pyramid.PyramidIntegration",
10099
"sentry_sdk.integrations.quart.QuartIntegration",

sentry_sdk/integrations/pyreqwest.py

Lines changed: 42 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,22 @@
1515
parse_url,
1616
)
1717

18-
from typing import TYPE_CHECKING
19-
20-
if TYPE_CHECKING:
21-
from typing import Any
22-
23-
24-
import importlib.util
25-
26-
if importlib.util.find_spec("pyreqwest") is None:
27-
raise DidNotEnable("pyreqwest is not installed")
18+
from contextlib import contextmanager
19+
from typing import Any, Generator
20+
21+
try:
22+
from pyreqwest.client import ClientBuilder, SyncClientBuilder # type: ignore[import-not-found]
23+
from pyreqwest.request import ( # type: ignore[import-not-found]
24+
Request,
25+
RequestBuilder,
26+
SyncRequestBuilder,
27+
OneOffRequestBuilder,
28+
SyncOneOffRequestBuilder,
29+
)
30+
from pyreqwest.middleware import Next, SyncNext # type: ignore[import-not-found]
31+
from pyreqwest.response import Response, SyncResponse # type: ignore[import-not-found]
32+
except ImportError:
33+
raise DidNotEnable("pyreqwest not installed or incompatible version installed")
2834

2935

3036
class PyreqwestIntegration(Integration):
@@ -38,33 +44,16 @@ def setup_once() -> None:
3844

3945
def _patch_pyreqwest() -> None:
4046
# Patch Client Builders
41-
try:
42-
from pyreqwest.client import ClientBuilder, SyncClientBuilder # type: ignore[import-not-found]
43-
44-
_patch_builder_method(ClientBuilder, "build", sentry_async_middleware)
45-
_patch_builder_method(SyncClientBuilder, "build", sentry_sync_middleware)
46-
except ImportError:
47-
pass
47+
_patch_builder_method(ClientBuilder, "build", sentry_async_middleware)
48+
_patch_builder_method(SyncClientBuilder, "build", sentry_sync_middleware)
4849

4950
# Patch Request Builders (for simple requests and manual request building)
50-
try:
51-
from pyreqwest.request import ( # type: ignore[import-not-found]
52-
RequestBuilder,
53-
SyncRequestBuilder,
54-
OneOffRequestBuilder,
55-
SyncOneOffRequestBuilder,
56-
)
57-
58-
_patch_builder_method(RequestBuilder, "build", sentry_async_middleware)
59-
_patch_builder_method(RequestBuilder, "build_streamed", sentry_async_middleware)
60-
_patch_builder_method(SyncRequestBuilder, "build", sentry_sync_middleware)
61-
_patch_builder_method(
62-
SyncRequestBuilder, "build_streamed", sentry_sync_middleware
63-
)
64-
_patch_builder_method(OneOffRequestBuilder, "send", sentry_async_middleware)
65-
_patch_builder_method(SyncOneOffRequestBuilder, "send", sentry_sync_middleware)
66-
except ImportError:
67-
pass
51+
_patch_builder_method(RequestBuilder, "build", sentry_async_middleware)
52+
_patch_builder_method(RequestBuilder, "build_streamed", sentry_async_middleware)
53+
_patch_builder_method(SyncRequestBuilder, "build", sentry_sync_middleware)
54+
_patch_builder_method(SyncRequestBuilder, "build_streamed", sentry_sync_middleware)
55+
_patch_builder_method(OneOffRequestBuilder, "send", sentry_async_middleware)
56+
_patch_builder_method(SyncOneOffRequestBuilder, "send", sentry_sync_middleware)
6857

6958

7059
def _patch_builder_method(cls: type, method_name: str, middleware: "Any") -> None:
@@ -88,21 +77,15 @@ def sentry_patched_method(self: "Any", *args: "Any", **kwargs: "Any") -> "Any":
8877
setattr(cls, method_name, sentry_patched_method)
8978

9079

91-
async def sentry_async_middleware(request: "Any", next_handler: "Any") -> "Any":
92-
if sentry_sdk.get_client().get_integration(PyreqwestIntegration) is None:
93-
return await next_handler.run(request)
94-
80+
@contextmanager
81+
def _sentry_pyreqwest_span(request: "Request") -> "Generator[Any, None, None]":
9582
parsed_url = None
9683
with capture_internal_exceptions():
9784
parsed_url = parse_url(str(request.url), sanitize=False)
9885

9986
with start_span(
10087
op=OP.HTTP_CLIENT,
101-
name="%s %s"
102-
% (
103-
request.method,
104-
parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE,
105-
),
88+
name=f"{request.method} {parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE}",
10689
origin=PyreqwestIntegration.origin,
10790
) as span:
10891
span.set_data(SPANDATA.HTTP_METHOD, request.method)
@@ -127,60 +110,33 @@ async def sentry_async_middleware(request: "Any", next_handler: "Any") -> "Any":
127110
else:
128111
request.headers[key] = value
129112

130-
response = await next_handler.run(request)
131-
132-
span.set_http_status(response.status)
113+
yield span
133114

134115
with capture_internal_exceptions():
135116
add_http_request_source(span)
136117

137-
return response
138-
139118

140-
def sentry_sync_middleware(request: "Any", next_handler: "Any") -> "Any":
119+
async def sentry_async_middleware(
120+
request: "Request", next_handler: "Next"
121+
) -> "Response":
141122
if sentry_sdk.get_client().get_integration(PyreqwestIntegration) is None:
142-
return next_handler.run(request)
123+
return await next_handler.run(request)
143124

144-
parsed_url = None
145-
with capture_internal_exceptions():
146-
parsed_url = parse_url(str(request.url), sanitize=False)
125+
with _sentry_pyreqwest_span(request) as span:
126+
response = await next_handler.run(request)
127+
span.set_http_status(response.status)
147128

148-
with start_span(
149-
op=OP.HTTP_CLIENT,
150-
name="%s %s"
151-
% (
152-
request.method,
153-
parsed_url.url if parsed_url else SENSITIVE_DATA_SUBSTITUTE,
154-
),
155-
origin=PyreqwestIntegration.origin,
156-
) as span:
157-
span.set_data(SPANDATA.HTTP_METHOD, request.method)
158-
if parsed_url is not None:
159-
span.set_data("url", parsed_url.url)
160-
span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query)
161-
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)
129+
return response
162130

163-
if should_propagate_trace(sentry_sdk.get_client(), str(request.url)):
164-
for (
165-
key,
166-
value,
167-
) in sentry_sdk.get_current_scope().iter_trace_propagation_headers():
168-
logger.debug(
169-
"[Tracing] Adding `{key}` header {value} to outgoing request to {url}.".format(
170-
key=key, value=value, url=request.url
171-
)
172-
)
173131

174-
if key == BAGGAGE_HEADER_NAME:
175-
add_sentry_baggage_to_headers(request.headers, value)
176-
else:
177-
request.headers[key] = value
132+
def sentry_sync_middleware(
133+
request: "Request", next_handler: "SyncNext"
134+
) -> "SyncResponse":
135+
if sentry_sdk.get_client().get_integration(PyreqwestIntegration) is None:
136+
return next_handler.run(request)
178137

138+
with _sentry_pyreqwest_span(request) as span:
179139
response = next_handler.run(request)
180-
181140
span.set_http_status(response.status)
182141

183-
with capture_internal_exceptions():
184-
add_http_request_source(span)
185-
186142
return response

tests/integrations/pyreqwest/test_pyreqwest.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from threading import Thread
33
import pytest
44

5-
import pyreqwest
65
from pyreqwest.client import ClientBuilder, SyncClientBuilder
76
from pyreqwest.simple.request import pyreqwest_get as async_pyreqwest_get
87
from pyreqwest.simple.sync_request import pyreqwest_get as sync_pyreqwest_get
@@ -55,7 +54,6 @@ def clear_captured_requests():
5554
PyreqwestMockHandler.captured_requests.clear()
5655

5756

58-
@pytest.mark.skipif(pyreqwest is None, reason="pyreqwest not installed")
5957
def test_sync_client_spans(sentry_init, capture_events, server_port):
6058
sentry_init(integrations=[PyreqwestIntegration()], traces_sample_rate=1.0)
6159
events = capture_events()
@@ -75,7 +73,6 @@ def test_sync_client_spans(sentry_init, capture_events, server_port):
7573
assert span["origin"] == "auto.http.pyreqwest"
7674

7775

78-
@pytest.mark.skipif(pyreqwest is None, reason="pyreqwest not installed")
7976
@pytest.mark.asyncio
8077
async def test_async_client_spans(sentry_init, capture_events, server_port):
8178
sentry_init(integrations=[PyreqwestIntegration()], traces_sample_rate=1.0)
@@ -96,7 +93,6 @@ async def test_async_client_spans(sentry_init, capture_events, server_port):
9693
assert span["origin"] == "auto.http.pyreqwest"
9794

9895

99-
@pytest.mark.skipif(pyreqwest is None, reason="pyreqwest not installed")
10096
def test_sync_simple_request_spans(sentry_init, capture_events, server_port):
10197
sentry_init(integrations=[PyreqwestIntegration()], traces_sample_rate=1.0)
10298
events = capture_events()
@@ -112,7 +108,6 @@ def test_sync_simple_request_spans(sentry_init, capture_events, server_port):
112108
assert span["description"] == f"GET {url}"
113109

114110

115-
@pytest.mark.skipif(pyreqwest is None, reason="pyreqwest not installed")
116111
@pytest.mark.asyncio
117112
async def test_async_simple_request_spans(sentry_init, capture_events, server_port):
118113
sentry_init(integrations=[PyreqwestIntegration()], traces_sample_rate=1.0)
@@ -129,7 +124,6 @@ async def test_async_simple_request_spans(sentry_init, capture_events, server_po
129124
assert span["description"] == f"GET {url}"
130125

131126

132-
@pytest.mark.skipif(pyreqwest is None, reason="pyreqwest not installed")
133127
def test_outgoing_trace_headers(sentry_init, server_port):
134128
sentry_init(
135129
integrations=[PyreqwestIntegration()],

0 commit comments

Comments
 (0)