kleinkram 0.48.0.dev20250723090520__py3-none-any.whl → 0.58.0.dev20260110152317__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.
Files changed (44) hide show
  1. kleinkram/api/client.py +6 -18
  2. kleinkram/api/deser.py +152 -1
  3. kleinkram/api/file_transfer.py +57 -87
  4. kleinkram/api/pagination.py +11 -2
  5. kleinkram/api/query.py +10 -10
  6. kleinkram/api/routes.py +192 -59
  7. kleinkram/auth.py +108 -7
  8. kleinkram/cli/_action.py +131 -0
  9. kleinkram/cli/_download.py +6 -18
  10. kleinkram/cli/_endpoint.py +2 -4
  11. kleinkram/cli/_file.py +6 -18
  12. kleinkram/cli/_file_validator.py +125 -0
  13. kleinkram/cli/_list.py +5 -15
  14. kleinkram/cli/_mission.py +24 -28
  15. kleinkram/cli/_project.py +10 -26
  16. kleinkram/cli/_run.py +220 -0
  17. kleinkram/cli/_upload.py +58 -26
  18. kleinkram/cli/_verify.py +48 -15
  19. kleinkram/cli/app.py +56 -17
  20. kleinkram/cli/error_handling.py +1 -3
  21. kleinkram/config.py +6 -21
  22. kleinkram/core.py +19 -36
  23. kleinkram/errors.py +12 -0
  24. kleinkram/models.py +49 -0
  25. kleinkram/printing.py +225 -15
  26. kleinkram/utils.py +8 -22
  27. kleinkram/wrappers.py +13 -34
  28. {kleinkram-0.48.0.dev20250723090520.dist-info → kleinkram-0.58.0.dev20260110152317.dist-info}/METADATA +6 -5
  29. kleinkram-0.58.0.dev20260110152317.dist-info/RECORD +53 -0
  30. {kleinkram-0.48.0.dev20250723090520.dist-info → kleinkram-0.58.0.dev20260110152317.dist-info}/top_level.txt +0 -1
  31. {testing → tests}/backend_fixtures.py +27 -3
  32. tests/conftest.py +1 -1
  33. tests/generate_test_data.py +314 -0
  34. tests/test_config.py +2 -6
  35. tests/test_core.py +11 -31
  36. tests/test_end_to_end.py +3 -5
  37. tests/test_fixtures.py +3 -5
  38. tests/test_printing.py +1 -3
  39. tests/test_utils.py +1 -3
  40. tests/test_wrappers.py +9 -27
  41. kleinkram-0.48.0.dev20250723090520.dist-info/RECORD +0 -50
  42. testing/__init__.py +0 -0
  43. {kleinkram-0.48.0.dev20250723090520.dist-info → kleinkram-0.58.0.dev20260110152317.dist-info}/WHEEL +0 -0
  44. {kleinkram-0.48.0.dev20250723090520.dist-info → kleinkram-0.58.0.dev20260110152317.dist-info}/entry_points.txt +0 -0
tests/test_core.py CHANGED
@@ -17,43 +17,33 @@ from kleinkram.api.query import MissionQuery
17
17
  from kleinkram.api.query import ProjectQuery
18
18
  from kleinkram.errors import MissionNotFound
19
19
  from kleinkram.models import FileVerificationStatus
20
- from testing.backend_fixtures import DATA_FILES
20
+ from tests.backend_fixtures import DATA_FILES
21
21
 
22
22
 
23
23
  @pytest.mark.slow
24
24
  def test_upload_create(project):
25
25
  mission_name = token_hex(8)
26
- mission_query = MissionQuery(
27
- patterns=[mission_name], project_query=ProjectQuery(ids=[project.id])
28
- )
26
+ mission_query = MissionQuery(patterns=[mission_name], project_query=ProjectQuery(ids=[project.id]))
29
27
 
30
28
  client = AuthenticatedClient()
31
- kleinkram.core.upload(
32
- client=client, query=mission_query, file_paths=DATA_FILES, create=True
33
- )
29
+ kleinkram.core.upload(client=client, query=mission_query, file_paths=DATA_FILES, create=True)
34
30
 
