kleinkram 0.44.0.dev20250409080532__tar.gz → 0.44.1.dev20250409111712__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.
Potentially problematic release.
This version of kleinkram might be problematic. Click here for more details.
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/PKG-INFO +1 -1
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/file_transfer.py +67 -17
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram.egg-info/PKG-INFO +1 -1
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/setup.cfg +1 -1
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/README.md +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/__init__.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/__main__.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/_version.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/__init__.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/client.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/deser.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/pagination.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/query.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/routes.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/auth.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/__init__.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_download.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_endpoint.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_file.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_list.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_mission.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_project.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_upload.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_verify.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/app.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/error_handling.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/config.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/core.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/errors.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/main.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/models.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/printing.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/py.typed +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/types.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/utils.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/wrappers.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram.egg-info/SOURCES.txt +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram.egg-info/dependency_links.txt +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram.egg-info/entry_points.txt +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram.egg-info/requires.txt +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram.egg-info/top_level.txt +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/pyproject.toml +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/requirements.txt +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/setup.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/testing/__init__.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/testing/backend_fixtures.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/__init__.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/conftest.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_config.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_core.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_end_to_end.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_error_handling.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_fixtures.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_printing.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_query.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_utils.py +0 -0
- {kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_wrappers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kleinkram
|
|
3
|
-
Version: 0.44.
|
|
3
|
+
Version: 0.44.1.dev20250409111712
|
|
4
4
|
Summary: give me your bags
|
|
5
5
|
Author: Cyrill Püntener, Dominique Garmier, Johann Schwabe
|
|
6
6
|
Author-email: pucyril@ethz.ch, dgarmier@ethz.ch, jschwab@ethz.ch
|
|
@@ -17,6 +17,7 @@ from uuid import UUID
|
|
|
17
17
|
import boto3.s3.transfer
|
|
18
18
|
import botocore.config
|
|
19
19
|
import httpx
|
|
20
|
+
from httpx import RemoteProtocolError
|
|
20
21
|
from rich.console import Console
|
|
21
22
|
from tqdm import tqdm
|
|
22
23
|
|
|
@@ -44,6 +45,9 @@ MAX_UPLOAD_RETRIES = 3
|
|
|
44
45
|
S3_MAX_RETRIES = 60 # same as frontend
|
|
45
46
|
S3_READ_TIMEOUT = 60 * 5 # 5 minutes
|
|
46
47
|
|
|
48
|
+
RETRY_BACKOFF_BASE = 2 # exponential backoff base
|
|
49
|
+
MAX_RETRIES = 5
|
|
50
|
+
|
|
47
51
|
|
|
48
52
|
class UploadCredentials(NamedTuple):
|
|
49
53
|
access_key: str
|
|
@@ -264,23 +268,69 @@ def _get_file_download(client: AuthenticatedClient, id: UUID) -> str:
|
|
|
264
268
|
def _url_download(
|
|
265
269
|
url: str, *, path: Path, size: int, overwrite: bool = False, verbose: bool = False
|
|
266
270
|
) -> None:
|
|
267
|
-
if path.exists()
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
271
|
+
if path.exists():
|
|
272
|
+
if overwrite:
|
|
273
|
+
path.unlink()
|
|
274
|
+
downloaded = 0
|
|
275
|
+
else:
|
|
276
|
+
downloaded = path.stat().st_size
|
|
277
|
+
if downloaded >= size:
|
|
278
|
+
raise FileExistsError(f"file already exists and is complete: {path}")
|
|
279
|
+
else:
|
|
280
|
+
downloaded = 0
|
|
281
|
+
|
|
282
|
+
attempt = 0
|
|
283
|
+
while downloaded < size:
|
|
284
|
+
try:
|
|
285
|
+
headers = {"Range": f"bytes={downloaded}-"}
|
|
286
|
+
with httpx.stream(
|
|
287
|
+
"GET", url, headers=headers, timeout=S3_READ_TIMEOUT
|
|
288
|
+
) as response:
|
|
289
|
+
# Accept both 206 Partial Content and 200 OK if starting from 0
|
|
290
|
+
if not (
|
|
291
|
+
response.status_code == 206
|
|
292
|
+
or (downloaded == 0 and response.status_code == 200)
|
|
293
|
+
):
|
|
294
|
+
response.raise_for_status()
|
|
295
|
+
raise RuntimeError(
|
|
296
|
+
f"Expected 206 Partial Content, got {response.status_code}"
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
mode = "ab" if downloaded > 0 else "wb"
|
|
300
|
+
with open(path, mode) as f:
|
|
301
|
+
with tqdm(
|
|
302
|
+
total=size,
|
|
303
|
+
initial=downloaded,
|
|
304
|
+
desc=f"downloading {path.name}",
|
|
305
|
+
unit="B",
|
|
306
|
+
unit_scale=True,
|
|
307
|
+
leave=False,
|
|
308
|
+
disable=not verbose,
|
|
309
|
+
) as pbar:
|
|
310
|
+
for chunk in response.iter_bytes(
|
|
311
|
+
chunk_size=DOWNLOAD_CHUNK_SIZE
|
|
312
|
+
):
|
|
313
|
+
attempt = 0 # reset attempt counter on successful download of non-empty chunk
|
|
314
|
+
if not chunk:
|
|
315
|
+
break
|
|
316
|
+
f.write(chunk)
|
|
317
|
+
downloaded += len(chunk)
|
|
318
|
+
pbar.update(len(chunk))
|
|
319
|
+
break # download complete
|
|
320
|
+
except RemoteProtocolError as e:
|
|
321
|
+
logger.info(f"Error: {e}, retrying...")
|
|
322
|
+
attempt += 1
|
|
323
|
+
if attempt > MAX_RETRIES:
|
|
324
|
+
raise RuntimeError(
|
|
325
|
+
f"Download failed after {MAX_RETRIES} retries due to RemoteProtocolError"
|
|
326
|
+
) from e
|
|
327
|
+
if verbose:
|
|
328
|
+
print(
|
|
329
|
+
f"RemoteProtocolError on attempt {attempt}/{MAX_RETRIES}, retrying after backoff..."
|
|
330
|
+
)
|
|
331
|
+
sleep(RETRY_BACKOFF_BASE**attempt)
|
|
332
|
+
except Exception as e:
|
|
333
|
+
raise RuntimeError(f"Failed to download: {e}") from e
|
|
284
334
|
|
|
285
335
|
|
|
286
336
|
class DownloadState(Enum):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kleinkram
|
|
3
|
-
Version: 0.44.
|
|
3
|
+
Version: 0.44.1.dev20250409111712
|
|
4
4
|
Summary: give me your bags
|
|
5
5
|
Author: Cyrill Püntener, Dominique Garmier, Johann Schwabe
|
|
6
6
|
Author-email: pucyril@ethz.ch, dgarmier@ethz.ch, jschwab@ethz.ch
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/__init__.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/__main__.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/_version.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/__init__.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/client.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/deser.py
RENAMED
|
File without changes
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/query.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/api/routes.py
RENAMED
|
File without changes
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/__init__.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_download.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_endpoint.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_file.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_list.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_mission.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_project.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_upload.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/_verify.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/cli/app.py
RENAMED
|
File without changes
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/config.py
RENAMED
|
File without changes
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/errors.py
RENAMED
|
File without changes
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/models.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/printing.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/py.typed
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/types.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/utils.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/kleinkram/wrappers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/testing/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_config.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_core.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_end_to_end.py
RENAMED
|
File without changes
|
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_fixtures.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_printing.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_query.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_utils.py
RENAMED
|
File without changes
|
{kleinkram-0.44.0.dev20250409080532 → kleinkram-0.44.1.dev20250409111712}/tests/test_wrappers.py
RENAMED
|
File without changes
|