4848 from starlette import __version__ as STARLETTE_VERSION
4949 from starlette .applications import Starlette # type: ignore
5050 from starlette .datastructures import ( # type: ignore
51- FormData ,
5251 UploadFile ,
5352 )
5453 from starlette .middleware import Middleware # type: ignore
9291
9392TRANSACTION_STYLE_VALUES = ("endpoint" , "url" )
9493
95- _SCOPE_STATE_JSON_REQUEST_BODY_KEY = "sentry_sdk.json_request_body"
96- _SCOPE_STATE_FORMDATA_REQUEST_BODY_KEY = "sentry_sdk.formdata_request_body"
97-
9894
9995class StarletteIntegration (Integration ):
10096 identifier = "starlette"
@@ -153,16 +149,6 @@ def setup_once() -> None:
153149 if version >= (0 , 24 ):
154150 patch_templates ()
155151
156- def setup_once_with_options (
157- self : "StarletteIntegration" , options : "Optional[dict[str, Any]]" = None
158- ) -> None :
159- is_span_streaming_enabled = has_span_streaming_enabled (options )
160- if not is_span_streaming_enabled :
161- return
162-
163- _patch_json_request_body_accessor ()
164- _patch_formdata_request_body_accessor ()
165-
166152
167153def _enable_span_for_middleware (middleware_class : "Any" ) -> type :
168154 old_call = middleware_class .__call__
@@ -495,61 +481,13 @@ def _is_async_callable(obj: "Any") -> bool:
495481 )
496482
497483
498- def _patch_json_request_body_accessor () -> None :
499- """
500- Caches request body data on the ASGI scope, so that the body can be attached to telemetry after the request handler runs.
501- Without the cache, consuming the stream causes applications to hang when middleware or handlers consume the raw
502- `receive()` callable exposed by Starlette.
503- """
504- _original_json = Request .json
505-
506- @functools .wraps (_original_json )
507- async def wrapped_json (self : "Request" , * args : "Any" , ** kwargs : "Any" ) -> "Any" :
508- request_json = await _original_json (self , * args , ** kwargs )
509- self .scope .setdefault ("state" , {})[_SCOPE_STATE_JSON_REQUEST_BODY_KEY ] = (
510- request_json
511- )
512- return request_json
513-
514- Request .json = wrapped_json
515-
516-
517- def _patch_formdata_request_body_accessor () -> None :
518- """
519- Caches request body data on the ASGI scope, so that the body can be attached to telemetry after the request handler runs.
520- Without the cache, consuming the stream causes applications to hang when middleware or handlers consume the raw
521- `receive()` callable exposed by Starlette.
522- """
523- if not hasattr (Request , "_get_form" ):
524- return
525-
526- _original_form = Request ._get_form
527-
528- @functools .wraps (_original_form )
529- async def wrapped_form (
530- self : "Request" , * args : "Any" , ** kwargs : "Any"
531- ) -> "FormData" :
532- request_formdata = await _original_form (self , * args , ** kwargs )
533- self .scope .setdefault ("state" , {})[_SCOPE_STATE_FORMDATA_REQUEST_BODY_KEY ] = (
534- request_formdata
535- )
536- return request_formdata
537-
538- Request ._get_form = wrapped_form
539-
540-
541- def _serialize_cached_request_body_attribute (
484+ def _get_cached_request_body_attribute (
542485 client : "sentry_sdk.client.BaseClient" , request : "Request"
543486) -> "Optional[str]" :
544487 """
545- Returns a stringified JSON representation of the request body if the request body is cached on the ASGI scope and within size bounds.
488+ Returns a stringified JSON representation of the request body if the request body is cached and within size bounds.
546489 """
547- scope_state = request .scope .get ("state" , {})
548- if (
549- "content-length" not in request .headers
550- or _SCOPE_STATE_JSON_REQUEST_BODY_KEY not in scope_state
551- and _SCOPE_STATE_FORMDATA_REQUEST_BODY_KEY not in scope_state
552- ):
490+ if "content-length" not in request .headers :
553491 return None
554492
555493 try :
@@ -560,13 +498,16 @@ def _serialize_cached_request_body_attribute(
560498 if content_length and not request_body_within_bounds (client , content_length ):
561499 return OVER_SIZE_LIMIT_SUBSTITUTE
562500
563- if _SCOPE_STATE_JSON_REQUEST_BODY_KEY in request .scope ["state" ]:
564- return json .dumps (request .scope ["state" ][_SCOPE_STATE_JSON_REQUEST_BODY_KEY ])
501+ json_body = getattr (request , "_json" , None )
502+ if json_body is not None :
503+ return json .dumps (json_body )
565504
566- form = request .scope ["state" ][_SCOPE_STATE_FORMDATA_REQUEST_BODY_KEY ]
505+ formdata_body = getattr (request , "_form" , None )
506+ if formdata_body is None :
507+ return
567508
568509 form_data = {}
569- for key , val in form .items ():
510+ for key , val in formdata_body .items ():
570511 is_file = isinstance (val , UploadFile )
571512 form_data [key ] = val if not is_file else "[Unparsable]"
572513
@@ -627,13 +568,13 @@ def event_processor(event: "Event", hint: "Dict[str, Any]") -> "Event":
627568 current_span = _get_current_streamed_span ()
628569
629570 if type (current_span ) is StreamedSpan :
630- serialized_request_body = _serialize_cached_request_body_attribute (
571+ request_body = _get_cached_request_body_attribute (
631572 client = client , request = request
632573 )
633- if serialized_request_body :
574+ if request_body :
634575 current_span ._segment .set_attribute (
635576 SPANDATA .HTTP_REQUEST_BODY_DATA ,
636- serialized_request_body ,
577+ request_body ,
637578 )
638579
639580
0 commit comments