apitally 0.17.0__py3-none-any.whl → 0.18.1__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.
- apitally/starlette.py +12 -1
- {apitally-0.17.0.dist-info → apitally-0.18.1.dist-info}/METADATA +2 -3
- {apitally-0.17.0.dist-info → apitally-0.18.1.dist-info}/RECORD +5 -5
- {apitally-0.17.0.dist-info → apitally-0.18.1.dist-info}/WHEEL +0 -0
- {apitally-0.17.0.dist-info → apitally-0.18.1.dist-info}/licenses/LICENSE +0 -0
apitally/starlette.py
CHANGED
@@ -38,12 +38,14 @@ class ApitallyMiddleware:
|
|
38
38
|
app_version: Optional[str] = None,
|
39
39
|
openapi_url: Optional[str] = "/openapi.json",
|
40
40
|
identify_consumer_callback: Optional[Callable[[Request], Union[str, ApitallyConsumer, None]]] = None,
|
41
|
+
capture_client_disconnects: bool = False,
|
41
42
|
proxy: Optional[Union[str, Proxy]] = None,
|
42
43
|
) -> None:
|
43
44
|
self.app = app
|
44
45
|
self.app_version = app_version
|
45
46
|
self.openapi_url = openapi_url
|
46
47
|
self.identify_consumer_callback = identify_consumer_callback
|
48
|
+
self.capture_client_disconnects = capture_client_disconnects
|
47
49
|
self.client = ApitallyClient(
|
48
50
|
client_id=client_id,
|
49
51
|
env=env,
|
@@ -72,7 +74,7 @@ class ApitallyMiddleware:
|
|
72
74
|
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
|
73
75
|
if self.client.enabled and scope["type"] == "http" and scope["method"] != "OPTIONS":
|
74
76
|
timestamp = time.time()
|
75
|
-
request = Request(scope)
|
77
|
+
request = Request(scope, receive, send)
|
76
78
|
request_size = parse_int(request.headers.get("Content-Length"))
|
77
79
|
request_body = b""
|
78
80
|
request_body_too_large = request_size is not None and request_size > MAX_BODY_SIZE
|
@@ -89,6 +91,7 @@ class ApitallyMiddleware:
|
|
89
91
|
|
90
92
|
async def receive_wrapper() -> Message:
|
91
93
|
nonlocal request_body, request_body_too_large
|
94
|
+
|
92
95
|
message = await receive()
|
93
96
|
if message["type"] == "http.request" and self.capture_request_body and not request_body_too_large:
|
94
97
|
request_body += message.get("body", b"")
|
@@ -107,6 +110,7 @@ class ApitallyMiddleware:
|
|
107
110
|
response_chunked, \
|
108
111
|
response_content_type, \
|
109
112
|
response_size
|
113
|
+
|
110
114
|
if message["type"] == "http.response.start":
|
111
115
|
response_time = time.perf_counter() - start_time
|
112
116
|
response_status = message["status"]
|
@@ -118,9 +122,11 @@ class ApitallyMiddleware:
|
|
118
122
|
response_content_type = response_headers.get("Content-Type")
|
119
123
|
response_size = parse_int(response_headers.get("Content-Length")) if not response_chunked else 0
|
120
124
|
response_body_too_large = response_size is not None and response_size > MAX_BODY_SIZE
|
125
|
+
|
121
126
|
elif message["type"] == "http.response.body":
|
122
127
|
if response_chunked and response_size is not None:
|
123
128
|
response_size += len(message.get("body", b""))
|
129
|
+
|
124
130
|
if (
|
125
131
|
(self.capture_response_body or response_status == 422)
|
126
132
|
and RequestLogger.is_supported_content_type(response_content_type)
|
@@ -130,6 +136,11 @@ class ApitallyMiddleware:
|
|
130
136
|
if len(response_body) > MAX_BODY_SIZE:
|
131
137
|
response_body_too_large = True
|
132
138
|
response_body = b""
|
139
|
+
|
140
|
+
if self.capture_client_disconnects and await request.is_disconnected():
|
141
|
+
# Client closed connection (report NGINX specific status code)
|
142
|
+
response_status = 499
|
143
|
+
|
133
144
|
await send(message)
|
134
145
|
|
135
146
|
try:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: apitally
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.18.1
|
4
4
|
Summary: Simple API monitoring & analytics for REST APIs built with FastAPI, Flask, Django, Starlette, Litestar and BlackSheep.
|
5
5
|
Project-URL: Homepage, https://apitally.io
|
6
6
|
Project-URL: Documentation, https://docs.apitally.io
|
@@ -19,7 +19,6 @@ Classifier: License :: OSI Approved :: MIT License
|
|
19
19
|
Classifier: Programming Language :: Python
|
20
20
|
Classifier: Programming Language :: Python :: 3
|
21
21
|
Classifier: Programming Language :: Python :: 3 :: Only
|
22
|
-
Classifier: Programming Language :: Python :: 3.8
|
23
22
|
Classifier: Programming Language :: Python :: 3.9
|
24
23
|
Classifier: Programming Language :: Python :: 3.10
|
25
24
|
Classifier: Programming Language :: Python :: 3.11
|
@@ -31,7 +30,7 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
|
|
31
30
|
Classifier: Topic :: Software Development
|
32
31
|
Classifier: Topic :: System :: Monitoring
|
33
32
|
Classifier: Typing :: Typed
|
34
|
-
Requires-Python: <4.0,>=3.
|
33
|
+
Requires-Python: <4.0,>=3.9
|
35
34
|
Requires-Dist: backoff>=2.0.0
|
36
35
|
Provides-Extra: blacksheep
|
37
36
|
Requires-Dist: blacksheep>=2; extra == 'blacksheep'
|
@@ -8,7 +8,7 @@ apitally/fastapi.py,sha256=IfKfgsmIY8_AtnuMTW2sW4qnkya61CAE2vBoIpcc9tk,169
|
|
8
8
|
apitally/flask.py,sha256=OoCEnjtnD51GUGq-adK80ebuiLj-5HXubxffCv5XTCM,9622
|
9
9
|
apitally/litestar.py,sha256=mHoMqBO_gyoopeHljY8e8GTcV29UDf3uhQMxY3GeNpA,13451
|
10
10
|
apitally/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
-
apitally/starlette.py,sha256=
|
11
|
+
apitally/starlette.py,sha256=Ep7n_yAqoleFpuLk43kMONiFJVRsFsu-G2_TIjfiCHQ,13878
|
12
12
|
apitally/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
apitally/client/client_asyncio.py,sha256=rTsH5wlLHK3RmyIuEiT6vzjquU-l2OPC34JnC2U6uYw,6658
|
14
14
|
apitally/client/client_base.py,sha256=DvivGeHd3dyOASRvkIo44Zh8RzdBMfH8_rROa2lFbgw,3799
|
@@ -20,7 +20,7 @@ apitally/client/requests.py,sha256=SDptGOg9XvaEKFj2o3oxJz-JAuZzUrqpHnbOQixf99o,3
|
|
20
20
|
apitally/client/sentry.py,sha256=qMjHdI0V7c50ruo1WjmjWc8g6oGDv724vSCvcuZ8G9k,1188
|
21
21
|
apitally/client/server_errors.py,sha256=4B2BKDFoIpoWc55UVH6AIdYSgzj6zxCdMNUW77JjhZw,3423
|
22
22
|
apitally/client/validation_errors.py,sha256=6G8WYWFgJs9VH9swvkPXJGuOJgymj5ooWA9OwjUTbuM,1964
|
23
|
-
apitally-0.
|
24
|
-
apitally-0.
|
25
|
-
apitally-0.
|
26
|
-
apitally-0.
|
23
|
+
apitally-0.18.1.dist-info/METADATA,sha256=tlmfFn2vb-x63umo1V3lkZGHPWkB_A-Z6eGk9e5C2nI,9271
|
24
|
+
apitally-0.18.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
25
|
+
apitally-0.18.1.dist-info/licenses/LICENSE,sha256=vbLzC-4TddtXX-_AFEBKMYWRlxC_MN0g66QhPxo8PgY,1065
|
26
|
+
apitally-0.18.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|