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
3036class PyreqwestIntegration (Integration ):
@@ -38,33 +44,16 @@ def setup_once() -> None:
3844
3945def _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
7059def _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
0 commit comments