port-ocean 0.25.3__py3-none-any.whl → 0.25.5__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.
- port_ocean/helpers/retry.py +68 -1
- {port_ocean-0.25.3.dist-info → port_ocean-0.25.5.dist-info}/METADATA +2 -1
- {port_ocean-0.25.3.dist-info → port_ocean-0.25.5.dist-info}/RECORD +6 -6
- {port_ocean-0.25.3.dist-info → port_ocean-0.25.5.dist-info}/LICENSE.md +0 -0
- {port_ocean-0.25.3.dist-info → port_ocean-0.25.5.dist-info}/WHEEL +0 -0
- {port_ocean-0.25.3.dist-info → port_ocean-0.25.5.dist-info}/entry_points.txt +0 -0
port_ocean/helpers/retry.py
CHANGED
@@ -4,9 +4,10 @@ import time
|
|
4
4
|
from datetime import datetime
|
5
5
|
from functools import partial
|
6
6
|
from http import HTTPStatus
|
7
|
-
from typing import Any, Callable, Coroutine, Iterable, Mapping, Union
|
7
|
+
from typing import Any, Callable, Coroutine, Iterable, Mapping, Union, cast
|
8
8
|
import httpx
|
9
9
|
from dateutil.parser import isoparse
|
10
|
+
import logging
|
10
11
|
|
11
12
|
_ON_RETRY_CALLBACK: Callable[[httpx.Request], httpx.Request] | None = None
|
12
13
|
|
@@ -148,6 +149,9 @@ class RetryTransport(httpx.AsyncBaseTransport, httpx.BaseTransport):
|
|
148
149
|
response = self._retry_operation(request, send_method)
|
149
150
|
else:
|
150
151
|
response = transport.handle_request(request)
|
152
|
+
|
153
|
+
self._log_response_size(request, response)
|
154
|
+
|
151
155
|
return response
|
152
156
|
except Exception as e:
|
153
157
|
if not self._is_retryable_method(request) and self._logger is not None:
|
@@ -172,6 +176,8 @@ class RetryTransport(httpx.AsyncBaseTransport, httpx.BaseTransport):
|
|
172
176
|
else:
|
173
177
|
response = await transport.handle_async_request(request)
|
174
178
|
|
179
|
+
await self._log_response_size_async(request, response)
|
180
|
+
|
175
181
|
return response
|
176
182
|
except Exception as e:
|
177
183
|
# Retyable methods are logged via _log_error
|
@@ -246,6 +252,67 @@ class RetryTransport(httpx.AsyncBaseTransport, httpx.BaseTransport):
|
|
246
252
|
f" {type(error).__name__} - {str(error) or 'No error message'}, retrying in {sleep_time} seconds."
|
247
253
|
)
|
248
254
|
|
255
|
+
def _should_log_response_size(self, request: httpx.Request) -> bool:
|
256
|
+
return self._logger is not None and not request.url.host.endswith("getport.io")
|
257
|
+
|
258
|
+
def _get_content_length(self, response: httpx.Response) -> int | None:
|
259
|
+
content_length = response.headers.get("Content-Length") or response.headers.get(
|
260
|
+
"content-length"
|
261
|
+
)
|
262
|
+
if content_length:
|
263
|
+
return int(content_length)
|
264
|
+
return None
|
265
|
+
|
266
|
+
async def _log_response_size_async(
|
267
|
+
self, request: httpx.Request, response: httpx.Response
|
268
|
+
) -> None:
|
269
|
+
"""Log the size of the response."""
|
270
|
+
if not self._should_log_response_size(request):
|
271
|
+
return
|
272
|
+
|
273
|
+
# Try to get content length from headers first
|
274
|
+
content_length = self._get_content_length(response)
|
275
|
+
if content_length is not None:
|
276
|
+
size_info = content_length
|
277
|
+
else:
|
278
|
+
# If no Content-Length header, try to get actual content size
|
279
|
+
try:
|
280
|
+
actual_size = len(await response.aread())
|
281
|
+
size_info = actual_size
|
282
|
+
except Exception as e:
|
283
|
+
cast(logging.Logger, self._logger).error(
|
284
|
+
f"Error getting response size: {e}"
|
285
|
+
)
|
286
|
+
return
|
287
|
+
|
288
|
+
cast(logging.Logger, self._logger).info(
|
289
|
+
f"Response for {request.method} {request.url} - Size: {size_info} bytes"
|
290
|
+
)
|
291
|
+
|
292
|
+
def _log_response_size(
|
293
|
+
self, request: httpx.Request, response: httpx.Response
|
294
|
+
) -> None:
|
295
|
+
if not self._should_log_response_size(request):
|
296
|
+
return
|
297
|
+
|
298
|
+
content_length = self._get_content_length(response)
|
299
|
+
if content_length is not None:
|
300
|
+
size_info = content_length
|
301
|
+
else:
|
302
|
+
# If no Content-Length header, try to get actual content size
|
303
|
+
try:
|
304
|
+
actual_size = len(response.read())
|
305
|
+
size_info = actual_size
|
306
|
+
except Exception as e:
|
307
|
+
cast(logging.Logger, self._logger).error(
|
308
|
+
f"Error getting response size: {e}"
|
309
|
+
)
|
310
|
+
return
|
311
|
+
|
312
|
+
cast(logging.Logger, self._logger).info(
|
313
|
+
f"Response for {request.method} {request.url} - Size: {size_info} bytes"
|
314
|
+
)
|
315
|
+
|
249
316
|
async def _should_retry_async(self, response: httpx.Response) -> bool:
|
250
317
|
return response.status_code in self._retry_status_codes
|
251
318
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: port-ocean
|
3
|
-
Version: 0.25.
|
3
|
+
Version: 0.25.5
|
4
4
|
Summary: Port Ocean is a CLI tool for managing your Port projects.
|
5
5
|
Home-page: https://app.getport.io
|
6
6
|
Keywords: ocean,port-ocean,port
|
@@ -28,6 +28,7 @@ Requires-Dist: confluent-kafka (>=2.10.1,<3.0.0)
|
|
28
28
|
Requires-Dist: cookiecutter (>=2.1.1,<3.0.0) ; extra == "cli"
|
29
29
|
Requires-Dist: fastapi (>=0.115.3,<0.116.0)
|
30
30
|
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
31
|
+
Requires-Dist: jinja2 (>=3.1.6)
|
31
32
|
Requires-Dist: jinja2-time (>=0.2.0,<0.3.0) ; extra == "cli"
|
32
33
|
Requires-Dist: jq (>=1.8.0,<2.0.0)
|
33
34
|
Requires-Dist: loguru (>=0.7.0,<0.8.0)
|
@@ -142,7 +142,7 @@ port_ocean/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
142
142
|
port_ocean/helpers/async_client.py,sha256=0MkFY46MuEYkju7gJ8HYeUTMBsjwAzESvATryJy2DaM,1698
|
143
143
|
port_ocean/helpers/metric/metric.py,sha256=Aacz7bOd8ZCwEPpXAdwLbKRXf28Z4wiViG_GXiV_xWg,14529
|
144
144
|
port_ocean/helpers/metric/utils.py,sha256=1lAgrxnZLuR_wUNDyPOPzLrm32b8cDdioob2lvnPQ1A,1619
|
145
|
-
port_ocean/helpers/retry.py,sha256=
|
145
|
+
port_ocean/helpers/retry.py,sha256=VHAp6j9-Vid6aNR5sca3S0aW6b1S2oYw9vT9hi1N22U,18556
|
146
146
|
port_ocean/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
147
147
|
port_ocean/log/handlers.py,sha256=ncVjgqrZRh6BhyRrA6DQG86Wsbxph1yWYuEC0cWfe-Q,3631
|
148
148
|
port_ocean/log/logger_setup.py,sha256=0K3zVG0YYrYOWEV8-rCGks1o-bMRxgHXlqawu9w_tSw,2656
|
@@ -203,8 +203,8 @@ port_ocean/utils/repeat.py,sha256=U2OeCkHPWXmRTVoPV-VcJRlQhcYqPWI5NfmPlb1JIbc,32
|
|
203
203
|
port_ocean/utils/signal.py,sha256=mMVq-1Ab5YpNiqN4PkiyTGlV_G0wkUDMMjTZp5z3pb0,1514
|
204
204
|
port_ocean/utils/time.py,sha256=pufAOH5ZQI7gXvOvJoQXZXZJV-Dqktoj9Qp9eiRwmJ4,1939
|
205
205
|
port_ocean/version.py,sha256=UsuJdvdQlazzKGD3Hd5-U7N69STh8Dq9ggJzQFnu9fU,177
|
206
|
-
port_ocean-0.25.
|
207
|
-
port_ocean-0.25.
|
208
|
-
port_ocean-0.25.
|
209
|
-
port_ocean-0.25.
|
210
|
-
port_ocean-0.25.
|
206
|
+
port_ocean-0.25.5.dist-info/LICENSE.md,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
207
|
+
port_ocean-0.25.5.dist-info/METADATA,sha256=z6eqWLmVOCtooAj5NDNhgK76ZNsAtBXWufhYAz2ee80,6887
|
208
|
+
port_ocean-0.25.5.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
209
|
+
port_ocean-0.25.5.dist-info/entry_points.txt,sha256=F_DNUmGZU2Kme-8NsWM5LLE8piGMafYZygRYhOVtcjA,54
|
210
|
+
port_ocean-0.25.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|