77 should_propagate_trace ,
88 add_http_request_source ,
99 add_sentry_baggage_to_headers ,
10+ has_span_streaming_enabled ,
1011)
1112from sentry_sdk .utils import (
1213 SENSITIVE_DATA_SUBSTITUTE ,
@@ -47,27 +48,46 @@ def setup_once() -> None:
4748def _install_httpx_client () -> None :
4849 real_send = Client .send
4950
50- @ensure_integration_enabled (HttpxIntegration , real_send )
5151 def send (self : "Client" , request : "Request" , ** kwargs : "Any" ) -> "Response" :
52+ client = sentry_sdk .get_client ()
53+ if client .get_integration (HttpxIntegration ) is None :
54+ return real_send (self , request , ** kwargs )
55+
56+ span_streaming = has_span_streaming_enabled (client .options )
57+
5258 parsed_url = None
5359 with capture_internal_exceptions ():
5460 parsed_url = parse_url (str (request .url ), sanitize = False )
5561
56- with start_span (
57- op = OP .HTTP_CLIENT ,
58- name = "%s %s"
59- % (
60- request .method ,
61- parsed_url .url if parsed_url else SENSITIVE_DATA_SUBSTITUTE ,
62- ),
63- origin = HttpxIntegration .origin ,
64- ) as span :
62+ if span_streaming :
63+ span = sentry_sdk .traces .start_span (
64+ name = f"{ request .method } { parsed_url .url if parsed_url else SENSITIVE_DATA_SUBSTITUTE } "
65+ )
66+ span .set_op (OP .HTTP_CLIENT )
67+ span .set_origin (HttpxIntegration .origin )
68+
69+ span .set_attribute (SPANDATA .HTTP_METHOD , request .method )
70+ if parsed_url is not None :
71+ span .set_attribute ("url" , parsed_url .url )
72+ span .set_attribute (SPANDATA .HTTP_QUERY , parsed_url .query )
73+ span .set_attribute (SPANDATA .HTTP_FRAGMENT , parsed_url .fragment )
74+ else :
75+ span = start_span (
76+ op = OP .HTTP_CLIENT ,
77+ name = "%s %s"
78+ % (
79+ request .method ,
80+ parsed_url .url if parsed_url else SENSITIVE_DATA_SUBSTITUTE ,
81+ ),
82+ origin = HttpxIntegration .origin ,
83+ )
6584 span .set_data (SPANDATA .HTTP_METHOD , request .method )
6685 if parsed_url is not None :
6786 span .set_data ("url" , parsed_url .url )
6887 span .set_data (SPANDATA .HTTP_QUERY , parsed_url .query )
6988 span .set_data (SPANDATA .HTTP_FRAGMENT , parsed_url .fragment )
7089
90+ with span :
7191 if should_propagate_trace (sentry_sdk .get_client (), str (request .url )):
7292 for (
7393 key ,
@@ -87,7 +107,10 @@ def send(self: "Client", request: "Request", **kwargs: "Any") -> "Response":
87107 rv = real_send (self , request , ** kwargs )
88108
89109 span .set_http_status (rv .status_code )
90- span .set_data ("reason" , rv .reason_phrase )
110+ if span_streaming :
111+ span .set_attribute ("reason" , rv .reason_phrase )
112+ else :
113+ span .set_data ("reason" , rv .reason_phrase )
91114
92115 with capture_internal_exceptions ():
93116 add_http_request_source (span )
@@ -103,28 +126,44 @@ def _install_httpx_async_client() -> None:
103126 async def send (
104127 self : "AsyncClient" , request : "Request" , ** kwargs : "Any"
105128 ) -> "Response" :
106- if sentry_sdk .get_client ().get_integration (HttpxIntegration ) is None :
129+ client = sentry_sdk .get_client ()
130+ if client .get_integration (HttpxIntegration ) is None :
107131 return await real_send (self , request , ** kwargs )
108132
133+ span_streaming = has_span_streaming_enabled (client .options )
134+
109135 parsed_url = None
110136 with capture_internal_exceptions ():
111137 parsed_url = parse_url (str (request .url ), sanitize = False )
112138
113- with start_span (
114- op = OP .HTTP_CLIENT ,
115- name = "%s %s"
116- % (
117- request .method ,
118- parsed_url .url if parsed_url else SENSITIVE_DATA_SUBSTITUTE ,
119- ),
120- origin = HttpxIntegration .origin ,
121- ) as span :
139+ if span_streaming :
140+ span = sentry_sdk .traces .start_span (
141+ name = f"{ request .method } { parsed_url .url if parsed_url else SENSITIVE_DATA_SUBSTITUTE } "
142+ )
143+ span .set_op (OP .HTTP_CLIENT )
144+ span .set_origin (HttpxIntegration .origin )
145+ span .set_attribute (SPANDATA .HTTP_METHOD , request .method )
146+ if parsed_url is not None :
147+ span .set_attribute ("url" , parsed_url .url )
148+ span .set_attribute (SPANDATA .HTTP_QUERY , parsed_url .query )
149+ span .set_attribute (SPANDATA .HTTP_FRAGMENT , parsed_url .fragment )
150+ else :
151+ span = start_span (
152+ op = OP .HTTP_CLIENT ,
153+ name = "%s %s"
154+ % (
155+ request .method ,
156+ parsed_url .url if parsed_url else SENSITIVE_DATA_SUBSTITUTE ,
157+ ),
158+ origin = HttpxIntegration .origin ,
159+ )
122160 span .set_data (SPANDATA .HTTP_METHOD , request .method )
123161 if parsed_url is not None :
124162 span .set_data ("url" , parsed_url .url )
125163 span .set_data (SPANDATA .HTTP_QUERY , parsed_url .query )
126164 span .set_data (SPANDATA .HTTP_FRAGMENT , parsed_url .fragment )
127165
166+ with span :
128167 if should_propagate_trace (sentry_sdk .get_client (), str (request .url )):
129168 for (
130169 key ,
@@ -146,7 +185,10 @@ async def send(
146185 rv = await real_send (self , request , ** kwargs )
147186
148187 span .set_http_status (rv .status_code )
149- span .set_data ("reason" , rv .reason_phrase )
188+ if span_streaming :
189+ span .set_data ("reason" , rv .reason_phrase )
190+ else :
191+ span .set_attribute ("reason" , rv .reason_phrase )
150192
151193 with capture_internal_exceptions ():
152194 add_http_request_source (span )
0 commit comments