1
1
from sentry_sdk ._types import MYPY
2
- from sentry_sdk .hub import Hub
2
+ from sentry_sdk .hub import Hub , _should_send_default_pii
3
3
from sentry_sdk .integrations import DidNotEnable
4
4
from sentry_sdk .integrations .starlette import (
5
- SentryStarletteMiddleware ,
6
5
StarletteIntegration ,
6
+ StarletteRequestExtractor ,
7
7
)
8
8
from sentry_sdk .tracing import SOURCE_FOR_STYLE , TRANSACTION_SOURCE_ROUTE
9
9
from sentry_sdk .utils import transaction_from_function
14
14
from sentry_sdk ._types import Event
15
15
16
16
try :
17
- from fastapi import FastAPI # type: ignore
18
- from fastapi import Request
17
+ import fastapi # type: ignore
19
18
except ImportError :
20
19
raise DidNotEnable ("FastAPI is not installed" )
21
20
22
- try :
23
- from starlette .types import ASGIApp , Receive , Scope , Send # type: ignore
24
- except ImportError :
25
- raise DidNotEnable ("Starlette is not installed" )
26
-
27
21
28
22
_DEFAULT_TRANSACTION_NAME = "generic FastAPI request"
29
23
@@ -34,27 +28,7 @@ class FastApiIntegration(StarletteIntegration):
34
28
@staticmethod
35
29
def setup_once ():
36
30
# 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 ()
58
32
59
33
60
34
def _set_transaction_name_and_source (event , transaction_style , request ):
@@ -82,42 +56,55 @@ def _set_transaction_name_and_source(event, transaction_style, request):
82
56
event ["transaction_info" ] = {"source" : SOURCE_FOR_STYLE [transaction_style ]}
83
57
84
58
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 ()
89
78
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]
95
83
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
101
92
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
+ )
104
96
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
109
98
110
- _set_transaction_name_and_source (
111
- event , integration .transaction_style , req
112
- )
99
+ return event_processor
113
100
114
- return event
101
+ sentry_scope ._name = FastApiIntegration .identifier
102
+ sentry_scope .add_event_processor (
103
+ _make_request_event_processor (request , integration )
104
+ )
115
105
116
- return event_processor
106
+ return await old_app ( * args , ** kwargs )
117
107
118
- sentry_scope ._name = FastApiIntegration .identifier
119
- sentry_scope .add_event_processor (
120
- _make_request_event_processor (request , integration )
121
- )
108
+ return _sentry_app
122
109
123
- await self . app ( scope , receive , send )
110
+ fastapi . routing . get_request_handler = _sentry_get_request_handler
0 commit comments