fastapi-radar 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fastapi_radar/__init__.py CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  from .radar import Radar
4
4
 
5
- __version__ = "0.1.7"
5
+ __version__ = "0.1.8"
6
6
  __all__ = ["Radar"]
@@ -109,24 +109,28 @@ class RadarMiddleware(BaseHTTPMiddleware):
109
109
  exception_occurred = False
110
110
 
111
111
  try:
112
- response = await call_next(request)
112
+ response = original_response = await call_next(request)
113
113
 
114
114
  captured_request.status_code = response.status_code
115
115
  captured_request.response_headers = serialize_headers(response.headers)
116
116
 
117
- if self.capture_response_body and not isinstance(
118
- response, StreamingResponse
119
- ):
120
- response_body = b""
121
- async for chunk in response.body_iterator:
122
- response_body += chunk
123
-
124
- captured_request.response_body = truncate_body(
125
- response_body.decode("utf-8", errors="ignore"), self.max_body_size
126
- )
127
-
128
- response = Response(
129
- content=response_body,
117
+ if self.capture_response_body:
118
+
119
+ async def capture_response():
120
+ response_body = ""
121
+ async for chunk in original_response.body_iterator:
122
+ yield chunk
123
+ if len(response_body) < self.max_body_size:
124
+ response_body += chunk.decode("utf-8", errors="ignore")
125
+ with self.get_session() as session:
126
+ captured_request.response_body = truncate_body(
127
+ response_body, self.max_body_size
128
+ )
129
+ session.add(captured_request)
130
+ session.commit()
131
+
132
+ response = StreamingResponse(
133
+ content=capture_response(),
130
134
  status_code=response.status_code,
131
135
  headers=dict(response.headers),
132
136
  media_type=response.media_type,
fastapi_radar/radar.py CHANGED
@@ -34,6 +34,7 @@ class Radar:
34
34
  enable_tracing: bool = True,
35
35
  service_name: str = "fastapi-app",
36
36
  include_in_schema: bool = True,
37
+ db_path: Optional[str] = None,
37
38
  ):
38
39
  self.app = app
39
40
  self.db_engine = db_engine
@@ -46,6 +47,7 @@ class Radar:
46
47
  self.theme = theme
47
48
  self.enable_tracing = enable_tracing
48
49
  self.service_name = service_name
50
+ self.db_path = db_path
49
51
  self.query_capture = None
50
52
 
51
53
  # Exclude radar dashboard paths
@@ -65,7 +67,34 @@ class Radar:
65
67
  # Import duckdb_engine to register the dialect
66
68
  import duckdb_engine # noqa: F401
67
69
 
68
- radar_db_path = Path.cwd() / "radar.duckdb"
70
+ if self.db_path:
71
+ try:
72
+ # Avoid shadowing the attribute name by using a different variable name
73
+ provided_path = Path(self.db_path).resolve()
74
+ if provided_path.suffix.lower() == ".duckdb":
75
+ radar_db_path = provided_path
76
+ radar_db_path.parent.mkdir(parents=True, exist_ok=True)
77
+ else:
78
+ radar_db_path = provided_path / "radar.duckdb"
79
+ provided_path.mkdir(parents=True, exist_ok=True)
80
+
81
+ except Exception as e:
82
+ # Fallback to current directory if path creation fails
83
+ import warnings
84
+
85
+ warnings.warn(
86
+ (
87
+ f"Failed to create database path '{self.db_path}': {e}. "
88
+ f"Using current directory."
89
+ ),
90
+ UserWarning,
91
+ )
92
+
93
+ radar_db_path = Path.cwd() / "radar.duckdb"
94
+ radar_db_path.parent.mkdir(parents=True, exist_ok=True)
95
+ else:
96
+ radar_db_path = Path.cwd() / "radar.duckdb"
97
+ radar_db_path.parent.mkdir(parents=True, exist_ok=True)
69
98
  self.storage_engine = create_engine(
70
99
  f"duckdb:///{radar_db_path}",
71
100
  connect_args={
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-radar
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: A debugging dashboard for FastAPI applications with real-time monitoring
5
5
  Home-page: https://github.com/doganarif/fastapi-radar
6
6
  Author: Arif Dogan
@@ -139,9 +139,30 @@ radar = Radar(
139
139
  capture_sql_bindings=True, # Capture SQL query parameters
140
140
  exclude_paths=["/health"], # Paths to exclude from monitoring
141
141
  theme="auto", # Dashboard theme: "light", "dark", or "auto"
142
+ db_path="/path/to/db", # Custom path for radar.duckdb file (default: current directory)
142
143
  )
143
144
  ```
144
145
 
146
+ ### Custom Database Location
147
+
148
+ By default, FastAPI Radar stores its monitoring data in a `radar.duckdb` file in your current working directory. You can customize this location using the `db_path` parameter:
149
+
150
+ ```python
151
+ # Store in a specific directory
152
+ radar = Radar(app, db_path="/var/data/monitoring")
153
+ # Creates: /var/data/monitoring/radar.duckdb
154
+
155
+ # Store with a specific filename
156
+ radar = Radar(app, db_path="/var/data/my_app_monitoring.duckdb")
157
+ # Creates: /var/data/my_app_monitoring.duckdb
158
+
159
+ # Use a relative path
160
+ radar = Radar(app, db_path="./data")
161
+ # Creates: ./data/radar.duckdb
162
+ ```
163
+
164
+ If the specified path cannot be created, FastAPI Radar will fallback to using the current directory with a warning.
165
+
145
166
  ## What Gets Captured?
146
167
 
147
168
  - ✅ HTTP requests and responses
@@ -1,18 +1,18 @@
1
- fastapi_radar/__init__.py,sha256=RsHUtOtkoaufEyEeY9NyVFNLVyPhUppP2RR6iz9mTyY,137
1
+ fastapi_radar/__init__.py,sha256=fedYsDj_d9FfIVMa1eDrNw5-COcCokqHcM8puxLKLRM,137
2
2
  fastapi_radar/api.py,sha256=JYXYocgWdmjHbrfthpBuqXmIWH8ZNct4qA3WCbinL2o,16099
3
3
  fastapi_radar/capture.py,sha256=butzGPmjR8f3gdrNqh4iOlXD2WBD8Zh6CcSTDlnYR5o,5186
4
- fastapi_radar/middleware.py,sha256=v36cdUWRozkFs1MxG8piRzuazQZG5CHRVp_e7AWobbk,7684
4
+ fastapi_radar/middleware.py,sha256=6FRlZa3XJwOA8UF5NkZ3pOXyK7F9P_ksvixf1CbFllk,8037
5
5
  fastapi_radar/models.py,sha256=jsYakaDd3HRDdAI7SfXLL5fI_fAfVBBhcYq8ktDPfmk,4865
6
- fastapi_radar/radar.py,sha256=8bVoEY9zekgp4bU50fAftgFYc4CP_3t42J8dS4zduvQ,11218
6
+ fastapi_radar/radar.py,sha256=GeD1bUqHX_20oZ0spQylk3-Vusopc9KIUmPoNRNRgQQ,12637
7
7
  fastapi_radar/tracing.py,sha256=m0AEX4sa-VUu5STezhpa51BZQ7R8Ax9u2zry2JSF3hQ,8743
8
8
  fastapi_radar/utils.py,sha256=82cNXjbtm7oTaNRwrSy2fPWDVGi8XSk56C_8o7N7oRQ,1516
9
9
  fastapi_radar/dashboard/dist/index.html,sha256=-Dx0Jw0WDyD29adrACqarkIq_XlUDo7BzqHmt3_mAkc,436
10
10
  fastapi_radar/dashboard/dist/assets/index-By5DXl8Z.js,sha256=D4jEA0Ep4L7PXXo8rZ_saAQIWhl43aAfIdjI6b4eotQ,833887
11
11
  fastapi_radar/dashboard/dist/assets/index-XlGcZj49.css,sha256=z2yLr4jYQoOM7KQ2aw5zrPpMlkr9dRvwBSGaxjzZNnc,35552
12
- fastapi_radar-0.1.7.dist-info/licenses/LICENSE,sha256=0ga4BB6q-nqx6xlDRhtrgKrYs0HgX02PQyIzNFRK09Q,1067
12
+ fastapi_radar-0.1.8.dist-info/licenses/LICENSE,sha256=0ga4BB6q-nqx6xlDRhtrgKrYs0HgX02PQyIzNFRK09Q,1067
13
13
  tests/__init__.py,sha256=kAWaI50iJRZ4JlAdyt7FICgm8MsloZz0ZlsmhgLXBas,31
14
14
  tests/test_radar.py,sha256=3F-_zdemPcgQnjP4kzCa7GhMxNJNYU0SgSWprctyXiA,2374
15
- fastapi_radar-0.1.7.dist-info/METADATA,sha256=fdCi6WDOrkSyPoxQmH0OgWdFdDNjUUJ_q0E7hb7GLLc,5884
16
- fastapi_radar-0.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- fastapi_radar-0.1.7.dist-info/top_level.txt,sha256=M-bALM-KDkiLcATq2aAx-BnG59Nv-GdFBzuzkUhiCa0,20
18
- fastapi_radar-0.1.7.dist-info/RECORD,,
15
+ fastapi_radar-0.1.8.dist-info/METADATA,sha256=pwGBPzfpMOI9z1gnzM1mGc_Svqa9d_jKH3PTe03fKVU,6685
16
+ fastapi_radar-0.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
+ fastapi_radar-0.1.8.dist-info/top_level.txt,sha256=M-bALM-KDkiLcATq2aAx-BnG59Nv-GdFBzuzkUhiCa0,20
18
+ fastapi_radar-0.1.8.dist-info/RECORD,,