35
31
  mission = list_missions(mission_names=[mission_name])[0]
36
32
  assert mission.project_id == project.id
37
33
  assert mission.name == mission_name
38
34
 
39
35
  files = list_files(mission_ids=[mission.id])
40
- assert set([file.name for file in files if file.name.endswith(".bag")]) == set(
41
- [file.name for file in DATA_FILES]
42
- )
36
+ assert set([file.name for file in files if file.name.endswith(".bag")]) == set([file.name for file in DATA_FILES])
43
37
 
44
38
 
45
39
  @pytest.mark.slow
46
40
  def test_upload_no_create(project):
47
41
  mission_name = token_hex(8)
48
- mission_query = MissionQuery(
49
- patterns=[mission_name], project_query=ProjectQuery(ids=[project.id])
50
- )
42
+ mission_query = MissionQuery(patterns=[mission_name], project_query=ProjectQuery(ids=[project.id]))
51
43
 
52
44
  client = AuthenticatedClient()
53
45
  with pytest.raises(MissionNotFound):
54
- kleinkram.core.upload(
55
- client=client, query=mission_query, file_paths=DATA_FILES, create=False
56
- )
46
+ kleinkram.core.upload(client=client, query=mission_query, file_paths=DATA_FILES, create=False)
57
47
 
58
48
 
59
49
  @pytest.mark.slow
@@ -64,9 +54,7 @@ def test_upload_to_existing_mission(empty_mission):
64
54
  kleinkram.core.upload(client=client, query=mission_query, file_paths=DATA_FILES)
65
55
 
66
56
  files = list_files(mission_ids=[empty_mission.id])
67
- assert set([file.name for file in files if file.name.endswith(".bag")]) == set(
68
- [file.name for file in DATA_FILES]
69
- )
57
+ assert set([file.name for file in files if file.name.endswith(".bag")]) == set([file.name for file in DATA_FILES])
70
58
 
71
59
 
72
60
  @pytest.mark.slow
@@ -84,9 +72,7 @@ def test_delete_working_as_expected_when_passing_empty_list(mission):
84
72
  # we need to filter by *.bag to not get flakyness due to conversion
85
73
  n_files = len(list_files(mission_ids=[mission.id], file_names=["*.bag"]))
86
74
  kleinkram.core.delete_files(client=client, file_ids=[])
87
- n_files_after_delete = len(
88
- list_files(mission_ids=[mission.id], file_names=["*.bag"])
89
- )
75
+ n_files_after_delete = len(list_files(mission_ids=[mission.id], file_names=["*.bag"]))
90
76
  assert n_files == n_files_after_delete
91
77
 
92
78
 
@@ -132,9 +118,7 @@ def test_create_update_delete_project():
132
118
  assert project.description == "test"
133
119
 
134
120
  new_name = token_hex(8)
135
- kleinkram.core.update_project(
136
- client=client, project_id=project.id, new_name=new_name, description="new desc"
137
- )
121
+ kleinkram.core.update_project(client=client, project_id=project.id, new_name=new_name, description="new desc")
138
122
 
139
123
  project = list_projects(project_ids=[project.id])[0]
140
124
  assert project.name == new_name
@@ -162,13 +146,9 @@ def test_verify(mission):
162
146
  client = AuthenticatedClient()
163
147
  query = MissionQuery(ids=[mission.id])
164
148
 
165
- verify_status = kleinkram.core.verify(
166
- client=client, query=query, file_paths=DATA_FILES, skip_hash=True
167
- )
149
+ verify_status = kleinkram.core.verify(client=client, query=query, file_paths=DATA_FILES, skip_hash=True)
168
150
 
169
- assert all(
170
- status == FileVerificationStatus.UPLOADED for status in verify_status.values()
171
- )
151
+ assert all(status == FileVerificationStatus.UPLOADED for status in verify_status.values())
172
152
 
173
153
 
174
154
  @pytest.mark.slow
