11from sentry_sdk ._types import MYPY
2- from sentry_sdk .hub import Hub
2+ from sentry_sdk .hub import Hub , _should_send_default_pii
33from sentry_sdk .integrations import DidNotEnable
44from sentry_sdk .integrations .starlette import (
5- SentryStarletteMiddleware ,
65 StarletteIntegration ,
6+ StarletteRequestExtractor ,
77)
88from sentry_sdk .tracing import SOURCE_FOR_STYLE , TRANSACTION_SOURCE_ROUTE
99from sentry_sdk .utils import transaction_from_function
1414 from sentry_sdk ._types import Event
1515
1616try :
17- from fastapi import FastAPI # type: ignore
18- from fastapi import Request
17+ import fastapi # type: ignore
1918except ImportError :
2019 raise DidNotEnable ("FastAPI is not installed" )
2120
22- try :
23- from starlette .types import ASGIApp , Receive , Scope , Send # type: ignore
24- except ImportError :
25- raise DidNotEnable ("Starlette is not installed" )
26-
2721
2822_DEFAULT_TRANSACTION_NAME = "generic FastAPI request"
2923
@@ -34,27 +28,7 @@ class FastApiIntegration(StarletteIntegration):
3428 @staticmethod
3529 def setup_once ():
3630 # type: () -> None
37- StarletteIntegration .setup_once ()
38- patch_middlewares ()
39-
40-
41- def patch_middlewares ():
42- # type: () -> None
43-
44- old_build_middleware_stack = FastAPI .build_middleware_stack
45-
46- def _sentry_build_middleware_stack (self ):
47- # type: (FastAPI) -> Callable[..., Any]
48- """
49- Adds `SentryStarletteMiddleware` and `SentryFastApiMiddleware` to the
50- middleware stack of the FastAPI application.
51- """
52- app = old_build_middleware_stack (self )
53- app = SentryStarletteMiddleware (app = app )
54- app = SentryFastApiMiddleware (app = app )
55- return app
56-
57- FastAPI .build_middleware_stack = _sentry_build_middleware_stack
31+ patch_get_request_handler ()
5832
5933
6034def _set_transaction_name_and_source (event , transaction_style , request ):
@@ -82,42 +56,55 @@ def _set_transaction_name_and_source(event, transaction_style, request):
8256 event ["transaction_info" ] = {"source" : SOURCE_FOR_STYLE [transaction_style ]}
8357
8458
85- class SentryFastApiMiddleware :
86- def __init__ (self , app , dispatch = None ):
87- # type: (ASGIApp, Any) -> None
88- self .app = app
59+ def patch_get_request_handler ():
60+ # type: () -> None
61+ old_get_request_handler = fastapi .routing .get_request_handler
62+
63+ def _sentry_get_request_handler (* args , ** kwargs ):
64+ # type: (*Any, **Any) -> Any
65+ old_app = old_get_request_handler (* args , ** kwargs )
66+
67+ async def _sentry_app (* args , ** kwargs ):
68+ # type: (*Any, **Any) -> Any
69+ hub = Hub .current
70+ integration = hub .get_integration (FastApiIntegration )
71+ if integration is None :
72+ return await old_app (* args , ** kwargs )
73+
74+ with hub .configure_scope () as sentry_scope :
75+ request = args [0 ]
76+ extractor = StarletteRequestExtractor (request )
77+ info = await extractor .extract_request_info ()
8978
90- async def __call__ (self , scope , receive , send ):
91- # type: (Scope, Receive, Send) -> Any
92- if scope ["type" ] != "http" :
93- await self .app (scope , receive , send )
94- return
79+ def _make_request_event_processor (req , integration ):
80+ # type: (Any, Any) -> Callable[[Dict[str, Any], Dict[str, Any]], Dict[str, Any]]
81+ def event_processor (event , hint ):
82+ # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
9583
96- hub = Hub .current
97- integration = hub .get_integration (FastApiIntegration )
98- if integration is None :
99- await self .app (scope , receive , send )
100- return
84+ # Extract information from request
85+ request_info = event .get ("request" , {})
86+ if info :
87+ if "cookies" in info and _should_send_default_pii ():
88+ request_info ["cookies" ] = info ["cookies" ]
89+ if "data" in info :
90+ request_info ["data" ] = info ["data" ]
91+ event ["request" ] = request_info
10192
102- with hub .configure_scope () as sentry_scope :
103- request = Request (scope , receive = receive , send = send )
93+ _set_transaction_name_and_source (
94+ event , integration .transaction_style , req
95+ )
10496
105- def _make_request_event_processor (req , integration ):
106- # type: (Any, Any) -> Callable[[Dict[str, Any], Dict[str, Any]], Dict[str, Any]]
107- def event_processor (event , hint ):
108- # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
97+ return event
10998
110- _set_transaction_name_and_source (
111- event , integration .transaction_style , req
112- )
99+ return event_processor
113100
114- return event
101+ sentry_scope ._name = FastApiIntegration .identifier
102+ sentry_scope .add_event_processor (
103+ _make_request_event_processor (request , integration )
104+ )
115105
116- return event_processor
106+ return await old_app ( * args , ** kwargs )
117107
118- sentry_scope ._name = FastApiIntegration .identifier
119- sentry_scope .add_event_processor (
120- _make_request_event_processor (request , integration )
121- )
108+ return _sentry_app
122109
123- await self . app ( scope , receive , send )
110+ fastapi . routing . get_request_handler = _sentry_get_request_handler
0 commit comments