kleinkram 0.39.0.dev20250224101424__py3-none-any.whl → 0.40.0.dev20250226155726__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.
Potentially problematic release.
This version of kleinkram might be problematic. Click here for more details.
- kleinkram/api/client.py +3 -1
- kleinkram/cli/app.py +10 -0
- kleinkram/config.py +4 -2
- kleinkram/printing.py +33 -10
- kleinkram/utils.py +1 -4
- {kleinkram-0.39.0.dev20250224101424.dist-info → kleinkram-0.40.0.dev20250226155726.dist-info}/METADATA +1 -1
- {kleinkram-0.39.0.dev20250224101424.dist-info → kleinkram-0.40.0.dev20250226155726.dist-info}/RECORD +11 -11
- {kleinkram-0.39.0.dev20250224101424.dist-info → kleinkram-0.40.0.dev20250226155726.dist-info}/WHEEL +1 -1
- tests/test_printing.py +11 -0
- {kleinkram-0.39.0.dev20250224101424.dist-info → kleinkram-0.40.0.dev20250226155726.dist-info}/entry_points.txt +0 -0
- {kleinkram-0.39.0.dev20250224101424.dist-info → kleinkram-0.40.0.dev20250226155726.dist-info}/top_level.txt +0 -0
kleinkram/api/client.py
CHANGED
|
@@ -148,7 +148,9 @@ class AuthenticatedClient(httpx.Client):
|
|
|
148
148
|
raise NotAuthenticated
|
|
149
149
|
|
|
150
150
|
logger.info(f"retrying request {method} {full_url}")
|
|
151
|
-
resp = super().request(
|
|
151
|
+
resp = super().request(
|
|
152
|
+
method, full_url, params=httpx_params, *args, **kwargs
|
|
153
|
+
)
|
|
152
154
|
logger.info(f"got response {resp}")
|
|
153
155
|
return resp
|
|
154
156
|
else:
|
kleinkram/cli/app.py
CHANGED
|
@@ -29,6 +29,7 @@ from kleinkram.cli._upload import upload_typer
|
|
|
29
29
|
from kleinkram.cli._verify import verify_typer
|
|
30
30
|
from kleinkram.cli.error_handling import ErrorHandledTyper
|
|
31
31
|
from kleinkram.cli.error_handling import display_error
|
|
32
|
+
from kleinkram.config import MAX_TABLE_SIZE
|
|
32
33
|
from kleinkram.config import Config
|
|
33
34
|
from kleinkram.config import check_config_compatibility
|
|
34
35
|
from kleinkram.config import get_config
|
|
@@ -179,6 +180,11 @@ def cli(
|
|
|
179
180
|
None, "--version", "-v", callback=_version_callback
|
|
180
181
|
),
|
|
181
182
|
log_level: Optional[LogLevel] = typer.Option(None, help="Set log level."),
|
|
183
|
+
max_lines: int = typer.Option(
|
|
184
|
+
MAX_TABLE_SIZE,
|
|
185
|
+
"--max-lines",
|
|
186
|
+
help="Maximum number of lines when pretty printing tables. -1 for unlimited.",
|
|
187
|
+
),
|
|
182
188
|
):
|
|
183
189
|
if not check_config_compatibility():
|
|
184
190
|
typer.confirm("found incompatible config file, overwrite?", abort=True)
|
|
@@ -189,6 +195,10 @@ def cli(
|
|
|
189
195
|
shared_state.verbose = verbose
|
|
190
196
|
shared_state.debug = debug
|
|
191
197
|
|
|
198
|
+
if max_lines < 0 and max_lines != -1:
|
|
199
|
+
raise typer.BadParameter("`--max-lines` must be -1 or positive")
|
|
200
|
+
shared_state.max_table_size = max_lines
|
|
201
|
+
|
|
192
202
|
if shared_state.debug and log_level is None:
|
|
193
203
|
log_level = LogLevel.DEBUG
|
|
194
204
|
if log_level is None:
|
kleinkram/config.py
CHANGED
|
@@ -28,6 +28,7 @@ from kleinkram._version import __version__
|
|
|
28
28
|
logger = logging.getLogger(__name__)
|
|
29
29
|
|
|
30
30
|
CONFIG_PATH = Path().home() / ".kleinkram.json"
|
|
31
|
+
MAX_TABLE_SIZE = 256
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
class Environment(Enum):
|
|
@@ -74,8 +75,8 @@ def get_env() -> Environment:
|
|
|
74
75
|
|
|
75
76
|
|
|
76
77
|
ACTION_API_KEY = "KLEINKRAM_API_KEY"
|
|
77
|
-
ACTION_API = "
|
|
78
|
-
ACTION_S3 = "
|
|
78
|
+
ACTION_API = "KLEINKRAM_API_ENDPOINT"
|
|
79
|
+
ACTION_S3 = "KLEINKRAM_S3_ENDPOINT"
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
def _get_endpoint_from_action_env_vars() -> Optional[Endpoint]:
|
|
@@ -245,6 +246,7 @@ class SharedState:
|
|
|
245
246
|
log_file: Optional[Path] = None
|
|
246
247
|
verbose: bool = True
|
|
247
248
|
debug: bool = False
|
|
249
|
+
max_table_size: int = MAX_TABLE_SIZE
|
|
248
250
|
|
|
249
251
|
|
|
250
252
|
SHARED_STATE = SharedState()
|
kleinkram/printing.py
CHANGED
|
@@ -17,6 +17,7 @@ from rich.console import Console
|
|
|
17
17
|
from rich.table import Table
|
|
18
18
|
from rich.text import Text
|
|
19
19
|
|
|
20
|
+
from kleinkram.config import get_shared_state
|
|
20
21
|
from kleinkram.core import FileVerificationStatus
|
|
21
22
|
from kleinkram.models import File
|
|
22
23
|
from kleinkram.models import FileState
|
|
@@ -46,6 +47,11 @@ FILE_VERIFICATION_STATUS_STYLES = {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
|
|
50
|
+
def _add_placeholder_row(table: Table, skipped: int) -> None:
|
|
51
|
+
first_column = f"... ({skipped} more)"
|
|
52
|
+
table.add_row(first_column, *["..." for _ in range(len(table.columns) - 1)])
|
|
53
|
+
|
|
54
|
+
|
|
49
55
|
def file_state_to_text(file_state: FileState) -> Text:
|
|
50
56
|
return Text(file_state.value, style=FILE_STATE_COLOR[file_state])
|
|
51
57
|
|
|
@@ -114,8 +120,11 @@ def projects_to_table(projects: Sequence[Project]) -> Table:
|
|
|
114
120
|
table.add_column("name")
|
|
115
121
|
table.add_column("description")
|
|
116
122
|
|
|
117
|
-
|
|
123
|
+
max_table_size = get_shared_state().max_table_size
|
|
124
|
+
for project in projects[:max_table_size]:
|
|
118
125
|
table.add_row(str(project.id), project.name, project.description)
|
|
126
|
+
if len(projects) > max_table_size:
|
|
127
|
+
_add_placeholder_row(table, skipped=len(projects) - max_table_size)
|
|
119
128
|
return table
|
|
120
129
|
|
|
121
130
|
|
|
@@ -136,10 +145,11 @@ def missions_to_table(missions: Sequence[Mission]) -> Table:
|
|
|
136
145
|
if not missions_tp:
|
|
137
146
|
return table
|
|
138
147
|
last_project: Optional[str] = None
|
|
139
|
-
|
|
148
|
+
max_table_size = get_shared_state().max_table_size
|
|
149
|
+
for project, _, mission in missions_tp[:max_table_size]:
|
|
140
150
|
# add delimiter row if project changes
|
|
141
151
|
if last_project is not None and last_project != project:
|
|
142
|
-
table.
|
|
152
|
+
table.add_section()
|
|
143
153
|
last_project = project
|
|
144
154
|
|
|
145
155
|
table.add_row(
|
|
@@ -149,6 +159,9 @@ def missions_to_table(missions: Sequence[Mission]) -> Table:
|
|
|
149
159
|
str(mission.number_of_files),
|
|
150
160
|
format_bytes(mission.size),
|
|
151
161
|
)
|
|
162
|
+
|
|
163
|
+
if len(missions_tp) > max_table_size:
|
|
164
|
+
_add_placeholder_row(table, skipped=len(missions_tp) - max_table_size)
|
|
152
165
|
return table
|
|
153
166
|
|
|
154
167
|
|
|
@@ -174,9 +187,10 @@ def files_to_table(
|
|
|
174
187
|
return table
|
|
175
188
|
|
|
176
189
|
last_mission: Optional[str] = None
|
|
177
|
-
|
|
190
|
+
max_table_size = get_shared_state().max_table_size
|
|
191
|
+
for _, mission, _, file in files_tp[:max_table_size]:
|
|
178
192
|
if last_mission is not None and last_mission != mission and delimiters:
|
|
179
|
-
table.
|
|
193
|
+
table.add_section()
|
|
180
194
|
last_mission = mission
|
|
181
195
|
|
|
182
196
|
table.add_row(
|
|
@@ -188,6 +202,10 @@ def files_to_table(
|
|
|
188
202
|
format_bytes(file.size),
|
|
189
203
|
", ".join(file.categories),
|
|
190
204
|
)
|
|
205
|
+
|
|
206
|
+
if len(files_tp) > max_table_size:
|
|
207
|
+
_add_placeholder_row(table, skipped=len(files_tp) - max_table_size)
|
|
208
|
+
|
|
191
209
|
return table
|
|
192
210
|
|
|
193
211
|
|
|
@@ -273,7 +291,8 @@ def print_file_verification_status(
|
|
|
273
291
|
either using pprint or as a list for piping
|
|
274
292
|
"""
|
|
275
293
|
if pprint:
|
|
276
|
-
|
|
294
|
+
table = file_verification_status_table(file_status)
|
|
295
|
+
Console().print(table)
|
|
277
296
|
else:
|
|
278
297
|
for path, status in file_status.items():
|
|
279
298
|
stream = (
|
|
@@ -288,7 +307,8 @@ def print_files(files: Sequence[File], *, pprint: bool) -> None:
|
|
|
288
307
|
either using pprint or as a list for piping
|
|
289
308
|
"""
|
|
290
309
|
if pprint:
|
|
291
|
-
|
|
310
|
+
table = files_to_table(files)
|
|
311
|
+
Console().print(table)
|
|
292
312
|
else:
|
|
293
313
|
for file in files:
|
|
294
314
|
stream = sys.stdout if file.state == FileState.OK else sys.stderr
|
|
@@ -301,7 +321,8 @@ def print_missions(missions: Sequence[Mission], *, pprint: bool) -> None:
|
|
|
301
321
|
either using pprint or as a list for piping
|
|
302
322
|
"""
|
|
303
323
|
if pprint:
|
|
304
|
-
|
|
324
|
+
table = missions_to_table(missions)
|
|
325
|
+
Console().print(table)
|
|
305
326
|
else:
|
|
306
327
|
for mission in missions:
|
|
307
328
|
print(mission.id)
|
|
@@ -313,7 +334,8 @@ def print_projects(projects: Sequence[Project], *, pprint: bool) -> None:
|
|
|
313
334
|
either using pprint or as a list for piping
|
|
314
335
|
"""
|
|
315
336
|
if pprint:
|
|
316
|
-
|
|
337
|
+
table = projects_to_table(projects)
|
|
338
|
+
Console().print(table)
|
|
317
339
|
else:
|
|
318
340
|
for project in projects:
|
|
319
341
|
print(project.id)
|
|
@@ -325,7 +347,8 @@ def print_file_info(file: File, *, pprint: bool) -> None:
|
|
|
325
347
|
either using pprint or as a list for piping
|
|
326
348
|
"""
|
|
327
349
|
if pprint:
|
|
328
|
-
|
|
350
|
+
table = file_info_table(file)
|
|
351
|
+
Console().print(table)
|
|
329
352
|
else:
|
|
330
353
|
file_dct = asdict(file)
|
|
331
354
|
for key in file_dct:
|
kleinkram/utils.py
CHANGED
|
@@ -40,10 +40,7 @@ def file_paths_from_files(
|
|
|
40
40
|
determines the destinations for a sequence of `File` objects,
|
|
41
41
|
possibly nested by project and mission
|
|
42
42
|
"""
|
|
43
|
-
if (
|
|
44
|
-
len(set([(file.project_id, file.mission_id) for file in files])) > 1
|
|
45
|
-
and not allow_nested
|
|
46
|
-
):
|
|
43
|
+
if len(set([file.mission_id for file in files])) > 1 and not allow_nested:
|
|
47
44
|
raise ValueError("files from multiple missions were selected")
|
|
48
45
|
elif not allow_nested:
|
|
49
46
|
return {dest / file.name: file for file in files}
|
{kleinkram-0.39.0.dev20250224101424.dist-info → kleinkram-0.40.0.dev20250226155726.dist-info}/RECORD
RENAMED
|
@@ -2,18 +2,18 @@ kleinkram/__init__.py,sha256=xIJqTJw2kbCGryGlCeAdpmtR1FTxmrW1MklUNQEaj74,1061
|
|
|
2
2
|
kleinkram/__main__.py,sha256=B9RiZxfO4jpCmWPUHyKJ7_EoZlEG4sPpH-nz7T_YhhQ,125
|
|
3
3
|
kleinkram/_version.py,sha256=QYJyRTcqFcJj4qWYpqs7WcoOP6jxDMqyvxLY-cD6KcE,129
|
|
4
4
|
kleinkram/auth.py,sha256=XD_rHOyJmYYfO7QJf3TLYH5qXA22gXGWi7PT3jujlVs,2968
|
|
5
|
-
kleinkram/config.py,sha256=
|
|
5
|
+
kleinkram/config.py,sha256=_gcQu9BibCGjxCN4n4aMlJXXw0P6WjkPYgFTVU_PTAU,6919
|
|
6
6
|
kleinkram/core.py,sha256=Q7OYIKPN9K6kxf9Eq7r5XRHPJ3RtT7SBZp_3_CS8yuY,8429
|
|
7
7
|
kleinkram/errors.py,sha256=4mygNxkf6IBgaiRWY95qu0v6z4TAXA3G6CUcXC9FU3s,772
|
|
8
8
|
kleinkram/main.py,sha256=BTE0mZN__xd46wBhFi6iBlK9eGGQvJ1LdUMsbnysLi0,172
|
|
9
9
|
kleinkram/models.py,sha256=8nJlPrKVLSmehspeuQSFV6nUo76JzehUn6KIZYH1xy4,1832
|
|
10
|
-
kleinkram/printing.py,sha256=
|
|
10
|
+
kleinkram/printing.py,sha256=fpkJFeVp5pzZ_cZY6nzYDV_qDFWHKHxiW-DaH2PPNeY,12160
|
|
11
11
|
kleinkram/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
kleinkram/types.py,sha256=nfDjj8TB1Jn5vqO0Xg6qhLOuKom9DDhe62BrngqnVGM,185
|
|
13
|
-
kleinkram/utils.py,sha256=
|
|
13
|
+
kleinkram/utils.py,sha256=fFQsq5isLjDC2Z-XUTiJzz30Wt9rFUi4391WXstusG0,6221
|
|
14
14
|
kleinkram/wrappers.py,sha256=4xXU43eNnvMG2sssU330MmTLSSRdurOpnZ-zNGOGmt0,11342
|
|
15
15
|
kleinkram/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
-
kleinkram/api/client.py,sha256=
|
|
16
|
+
kleinkram/api/client.py,sha256=1mQuguyYM3ghrADTlivQi9ybWjJzlb9emto5rPtJRkM,5112
|
|
17
17
|
kleinkram/api/deser.py,sha256=xRpYUFKZ0Luoo7XyAtYblJvprmpjNSZOiFVnFKmOzcM,4819
|
|
18
18
|
kleinkram/api/file_transfer.py,sha256=3wNlVQdjnRtxOzih5HhCTF18xPbYClFIDxCqbwkLl6c,12985
|
|
19
19
|
kleinkram/api/pagination.py,sha256=P_zPsBKlMWkmAv-YfUNHaGW-XLB_4U8BDMrKyiDFIXk,1370
|
|
@@ -28,7 +28,7 @@ kleinkram/cli/_mission.py,sha256=zDFnOozOFckpuREFgIPt1IzG5q3b1bsNxYlWQoHoz5A,530
|
|
|
28
28
|
kleinkram/cli/_project.py,sha256=N0C96NC_onCEwTteYp2wgkkwkdJt-1q43LFdqNXfjC8,3398
|
|
29
29
|
kleinkram/cli/_upload.py,sha256=gOhbjbmqhmwW7p6bWlSvI53vLHvBFO9QqD1kdU92I2k,2813
|
|
30
30
|
kleinkram/cli/_verify.py,sha256=0ABVa4U_WzaV36ClR8NsOIG7KAMRlnFmsbtnHhbWVj4,1742
|
|
31
|
-
kleinkram/cli/app.py,sha256=
|
|
31
|
+
kleinkram/cli/app.py,sha256=m2qq4z95QllvXnxh3koPp0kq06I5R9etsJV8qSV8TMk,7037
|
|
32
32
|
kleinkram/cli/error_handling.py,sha256=wK3tzeKVSrZm-xmiyzGLnGT2E4TRpyxhaak6GWGP7P8,1921
|
|
33
33
|
testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
34
|
testing/backend_fixtures.py,sha256=t5QWwyezHUhxxAlbUuE_eFmpyRaGbnWNNcGPwrO17JM,1571
|
|
@@ -39,12 +39,12 @@ tests/test_core.py,sha256=JbzB05LWmaaP77uXeTOQtCJD2AJT0zO9zhDfcZ3GNH8,5139
|
|
|
39
39
|
tests/test_end_to_end.py,sha256=0W5pUES5hek-pXq4NZtpPZqKTORkGCRsDv5_D3rDMjY,3372
|
|
40
40
|
tests/test_error_handling.py,sha256=qPSMKF1qsAHyUME0-krxbIrk38iGKkhAyAah-KwN4NE,1300
|
|
41
41
|
tests/test_fixtures.py,sha256=UlPmGbEsGvrDPsaStGMRjNvrVPGjCqOB0RMfLJq2VRA,1071
|
|
42
|
-
tests/test_printing.py,sha256=
|
|
42
|
+
tests/test_printing.py,sha256=Jz1AjqmqBRjp1JLm6H1oVJyvGaMPlahVXdKnd7UDQFc,2231
|
|
43
43
|
tests/test_query.py,sha256=fExmCKXLA7-9j2S2sF_sbvRX_2s6Cp3a7OTcqE25q9g,3864
|
|
44
44
|
tests/test_utils.py,sha256=eUBYrn3xrcgcaxm1X4fqZaX4tRvkbI6rh6BUbNbu9T0,4784
|
|
45
45
|
tests/test_wrappers.py,sha256=TbcTyO2L7fslbzgfDdcVZkencxNQ8cGPZm_iB6c9d6Q,2673
|
|
46
|
-
kleinkram-0.
|
|
47
|
-
kleinkram-0.
|
|
48
|
-
kleinkram-0.
|
|
49
|
-
kleinkram-0.
|
|
50
|
-
kleinkram-0.
|
|
46
|
+
kleinkram-0.40.0.dev20250226155726.dist-info/METADATA,sha256=P_hPAF92tq9-81_kWve3575bj7r4baAmbbCOeyJo2w4,2760
|
|
47
|
+
kleinkram-0.40.0.dev20250226155726.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
|
|
48
|
+
kleinkram-0.40.0.dev20250226155726.dist-info/entry_points.txt,sha256=SaB2l5aqhSr8gmaMw2kvQU90a8Bnl7PedU8cWYxkfYo,46
|
|
49
|
+
kleinkram-0.40.0.dev20250226155726.dist-info/top_level.txt,sha256=N3-sJagEHu1Tk1X6Dx1X1q0pLDNbDZpLzRxVftvepds,24
|
|
50
|
+
kleinkram-0.40.0.dev20250226155726.dist-info/RECORD,,
|
tests/test_printing.py
CHANGED
|
@@ -3,9 +3,11 @@ from __future__ import annotations
|
|
|
3
3
|
import datetime
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
|
+
from rich.table import Table
|
|
6
7
|
|
|
7
8
|
from kleinkram.models import MetadataValue
|
|
8
9
|
from kleinkram.models import MetadataValueType
|
|
10
|
+
from kleinkram.printing import _add_placeholder_row
|
|
9
11
|
from kleinkram.printing import format_bytes
|
|
10
12
|
from kleinkram.printing import parse_metadata_value
|
|
11
13
|
|
|
@@ -23,6 +25,15 @@ def test_format_bytes():
|
|
|
23
25
|
assert format_bytes(2**50) == "1.00 PB"
|
|
24
26
|
|
|
25
27
|
|
|
28
|
+
def test_add_placeholder_row():
|
|
29
|
+
table = Table("foo", "bar")
|
|
30
|
+
_add_placeholder_row(table, skipped=1)
|
|
31
|
+
|
|
32
|
+
assert table.row_count == 1
|
|
33
|
+
assert table.columns[0]._cells[-1] == "... (1 more)"
|
|
34
|
+
assert table.columns[1]._cells[-1] == "..."
|
|
35
|
+
|
|
36
|
+
|
|
26
37
|
def test_parse_metadata_value():
|
|
27
38
|
mv = MetadataValue(type_=MetadataValueType.STRING, value="foo")
|
|
28
39
|
assert parse_metadata_value(mv) == "foo"
|
|
File without changes
|
|
File without changes
|