tests/test_end_to_end.py CHANGED
@@ -16,7 +16,7 @@ VERBOSE = True
16
16
 
17
17
  CLI = "klein"
18
18
  PROJECT_NAME = "automated-testing"
19
- DATA_PATH = Path(__file__).parent.parent / "data" / "testing"
19
+ DATA_PATH = Path(__file__).parent / "data"
20
20
 
21
21
 
22
22
  @pytest.fixture(scope="session")
@@ -48,9 +48,7 @@ def test_upload_verify_update_download_mission(project, tmp_path, api):
48
48
 
49
49
  mission_name = secrets.token_hex(8)
50
50
  upload = f"{CLI} upload -p {project.name} -m {mission_name} --create {DATA_PATH.absolute()}/*.bag"
51
- verify = (
52
- f"{CLI} verify -p {project.name} -m {mission_name} {DATA_PATH.absolute()}/*.bag"
53
- )
51
+ verify = f"{CLI} verify -p {project.name} -m {mission_name} {DATA_PATH.absolute()}/*.bag"
54
52
  # update = f"{CLI} mission update -p {project.name} -m {mission_name} --metadata {DATA_PATH.absolute()}/metadata.yaml"
55
53
  download = f"{CLI} download -p {project.name} -m {mission_name} --dest {tmp_path.absolute()}"
56
54
  delete_file = f"{CLI} file delete -p {project.name} -m {mission_name} -f {file_names[0].name} -y"
@@ -69,7 +67,7 @@ def test_list_files(project, mission, api):
69
67
  assert run_cmd(f"{CLI} list files -p {project.name}") == 0
70
68
  assert run_cmd(f"{CLI} list files -p {project.name} -m {mission.name}") == 0
71
69
  assert run_cmd(f"{CLI} list files") == 0
72
- assert run_cmd(f"{CLI} list files -p {mission.name}") == 0
70
+ assert run_cmd(f"{CLI} list files -p {project.name}") == 0
73
71
  assert run_cmd(f'{CLI} list files -p "*" -m "*" "*"') == 0
74
72
 
75
73
 
tests/test_fixtures.py CHANGED
@@ -5,8 +5,8 @@ import pytest
5
5
  from kleinkram import list_files
6
6
  from kleinkram import list_missions
7
7
  from kleinkram import list_projects
8
- from testing.backend_fixtures import DATA_FILES
9
- from testing.backend_fixtures import PROJECT_DESCRIPTION
8
+ from tests.backend_fixtures import DATA_FILES
9
+ from tests.backend_fixtures import PROJECT_DESCRIPTION
10
10
 
11
11
 
12
12
  @pytest.mark.slow
@@ -22,9 +22,7 @@ def test_mission_fixture(mission, project):
22
22
 
23
23
  files = list_files(mission_ids=[mission.id])
24
24
 
25
- assert set([file.name for file in files if file.name.endswith(".bag")]) == set(
26
- [file.name for file in DATA_FILES]
27
- )
25
+ assert set([file.name for file in files if file.name.endswith(".bag")]) == set([file.name for file in DATA_FILES])
28
26
 
29
27
 
30
28
  @pytest.mark.slow
tests/test_printing.py CHANGED
@@ -48,9 +48,7 @@ def test_parse_metadata_value():
48
48
  mv = MetadataValue(type_=MetadataValueType.BOOLEAN, value="false")
49
49
  assert parse_metadata_value(mv) is False # noqa
50
50
  mv = MetadataValue(type_=MetadataValueType.DATE, value="2021-01-01T00:00:00Z")
51
- assert parse_metadata_value(mv) == datetime.datetime(
52
- 2021, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc
53
- )
51
+ assert parse_metadata_value(mv) == datetime.datetime(2021, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc)
54
52
 
55
53
 
56
54
  @pytest.mark.skip
tests/test_utils.py CHANGED
@@ -85,9 +85,7 @@ def test_is_valid_uuid4():
85
85
  "invalid_sybmols_____.txt",
86
86
  id="invalid symbols",
87
87
  ),
