Skip to content

Commit 4ba7e83

Browse files
committed
added more tests to the event code, and fixed couple bugs
1 parent c7a4a70 commit 4ba7e83

8 files changed

Lines changed: 283 additions & 71 deletions

File tree

osbot_fast_api/api/Fast_API.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ def routes_paths_all(self):
155155
return self.routes_paths(include_default=True, expand_mounts=True)
156156

157157

158-
def setup_middlewares(self): # overwrite to add more middlewares
159-
self.setup_middleware__request_id () # sets the 'fast-api-request-id' headers
158+
def setup_middlewares(self): # overwrite to add more middlewares (NOTE: the middleware execution is the reverse of the order they are added)
160159
self.setup_middleware__detect_disconnect()
161160
self.setup_middleware__cors ()
162161
self.setup_middleware__api_key_check ()
162+
self.setup_middleware__request_id () # sets the 'fast-api-request-id' headers
163163
return self
164164

165165
def setup_routes (self): return self # overwrite to add rules

osbot_fast_api/api/events/Fast_API__Http_Event.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Fast_API__Http_Event(Type_Safe):
2626
http_event_request : Fast_API__Http_Event__Request
2727
http_event_response : Fast_API__Http_Event__Response
2828
http_event_traces : Fast_API__Http_Event__Traces
29-
event_id : Random_Guid # todo: rename to http_event_id
29+
event_id : Random_Guid # todo: rename to http_event_id
3030

3131
def __init__(self, **kwargs):
3232
super().__init__(**kwargs)
@@ -60,7 +60,6 @@ def messages(self):
6060
return messages
6161

6262
def on_request(self, request: Request):
63-
6463
# http_event_request
6564
self.http_event_request.headers = dict(request.headers)
6665
self.http_event_request.host_name = request.url.hostname
@@ -77,8 +76,6 @@ def on_request(self, request: Request):
7776
self.http_event_info.timestamp = timestamp_utc_now()
7877
self.http_event_info.thread_id = current_thread_id()
7978

80-
self.set_request_headers(request)
81-
8279
def on_response(self, response: Response):
8380
# http_event_response
8481
self.http_event_response.end_time = Decimal(time.time())
@@ -88,19 +85,12 @@ def on_response(self, response: Response):
8885
self.http_event_request.duration = self.http_event_request.duration .quantize(Decimal('0.001')) # (maybe a custom Decimal class)
8986

9087
if response:
88+
self.set_response_header_for_static_files_cache(response)
9189
self.http_event_response.content_type = response.headers.get('content-type')
9290
self.http_event_response.content_length = response.headers.get('content-length')
9391
self.http_event_response.status_code = response.status_code
94-
self.set_response_headers(response)
9592
self.http_event_response.headers = dict(response.headers)
9693

97-
def set_request_headers(self, request: Request):
98-
request.headers._list.append((b'fast-api-request-id', str_to_bytes(self.event_id)))
99-
100-
def set_response_headers(self, response:Response):
101-
response.headers[HEADER_NAME__FAST_API_REQUEST_ID] = self.event_id
102-
self.set_response_header_for_static_files_cache(response)
103-
return self
10494

10595
def set_response_header_for_static_files_cache(self, response:Response):
10696
if self.http_event_response.content_type in HTTP_RESPONSE__CACHE_CONTENT_TYPES:

osbot_fast_api/api/events/Fast_API__Http_Events.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import types
22
from collections import deque
3-
from osbot_utils.type_safe.Type_Safe import Type_Safe
4-
from osbot_utils.helpers.trace.Trace_Call__Config import Trace_Call__Config
3+
from osbot_utils.type_safe.primitives.domains.identifiers.Random_Guid import Random_Guid
4+
from osbot_utils.type_safe.Type_Safe import Type_Safe
5+
from osbot_utils.helpers.trace.Trace_Call__Config import Trace_Call__Config
56

67

78
HTTP_EVENTS__MAX_REQUESTS_LOGGED = 50
89

910
from typing import TYPE_CHECKING, Union
1011

11-
if TYPE_CHECKING:
12-
from fastapi import Request
13-
from starlette.responses import Response
14-
from osbot_fast_api.api.events.Fast_API__Http_Event import Fast_API__Http_Event
12+
# if TYPE_CHECKING:
13+
# from fastapi import Request
14+
# from starlette.responses import Response
15+
from osbot_fast_api.api.events.Fast_API__Http_Event import Fast_API__Http_Event
1516

1617
class Fast_API__Http_Events(Type_Safe):
1718
#log_requests : bool = False # todo: change this to save on S3 and disk
@@ -25,7 +26,6 @@ class Fast_API__Http_Events(Type_Safe):
2526
requests_order : deque
2627
max_requests_logged : int = HTTP_EVENTS__MAX_REQUESTS_LOGGED
2728
fast_api_name : str
28-
#add_header_request_id : bool = True
2929

