logbrew-fastapi 0.1.1__tar.gz → 0.1.2__tar.gz
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.
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/PKG-INFO +18 -1
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/README.md +17 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/pyproject.toml +1 -1
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi/__init__.py +112 -2
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi.egg-info/PKG-INFO +18 -1
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/tests/test_fastapi_integration.py +38 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/setup.cfg +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi/examples/__init__.py +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi/examples/__main__.py +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi/examples/readme_example.py +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi/examples/real_user_smoke.py +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi/py.typed +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi.egg-info/SOURCES.txt +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi.egg-info/dependency_links.txt +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi.egg-info/requires.txt +0 -0
- {logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: logbrew-fastapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: FastAPI integration for capturing LogBrew request spans and exceptions.
|
|
5
5
|
Author: LogBrew
|
|
6
6
|
License-Expression: MIT
|
|
@@ -23,6 +23,10 @@ Requires-Dist: logbrew-sdk<0.2.0,>=0.1.1
|
|
|
23
23
|
|
|
24
24
|
# logbrew-fastapi
|
|
25
25
|
|
|
26
|
+
<p align="center">
|
|
27
|
+
<img src="https://raw.githubusercontent.com/LogBrewCo/sdk/main/assets/brand/logbrew-logo-espresso-bg-512.png" alt="LogBrew logo" width="96" height="96">
|
|
28
|
+
</p>
|
|
29
|
+
|
|
26
30
|
FastAPI integration for capturing LogBrew request spans and exceptions with the public Python SDK.
|
|
27
31
|
|
|
28
32
|
## Install
|
|
@@ -64,6 +68,19 @@ def health() -> dict[str, bool]:
|
|
|
64
68
|
|
|
65
69
|
When an incoming request has a valid W3C `traceparent` header, request capture continues that trace by using the incoming `traceId` and parent span id while creating a fresh child span id. Missing or malformed `traceparent` headers keep the existing synthetic request span behavior so bad client headers do not break the app. Automatic metadata uses the request path without query text.
|
|
66
70
|
|
|
71
|
+
Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
add_logbrew_middleware(
|
|
75
|
+
app,
|
|
76
|
+
client=client,
|
|
77
|
+
transport=transport,
|
|
78
|
+
capture_request_metrics=True,
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The metric includes primitive, low-cardinality metadata: `framework`, `method`, `routeTemplate`, `statusCode`, and `statusCodeClass`. Query strings and URL hashes are omitted. Set `capture_successful_requests=False` with `capture_request_metrics=True` when you only want duration metrics and not successful request spans. Avoid user IDs, request payloads, headers, or free-form text in custom metric metadata.
|
|
83
|
+
|
|
67
84
|
By default, transport failures do not break the FastAPI response path. Set `raise_flush_errors=True` only when your app wants delivery failures to surface as request errors.
|
|
68
85
|
|
|
69
86
|
Use a clearly fake placeholder like `LOGBREW_API_KEY` in examples.
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# logbrew-fastapi
|
|
2
2
|
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/LogBrewCo/sdk/main/assets/brand/logbrew-logo-espresso-bg-512.png" alt="LogBrew logo" width="96" height="96">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
3
7
|
FastAPI integration for capturing LogBrew request spans and exceptions with the public Python SDK.
|
|
4
8
|
|
|
5
9
|
## Install
|
|
@@ -41,6 +45,19 @@ def health() -> dict[str, bool]:
|
|
|
41
45
|
|
|
42
46
|
When an incoming request has a valid W3C `traceparent` header, request capture continues that trace by using the incoming `traceId` and parent span id while creating a fresh child span id. Missing or malformed `traceparent` headers keep the existing synthetic request span behavior so bad client headers do not break the app. Automatic metadata uses the request path without query text.
|
|
43
47
|
|
|
48
|
+
Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
add_logbrew_middleware(
|
|
52
|
+
app,
|
|
53
|
+
client=client,
|
|
54
|
+
transport=transport,
|
|
55
|
+
capture_request_metrics=True,
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The metric includes primitive, low-cardinality metadata: `framework`, `method`, `routeTemplate`, `statusCode`, and `statusCodeClass`. Query strings and URL hashes are omitted. Set `capture_successful_requests=False` with `capture_request_metrics=True` when you only want duration metrics and not successful request spans. Avoid user IDs, request payloads, headers, or free-form text in custom metric metadata.
|
|
60
|
+
|
|
44
61
|
By default, transport failures do not break the FastAPI response path. Set `raise_flush_errors=True` only when your app wants delivery failures to surface as request errors.
|
|
45
62
|
|
|
46
63
|
Use a clearly fake placeholder like `LOGBREW_API_KEY` in examples.
|
|
@@ -12,6 +12,7 @@ from typing import Any
|
|
|
12
12
|
from fastapi import FastAPI, Request, Response
|
|
13
13
|
from logbrew_sdk import (
|
|
14
14
|
LogBrewClient,
|
|
15
|
+
MetricAttributes,
|
|
15
16
|
RecordingTransport,
|
|
16
17
|
SdkError,
|
|
17
18
|
SpanAttributes,
|
|
@@ -30,10 +31,12 @@ class LogBrewFastAPIConfig:
|
|
|
30
31
|
client: LogBrewClient
|
|
31
32
|
transport: RecordingTransport | None = None
|
|
32
33
|
capture_successful_requests: bool = True
|
|
34
|
+
capture_request_metrics: bool = False
|
|
33
35
|
capture_exceptions: bool = True
|
|
34
36
|
flush_on_response: bool = True
|
|
35
37
|
raise_flush_errors: bool = False
|
|
36
38
|
service_name: str = "fastapi"
|
|
39
|
+
request_metric_name: str = "http.server.duration"
|
|
37
40
|
span_id_factory: Callable[[], str] | None = None
|
|
38
41
|
|
|
39
42
|
|
|
@@ -73,6 +76,82 @@ def request_metadata(
|
|
|
73
76
|
return metadata
|
|
74
77
|
|
|
75
78
|
|
|
79
|
+
def request_route_template(request: Request) -> str:
|
|
80
|
+
"""Return a low-cardinality FastAPI route template without query strings."""
|
|
81
|
+
|
|
82
|
+
route = request.scope.get("route")
|
|
83
|
+
route_path = getattr(route, "path", None)
|
|
84
|
+
template = route_path if isinstance(route_path, str) and route_path else request.url.path
|
|
85
|
+
return route_template_only(template)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def route_template_only(value: str) -> str:
|
|
89
|
+
"""Strip query/hash text from a route template and normalize empty values."""
|
|
90
|
+
|
|
91
|
+
route_template = value.split("?", 1)[0].split("#", 1)[0].strip()
|
|
92
|
+
return route_template or "/"
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def status_code_class(status_code: int) -> str:
|
|
96
|
+
"""Return the coarse HTTP status code class used by request metrics."""
|
|
97
|
+
|
|
98
|
+
return f"{status_code // 100}xx" if 100 <= status_code <= 599 else "unknown"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def create_request_metric_attributes(
|
|
102
|
+
request: Request,
|
|
103
|
+
*,
|
|
104
|
+
status_code: int,
|
|
105
|
+
duration_ms: float,
|
|
106
|
+
metric_name: str = "http.server.duration",
|
|
107
|
+
) -> MetricAttributes:
|
|
108
|
+
"""Create privacy-safe request duration metric attributes for a completed FastAPI request."""
|
|
109
|
+
|
|
110
|
+
duration_value = float(duration_ms)
|
|
111
|
+
if duration_value < 0:
|
|
112
|
+
duration_value = 0.0
|
|
113
|
+
return {
|
|
114
|
+
"name": metric_name,
|
|
115
|
+
"kind": "histogram",
|
|
116
|
+
"value": duration_value,
|
|
117
|
+
"unit": "ms",
|
|
118
|
+
"temporality": "delta",
|
|
119
|
+
"metadata": {
|
|
120
|
+
"framework": "fastapi",
|
|
121
|
+
"method": request.method,
|
|
122
|
+
"routeTemplate": request_route_template(request),
|
|
123
|
+
"statusCode": status_code,
|
|
124
|
+
"statusCodeClass": status_code_class(status_code),
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def capture_request_metric(
|
|
130
|
+
client: LogBrewClient,
|
|
131
|
+
request: Request,
|
|
132
|
+
*,
|
|
133
|
+
status_code: int,
|
|
134
|
+
duration_ms: float,
|
|
135
|
+
event_id: str | None = None,
|
|
136
|
+
timestamp: str | None = None,
|
|
137
|
+
metric_name: str = "http.server.duration",
|
|
138
|
+
) -> str:
|
|
139
|
+
"""Capture a FastAPI request duration metric and return its event id."""
|
|
140
|
+
|
|
141
|
+
metric_event_id = event_id or f"evt_fastapi_metric_{uuid.uuid4().hex}"
|
|
142
|
+
client.metric(
|
|
143
|
+
metric_event_id,
|
|
144
|
+
timestamp or utc_timestamp(),
|
|
145
|
+
create_request_metric_attributes(
|
|
146
|
+
request,
|
|
147
|
+
status_code=status_code,
|
|
148
|
+
duration_ms=duration_ms,
|
|
149
|
+
metric_name=metric_name,
|
|
150
|
+
),
|
|
151
|
+
)
|
|
152
|
+
return metric_event_id
|
|
153
|
+
|
|
154
|
+
|
|
76
155
|
def capture_request_span(
|
|
77
156
|
client: LogBrewClient,
|
|
78
157
|
request: Request,
|
|
@@ -154,10 +233,12 @@ class LogBrewFastAPIMiddleware(BaseHTTPMiddleware):
|
|
|
154
233
|
client: LogBrewClient,
|
|
155
234
|
transport: RecordingTransport | None = None,
|
|
156
235
|
capture_successful_requests: bool = True,
|
|
236
|
+
capture_request_metrics: bool = False,
|
|
157
237
|
capture_exceptions: bool = True,
|
|
158
238
|
flush_on_response: bool = True,
|
|
159
239
|
raise_flush_errors: bool = False,
|
|
160
240
|
service_name: str = "fastapi",
|
|
241
|
+
request_metric_name: str = "http.server.duration",
|
|
161
242
|
span_id_factory: Callable[[], str] | None = None,
|
|
162
243
|
) -> None:
|
|
163
244
|
super().__init__(app)
|
|
@@ -165,10 +246,12 @@ class LogBrewFastAPIMiddleware(BaseHTTPMiddleware):
|
|
|
165
246
|
client=client,
|
|
166
247
|
transport=transport,
|
|
167
248
|
capture_successful_requests=capture_successful_requests,
|
|
249
|
+
capture_request_metrics=capture_request_metrics,
|
|
168
250
|
capture_exceptions=capture_exceptions,
|
|
169
251
|
flush_on_response=flush_on_response,
|
|
170
252
|
raise_flush_errors=raise_flush_errors,
|
|
171
253
|
service_name=service_name,
|
|
254
|
+
request_metric_name=request_metric_name,
|
|
172
255
|
span_id_factory=span_id_factory,
|
|
173
256
|
)
|
|
174
257
|
|
|
@@ -178,7 +261,8 @@ class LogBrewFastAPIMiddleware(BaseHTTPMiddleware):
|
|
|
178
261
|
response = await call_next(request)
|
|
179
262
|
except Exception as exc:
|
|
180
263
|
duration_ms = (time.perf_counter() - start) * 1000
|
|
181
|
-
|
|
264
|
+
should_capture_exception = self.config.capture_exceptions
|
|
265
|
+
if should_capture_exception:
|
|
182
266
|
capture_exception(self.config.client, request, exc)
|
|
183
267
|
capture_request_span(
|
|
184
268
|
self.config.client,
|
|
@@ -187,11 +271,21 @@ class LogBrewFastAPIMiddleware(BaseHTTPMiddleware):
|
|
|
187
271
|
duration_ms=duration_ms,
|
|
188
272
|
span_id_factory=self.config.span_id_factory,
|
|
189
273
|
)
|
|
274
|
+
if self.config.capture_request_metrics:
|
|
275
|
+
capture_request_metric(
|
|
276
|
+
self.config.client,
|
|
277
|
+
request,
|
|
278
|
+
status_code=500,
|
|
279
|
+
duration_ms=duration_ms,
|
|
280
|
+
metric_name=self.config.request_metric_name,
|
|
281
|
+
)
|
|
282
|
+
if should_capture_exception or self.config.capture_request_metrics:
|
|
190
283
|
self._flush_if_configured()
|
|
191
284
|
raise
|
|
192
285
|
|
|
193
286
|
duration_ms = (time.perf_counter() - start) * 1000
|
|
194
|
-
|
|
287
|
+
should_capture_request_span = self.config.capture_successful_requests or response.status_code >= 500
|
|
288
|
+
if should_capture_request_span:
|
|
195
289
|
capture_request_span(
|
|
196
290
|
self.config.client,
|
|
197
291
|
request,
|
|
@@ -199,6 +293,15 @@ class LogBrewFastAPIMiddleware(BaseHTTPMiddleware):
|
|
|
199
293
|
duration_ms=duration_ms,
|
|
200
294
|
span_id_factory=self.config.span_id_factory,
|
|
201
295
|
)
|
|
296
|
+
if self.config.capture_request_metrics:
|
|
297
|
+
capture_request_metric(
|
|
298
|
+
self.config.client,
|
|
299
|
+
request,
|
|
300
|
+
status_code=response.status_code,
|
|
301
|
+
duration_ms=duration_ms,
|
|
302
|
+
metric_name=self.config.request_metric_name,
|
|
303
|
+
)
|
|
304
|
+
if should_capture_request_span or self.config.capture_request_metrics:
|
|
202
305
|
self._flush_if_configured()
|
|
203
306
|
return response
|
|
204
307
|
|
|
@@ -218,10 +321,12 @@ def add_logbrew_middleware(
|
|
|
218
321
|
client: LogBrewClient,
|
|
219
322
|
transport: RecordingTransport | None = None,
|
|
220
323
|
capture_successful_requests: bool = True,
|
|
324
|
+
capture_request_metrics: bool = False,
|
|
221
325
|
capture_exceptions: bool = True,
|
|
222
326
|
flush_on_response: bool = True,
|
|
223
327
|
raise_flush_errors: bool = False,
|
|
224
328
|
service_name: str = "fastapi",
|
|
329
|
+
request_metric_name: str = "http.server.duration",
|
|
225
330
|
span_id_factory: Callable[[], str] | None = None,
|
|
226
331
|
) -> None:
|
|
227
332
|
"""Install LogBrew request/exception capture middleware on a FastAPI app."""
|
|
@@ -231,10 +336,12 @@ def add_logbrew_middleware(
|
|
|
231
336
|
client=client,
|
|
232
337
|
transport=transport,
|
|
233
338
|
capture_successful_requests=capture_successful_requests,
|
|
339
|
+
capture_request_metrics=capture_request_metrics,
|
|
234
340
|
capture_exceptions=capture_exceptions,
|
|
235
341
|
flush_on_response=flush_on_response,
|
|
236
342
|
raise_flush_errors=raise_flush_errors,
|
|
237
343
|
service_name=service_name,
|
|
344
|
+
request_metric_name=request_metric_name,
|
|
238
345
|
span_id_factory=span_id_factory,
|
|
239
346
|
)
|
|
240
347
|
|
|
@@ -251,8 +358,11 @@ __all__ = [
|
|
|
251
358
|
"LogBrewFastAPIMiddleware",
|
|
252
359
|
"add_logbrew_middleware",
|
|
253
360
|
"capture_exception",
|
|
361
|
+
"capture_request_metric",
|
|
254
362
|
"capture_request_span",
|
|
363
|
+
"create_request_metric_attributes",
|
|
255
364
|
"request_metadata",
|
|
256
365
|
"request_name",
|
|
366
|
+
"request_route_template",
|
|
257
367
|
"utc_timestamp",
|
|
258
368
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: logbrew-fastapi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: FastAPI integration for capturing LogBrew request spans and exceptions.
|
|
5
5
|
Author: LogBrew
|
|
6
6
|
License-Expression: MIT
|
|
@@ -23,6 +23,10 @@ Requires-Dist: logbrew-sdk<0.2.0,>=0.1.1
|
|
|
23
23
|
|
|
24
24
|
# logbrew-fastapi
|
|
25
25
|
|
|
26
|
+
<p align="center">
|
|
27
|
+
<img src="https://raw.githubusercontent.com/LogBrewCo/sdk/main/assets/brand/logbrew-logo-espresso-bg-512.png" alt="LogBrew logo" width="96" height="96">
|
|
28
|
+
</p>
|
|
29
|
+
|
|
26
30
|
FastAPI integration for capturing LogBrew request spans and exceptions with the public Python SDK.
|
|
27
31
|
|
|
28
32
|
## Install
|
|
@@ -64,6 +68,19 @@ def health() -> dict[str, bool]:
|
|
|
64
68
|
|
|
65
69
|
When an incoming request has a valid W3C `traceparent` header, request capture continues that trace by using the incoming `traceId` and parent span id while creating a fresh child span id. Missing or malformed `traceparent` headers keep the existing synthetic request span behavior so bad client headers do not break the app. Automatic metadata uses the request path without query text.
|
|
66
70
|
|
|
71
|
+
Request duration metrics are opt-in. Set `capture_request_metrics=True` to emit an explicit `http.server.duration` histogram for completed requests:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
add_logbrew_middleware(
|
|
75
|
+
app,
|
|
76
|
+
client=client,
|
|
77
|
+
transport=transport,
|
|
78
|
+
capture_request_metrics=True,
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The metric includes primitive, low-cardinality metadata: `framework`, `method`, `routeTemplate`, `statusCode`, and `statusCodeClass`. Query strings and URL hashes are omitted. Set `capture_successful_requests=False` with `capture_request_metrics=True` when you only want duration metrics and not successful request spans. Avoid user IDs, request payloads, headers, or free-form text in custom metric metadata.
|
|
83
|
+
|
|
67
84
|
By default, transport failures do not break the FastAPI response path. Set `raise_flush_errors=True` only when your app wants delivery failures to surface as request errors.
|
|
68
85
|
|
|
69
86
|
Use a clearly fake placeholder like `LOGBREW_API_KEY` in examples.
|
|
@@ -41,6 +41,44 @@ class FastAPIIntegrationTests(unittest.TestCase):
|
|
|
41
41
|
self.assertEqual(attributes["status"], "ok")
|
|
42
42
|
self.assertEqual(attributes["metadata"]["status_code"], 200)
|
|
43
43
|
|
|
44
|
+
def test_request_metrics_can_be_captured_without_request_spans(self) -> None:
|
|
45
|
+
sdk_client = make_client()
|
|
46
|
+
transport = RecordingTransport.always_accept()
|
|
47
|
+
app = FastAPI()
|
|
48
|
+
add_logbrew_middleware(
|
|
49
|
+
app,
|
|
50
|
+
client=sdk_client,
|
|
51
|
+
transport=transport,
|
|
52
|
+
capture_successful_requests=False,
|
|
53
|
+
capture_request_metrics=True,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
@app.get("/orders/{order_id}")
|
|
57
|
+
def order_detail(order_id: int) -> dict[str, int]:
|
|
58
|
+
return {"orderId": order_id}
|
|
59
|
+
|
|
60
|
+
with TestClient(app) as http:
|
|
61
|
+
response = http.get("/orders/42?debug=true#receipt")
|
|
62
|
+
|
|
63
|
+
self.assertEqual(response.status_code, 200)
|
|
64
|
+
self.assertEqual(sdk_client.pending_events(), 0)
|
|
65
|
+
self.assertEqual(len(transport.sent_bodies), 1)
|
|
66
|
+
payload = json.loads(transport.sent_bodies[0])
|
|
67
|
+
self.assertEqual([event["type"] for event in payload["events"]], ["metric"])
|
|
68
|
+
metric = payload["events"][0]["attributes"]
|
|
69
|
+
self.assertEqual(metric["name"], "http.server.duration")
|
|
70
|
+
self.assertEqual(metric["kind"], "histogram")
|
|
71
|
+
self.assertGreaterEqual(metric["value"], 0)
|
|
72
|
+
self.assertEqual(metric["unit"], "ms")
|
|
73
|
+
self.assertEqual(metric["temporality"], "delta")
|
|
74
|
+
metadata = metric["metadata"]
|
|
75
|
+
self.assertEqual(metadata["framework"], "fastapi")
|
|
76
|
+
self.assertEqual(metadata["method"], "GET")
|
|
77
|
+
self.assertEqual(metadata["routeTemplate"], "/orders/{order_id}")
|
|
78
|
+
self.assertEqual(metadata["statusCode"], 200)
|
|
79
|
+
self.assertEqual(metadata["statusCodeClass"], "2xx")
|
|
80
|
+
self.assertNotIn("debug", json.dumps(metadata))
|
|
81
|
+
|
|
44
82
|
def test_valid_traceparent_continues_request_span(self) -> None:
|
|
45
83
|
sdk_client = make_client()
|
|
46
84
|
transport = RecordingTransport.always_accept()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi/examples/readme_example.py
RENAMED
|
File without changes
|
{logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi/examples/real_user_smoke.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{logbrew_fastapi-0.1.1 → logbrew_fastapi-0.1.2}/src/logbrew_fastapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|