88
- pytest.param(
89
- Path(f'{"a" * 100}.txt'), f'{"a" * 40}38bf3e475f.txt', id="too long"
90
- ),
88
+ pytest.param(Path(f'{"a" * 100}.txt'), f'{"a" * 40}38bf3e475f.txt', id="too long"),
91
89
  pytest.param(Path(f'{"a" * 50}.txt'), f'{"a" * 50}.txt', id="max length"),
92
90
  pytest.param(Path("in/a/folder.txt"), "folder.txt", id="in folder"),
93
91
  ],
tests/test_wrappers.py CHANGED
@@ -12,37 +12,25 @@ from kleinkram.wrappers import _args_to_project_query
12
12
 
13
13
  def test_args_to_project_query() -> None:
14
14
  assert _args_to_project_query() == ProjectQuery()
15
- assert _args_to_project_query(project_names=["test"]) == ProjectQuery(
16
- patterns=["test"]
17
- )
15
+ assert _args_to_project_query(project_names=["test"]) == ProjectQuery(patterns=["test"])
18
16
 
19
17
  _id = uuid4()
20
18
  assert _args_to_project_query(project_ids=[_id]) == ProjectQuery(ids=[_id])
21
- assert _args_to_project_query(
22
- project_names=["test"], project_ids=[_id]
23
- ) == ProjectQuery(patterns=["test"], ids=[_id])
19
+ assert _args_to_project_query(project_names=["test"], project_ids=[_id]) == ProjectQuery(patterns=["test"], ids=[_id])
24
20
  assert _args_to_project_query(project_ids=[str(_id)]) == ProjectQuery(ids=[_id])
25
21
 
26
22
 
27
23
  def test_args_to_mission_query() -> None:
28
24
  assert _args_to_mission_query() == MissionQuery()
29
- assert _args_to_mission_query(mission_names=["test"]) == MissionQuery(
30
- patterns=["test"]
31
- )
25
+ assert _args_to_mission_query(mission_names=["test"]) == MissionQuery(patterns=["test"])
32
26
 
33
27
  _id = uuid4()
34
28
  assert _args_to_mission_query(mission_ids=[_id]) == MissionQuery(ids=[_id])
35
- assert _args_to_mission_query(
36
- mission_names=["test"], mission_ids=[_id]
37
- ) == MissionQuery(patterns=["test"], ids=[_id])
29
+ assert _args_to_mission_query(mission_names=["test"], mission_ids=[_id]) == MissionQuery(patterns=["test"], ids=[_id])
38
30
  assert _args_to_mission_query(mission_ids=[str(_id)]) == MissionQuery(ids=[_id])
39
31
 
40
- assert _args_to_mission_query(project_names=["test"]) == MissionQuery(
41
- project_query=ProjectQuery(patterns=["test"])
42
- )
43
- assert _args_to_mission_query(project_ids=[_id]) == MissionQuery(
44
- project_query=ProjectQuery(ids=[_id])
45
- )
32
+ assert _args_to_mission_query(project_names=["test"]) == MissionQuery(project_query=ProjectQuery(patterns=["test"]))
33
+ assert _args_to_mission_query(project_ids=[_id]) == MissionQuery(project_query=ProjectQuery(ids=[_id]))
46
34
 
47
35
 
48
36
  def test_args_to_file_query() -> None:
@@ -51,17 +39,11 @@ def test_args_to_file_query() -> None:
51
39
 
52
40
  _id = uuid4()
53
41
  assert _args_to_file_query(file_ids=[_id]) == FileQuery(ids=[_id])
54
- assert _args_to_file_query(file_names=["test"], file_ids=[_id]) == FileQuery(
55
- patterns=["test"], ids=[_id]
56
- )
42
+ assert _args_to_file_query(file_names=["test"], file_ids=[_id]) == FileQuery(patterns=["test"], ids=[_id])
57
43
  assert _args_to_file_query(file_ids=[str(_id)]) == FileQuery(ids=[_id])
58
44
 