3030
def __init__(self,**kwargs):
3131
super().__init__(**kwargs)
@@ -75,9 +75,14 @@ def create_request_data(self, request):
7575
from osbot_fast_api.api.events.Fast_API__Http_Event import Fast_API__Http_Event
7676
from osbot_fast_api.api.events.Fast_API__Http_Event__Info import Fast_API__Http_Event__Info
7777

78+
if hasattr(request.state, 'request_id'): # Use existing request_id if available (from Middleware__Request_ID)
79+
event_id = request.state.request_id
80+
else:
81+
event_id = Random_Guid() # Fallback if middleware not present
82+
7883
kwargs = dict(fast_api_name = self.fast_api_name)
7984
http_event_info = Fast_API__Http_Event__Info(**kwargs)
80-
http_event = Fast_API__Http_Event(http_event_info=http_event_info)
85+
http_event = Fast_API__Http_Event(http_event_info=http_event_info, event_id=event_id)
8186
event_id = http_event.event_id # get the random request_id/guid that was created in the ctor of Fast_API__Request_Data
8287
request.state.http_events = self # store a copy of this object in the request (so that it is available durant the request handling)
8388
request.state.request_id = event_id # store request_id in request.state
@@ -103,8 +108,13 @@ def event_id(self, request):
103108
return self.request_data(request).event_id
104109

105110
def request_messages(self, request):
106-
event_id = self.event_id(request)
107-
return self.requests_data.get(event_id, {}).get('messages', [])
111+
event_id = self.event_id(request)
112+
http_event = self.requests_data.get(event_id)#.get('messages', [])
113+
if type(http_event) is Fast_API__Http_Event:
114+
return http_event.messages()
115+
if type(http_event) is dict:
116+
return http_event.get('messages', [])
117+
return []
108118

109119
def request_trace_start(self, request):
110120
from osbot_utils.helpers.trace.Trace_Call import Trace_Call

osbot_fast_api/events/Fast_API__With_Events.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ def __init__(self, **kwargs):
99
super().__init__(**kwargs)
1010
self.http_events.fast_api_name = self.config.name # Wire up the name
1111

12-
def setup_middlewares(self): # Add event middleware
12+
def setup_middlewares(self): # Add event middleware (NOTE: the middleware execution is the reverse of the order they are added)
13+
self.setup_middleware__http_events() # This will make this middleware to be the last one executed
1314
super().setup_middlewares() # Call parent middlewares first
14-
self.setup_middleware__http_events() # Then add events
15+
1516
return self
1617

1718
def setup_middleware__http_events(self): # Moved from base class

tests/unit/api/events/test_Fast_API__Http_Events.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ def test_on_http_response(self):
107107
#assert _.log_requests is False
108108
assert _.requests_data == {self.event_id : self.request_data}
109109

110-
assert self.response.headers == MutableHeaders({'content-length': '0', 'fast-api-request-id': self.event_id})
111-
110+
#assert self.response.headers == MutableHeaders({'content-length': '0', 'fast-api-request-id': self.event_id}) # this is now set on Middleware__Request_ID
112111

113112

113+
duration = self.request_data.http_event_request.duration
114114
expected_data = { 'http_event_info' : { 'client_city' : None ,
115115
'client_country' : None ,
116116
'client_ip' : 'pytest' ,
@@ -121,7 +121,7 @@ def test_on_http_response(self):
121121
'thread_id' : self.request_data.http_event_info.thread_id ,
122122
'timestamp' : self.request_data.http_event_info.timestamp ,
123123
'log_messages' : [] },
124-
'http_event_request' : { 'duration' : Decimal('0.001') ,
124+
'http_event_request' : { 'duration' : duration ,
125125
'host_name' : None ,
126126
'headers' : {} ,
127127
'event_id' : self.request_data.event_id ,
@@ -143,7 +143,7 @@ def test_on_http_response(self):
143143
'traces_count' : 0 ,
144144
'traces_id' : self.request_data.http_event_traces.traces_id }}
145145

146-
assert self.request_data.http_event_request.duration == Decimal(0.001).quantize(Decimal('0.001'))
146+
assert self.request_data.http_event_request.duration >= Decimal(0.001).quantize(Decimal('0.001'))
147147
assert self.request_data.json() == expected_data
148148

149149

tests/unit/api/test_Fast_API.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ def test_setup_routes(self):
103103
assert self.fast_api.setup_routes() == self.fast_api
104104

105105
def test_user_middleware(self):
106-
assert self.fast_api.user_middlewares() == [{'function_name': None, 'params': {}, 'type': 'Middleware__Detect_Disconnect'},
107-
{'function_name': None, 'params': {}, 'type': 'Middleware__Request_ID' }]
106+
assert self.fast_api.user_middlewares() == [{'function_name': None, 'params': {}, 'type': 'Middleware__Request_ID' },
107+
{'function_name': None, 'params': {}, 'type': 'Middleware__Detect_Disconnect'}]
108108

109109
def test__verify__title_description_version(self):
110110
app = self.fast_api.app()

0 commit comments

Comments
 (0)