59
- assert _args_to_file_query(mission_names=["test"]) == FileQuery(
60
- mission_query=MissionQuery(patterns=["test"])
61
- )
62
- assert _args_to_file_query(mission_ids=[_id]) == FileQuery(
63
- mission_query=MissionQuery(ids=[_id])
64
- )
45
+ assert _args_to_file_query(mission_names=["test"]) == FileQuery(mission_query=MissionQuery(patterns=["test"]))
46
+ assert _args_to_file_query(mission_ids=[_id]) == FileQuery(mission_query=MissionQuery(ids=[_id]))
65
47
 
66
48
  assert _args_to_file_query(project_names=["test"]) == FileQuery(
67
49
  mission_query=MissionQuery(project_query=ProjectQuery(patterns=["test"]))
@@ -1,50 +0,0 @@
1
- kleinkram/__init__.py,sha256=xIJqTJw2kbCGryGlCeAdpmtR1FTxmrW1MklUNQEaj74,1061
2
- kleinkram/__main__.py,sha256=B9RiZxfO4jpCmWPUHyKJ7_EoZlEG4sPpH-nz7T_YhhQ,125
3
- kleinkram/_version.py,sha256=QYJyRTcqFcJj4qWYpqs7WcoOP6jxDMqyvxLY-cD6KcE,129
4
- kleinkram/auth.py,sha256=XD_rHOyJmYYfO7QJf3TLYH5qXA22gXGWi7PT3jujlVs,2968
5
- kleinkram/config.py,sha256=nx6uSM5nLP4SKe8b9VAx4KDtCCwtyshXmzbEJcUwpsY,7411
6
- kleinkram/core.py,sha256=COJcUx8tP6EQIyg4OiVprJfQUCMbiq2QGB9xZ2CPUCo,9621
7
- kleinkram/errors.py,sha256=qa98YvhDbLqX60P8bcMcFmHy4HxgYNlSROXud8Kj-P4,965
8
- kleinkram/main.py,sha256=BTE0mZN__xd46wBhFi6iBlK9eGGQvJ1LdUMsbnysLi0,172
9
- kleinkram/models.py,sha256=MkWdGIWuCSnyg45DbdEUhtGIprwPYwKppYumHkRAS18,1870
10
- kleinkram/printing.py,sha256=gVLQPmAhyO1Fc5kKLBC77KvoEguBaAReTU3h-QQCx58,12212
11
- kleinkram/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- kleinkram/types.py,sha256=nfDjj8TB1Jn5vqO0Xg6qhLOuKom9DDhe62BrngqnVGM,185
13
- kleinkram/utils.py,sha256=lNtmjKTZj4ANndERqfL3QD8VI2B4ZavdW66lxNDz_IY,6767
14
- kleinkram/wrappers.py,sha256=ZScoEov5Q6D2rvaJJ8E-4f58P_NGWrGc9mRPYxSqOC0,13127
15
- kleinkram/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- kleinkram/api/client.py,sha256=VwuT97_WdbDpcVGwMXB0fRnUoQnUSf7BOP5eXUFokfI,5932
17
- kleinkram/api/deser.py,sha256=xRpYUFKZ0Luoo7XyAtYblJvprmpjNSZOiFVnFKmOzcM,4819
18
- kleinkram/api/file_transfer.py,sha256=eHJlK1FY0hHBmFHAves_p49hi4Mmpdjy1NNLeyLvK0w,19917
19
- kleinkram/api/pagination.py,sha256=P_zPsBKlMWkmAv-YfUNHaGW-XLB_4U8BDMrKyiDFIXk,1370
20
- kleinkram/api/query.py,sha256=9Exi4hJR7Ml38_zjAcOvSEoIAxZLlpM6QwwzO9fs5Gk,3293
21
- kleinkram/api/routes.py,sha256=x0IfzQO5RAC3rohDSpdUNlVOWl221gh4e0fbMKfGrQA,12251
22
- kleinkram/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- kleinkram/cli/_download.py,sha256=e0fDyp_CFOdbKIUGKmtITvAVINa6STYJk5w5QlElXSs,2394
24
- kleinkram/cli/_endpoint.py,sha256=oY0p4bnuHLEDJCXtTmir4AHswcKAygZ8I4IWC3RFcKc,1796
25
- kleinkram/cli/_file.py,sha256=Q2fLDdUyfHFmdGC6wIxMqgEl0F76qszhzWJrRV5rTBM,2973
26
- kleinkram/cli/_list.py,sha256=5gI3aIUeKC0_eWPQqdFXSBBFvpkTTJSm31TamHa197c,3090
27
- kleinkram/cli/_mission.py,sha256=zDFnOozOFckpuREFgIPt1IzG5q3b1bsNxYlWQoHoz5A,5301
28
- kleinkram/cli/_project.py,sha256=N0C96NC_onCEwTteYp2wgkkwkdJt-1q43LFdqNXfjC8,3398
29
- kleinkram/cli/_upload.py,sha256=gOhbjbmqhmwW7p6bWlSvI53vLHvBFO9QqD1kdU92I2k,2813
30
- kleinkram/cli/_verify.py,sha256=n9QThY0JnqaIqw6udYXdRQGcpUl2lIbFXGQIgpTnDPE,2112
31
- kleinkram/cli/app.py,sha256=m2qq4z95QllvXnxh3koPp0kq06I5R9etsJV8qSV8TMk,7037
32
- kleinkram/cli/error_handling.py,sha256=wK3tzeKVSrZm-xmiyzGLnGT2E4TRpyxhaak6GWGP7P8,1921
33
- testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- testing/backend_fixtures.py,sha256=t5QWwyezHUhxxAlbUuE_eFmpyRaGbnWNNcGPwrO17JM,1571
35
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
- tests/conftest.py,sha256=5MLYQOtQoXWl0TRkYntYKNdqpd4hl9m0XTRi5OXanYI,104
37
- tests/test_config.py,sha256=uvVh1iUSCoZc8YioxS_GjF-J7m4JE2z4XUbwK_4wDV0,5855
38
- tests/test_core.py,sha256=tVvmC4yBkE00VspoowhfdNAUiBsmkIJQodaC3jjUqqM,5623
39
- tests/test_end_to_end.py,sha256=0W5pUES5hek-pXq4NZtpPZqKTORkGCRsDv5_D3rDMjY,3372
40
- tests/test_error_handling.py,sha256=qPSMKF1qsAHyUME0-krxbIrk38iGKkhAyAah-KwN4NE,1300
41
- tests/test_fixtures.py,sha256=UlPmGbEsGvrDPsaStGMRjNvrVPGjCqOB0RMfLJq2VRA,1071
42
- tests/test_printing.py,sha256=kPzpIQOtQJ9yQ32mM8cMGDVOGsbrZZLQhfsXN1Pe68Q,2231
43
- tests/test_query.py,sha256=fExmCKXLA7-9j2S2sF_sbvRX_2s6Cp3a7OTcqE25q9g,3864
44
- tests/test_utils.py,sha256=eUBYrn3xrcgcaxm1X4fqZaX4tRvkbI6rh6BUbNbu9T0,4784
45
- tests/test_wrappers.py,sha256=TbcTyO2L7fslbzgfDdcVZkencxNQ8cGPZm_iB6c9d6Q,2673
46
- kleinkram-0.48.0.dev20250723090520.dist-info/METADATA,sha256=EfZ-_Un6YMwy8DtBolKFa9RWDVH-4pSzQa-mZPrCwe8,2846
47
- kleinkram-0.48.0.dev20250723090520.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
48
- kleinkram-0.48.0.dev20250723090520.dist-info/entry_points.txt,sha256=SaB2l5aqhSr8gmaMw2kvQU90a8Bnl7PedU8cWYxkfYo,46
49
- kleinkram-0.48.0.dev20250723090520.dist-info/top_level.txt,sha256=N3-sJagEHu1Tk1X6Dx1X1q0pLDNbDZpLzRxVftvepds,24
50
- kleinkram-0.48.0.dev20250723090520.dist-info/RECORD,,
testing/__init__.py DELETED
File without changes