kleinkram 0.38.1.dev20241119134715__py3-none-any.whl → 0.38.1.dev20241125112529__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/utils.py CHANGED
@@ -3,15 +3,13 @@ from __future__ import annotations
3
3
  import base64
4
4
  import fnmatch
5
5
  import hashlib
6
- import os
7
6
  import string
7
+ import traceback
8
8
  from hashlib import md5
9
9
  from pathlib import Path
10
10
  from typing import Any
11
11
  from typing import Dict
12
12
  from typing import List
13
- from typing import NamedTuple
14
- from typing import Optional
15
13
  from typing import Sequence
16
14
  from typing import Tuple
17
15
  from typing import Union
@@ -20,18 +18,22 @@ from uuid import UUID
20
18
  import yaml
21
19
  from kleinkram._version import __version__
22
20
  from kleinkram.errors import FileTypeNotSupported
23
- from kleinkram.errors import InvalidFileSpec
24
- from kleinkram.errors import InvalidMissionSpec
25
- from kleinkram.models import FilesById
26
- from kleinkram.models import FilesByMission
27
- from kleinkram.models import MissionById
28
- from kleinkram.models import MissionByName
29
21
  from rich.console import Console
30
22
 
31
-
32
23
  INTERNAL_ALLOWED_CHARS = string.ascii_letters + string.digits + "_" + "-"
33
24
 
34
25
 
26
+ def split_args(args: List[str]) -> Tuple[List[UUID], List[str]]:
27
+ uuids = []
28
+ names = []
29
+ for arg in args:
30
+ if is_valid_uuid4(arg):
31
+ uuids.append(UUID(arg, version=4))
32
+ else:
33
+ names.append(arg)
34
+ return uuids, names
35
+
36
+
35
37
  def check_file_paths(files: Sequence[Path]) -> None:
36
38
  for file in files:
37
39
  if file.is_dir():
@@ -44,6 +46,25 @@ def check_file_paths(files: Sequence[Path]) -> None:
44
46
  )
45
47
 
46
48
 
49
+ def noop(*args: Any, **kwargs: Any) -> None:
50
+ _ = args, kwargs # suppress unused variable warning
51
+ return
52
+
53
+
54
+ def format_error(msg: str, exc: Exception, *, verbose: bool = False) -> str:
55
+ if not verbose:
56
+ ret = f"{msg}: {type(exc).__name__}"
57
+ else:
58
+ ret = f"{msg}: {exc}"
59
+ return styled_string(ret, style="red")
60
+
61
+
62
+ def format_traceback(exc: Exception) -> str:
63
+ return "".join(
64
+ traceback.format_exception(etype=type(exc), value=exc, tb=exc.__traceback__)
65
+ )
66
+
67
+
47
68
  def filtered_by_patterns(names: Sequence[str], patterns: List[str]) -> List[str]:
48
69
  filtered = []
49
70
  for name in names:
@@ -52,17 +73,14 @@ def filtered_by_patterns(names: Sequence[str], patterns: List[str]) -> List[str]
52
73
  return filtered
53
74
 
54
75
 
55
- def raw_rich(*objects: Any, **kwargs: Any) -> str:
76
+ def styled_string(*objects: Any, **kwargs: Any) -> str:
56
77
  """\
57
78
  accepts any object that Console.print can print
58
79
  returns the raw string output
59
80
  """
60
-
61
81
  console = Console()
62
-
63
82
  with console.capture() as capture:
64
83
  console.print(*objects, **kwargs, end="")
65
-
66
84
  return capture.get()
67
85
 
68
86
 
@@ -127,45 +145,6 @@ def b64_md5(file: Path) -> str:
127
145
  return base64.b64encode(binary_digest).decode("utf-8")
128
146
 
129
147
 
130
- def get_valid_mission_spec(
131
- mission: Union[str, UUID],
132
- project: Optional[Union[str, UUID]] = None,
133
- ) -> Union[MissionById, MissionByName]:
134
- """\
135
- checks if:
136
- - atleast one is speicifed
137
- - if project is not specified then mission must be a valid uuid4
138
- """
139
-
140
- if isinstance(mission, UUID):
141
- return MissionById(id=mission)
142
- if isinstance(mission, str) and project is not None:
143
- return MissionByName(name=mission, project=project)
144
- raise InvalidMissionSpec("must specify mission id or project name / id")
145
-
146
-
147
- def get_valid_file_spec(
148
- files: Sequence[Union[str, UUID]],
149
- mission: Optional[Union[str, UUID]] = None,
150
- project: Optional[Union[str, UUID]] = None,
151
- ) -> Union[FilesById, FilesByMission]:
152
- """\
153
- """
154
- if not any([project, mission, files]):
155
- raise InvalidFileSpec("must specify `project`, `mission` or `files`")
156
-
157
- # if only files are specified they must be valid uuid4
158
- if project is None and mission is None:
159
- if all(map(lambda file: isinstance(file, UUID), files)):
160
- return FilesById(ids=files) # type: ignore
161
- raise InvalidFileSpec("if no mission is specified files must be valid uuid4")
162
-
163
- if mission is None:
164
- raise InvalidMissionSpec("mission must be specified")
165
- mission_spec = get_valid_mission_spec(mission, project)
166
- return FilesByMission(mission=mission_spec, files=list(files))
167
-
168
-
169
148
  def to_name_or_uuid(s: str) -> Union[UUID, str]:
170
149
  if is_valid_uuid4(s):
171
150
  return UUID(s)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kleinkram
3
- Version: 0.38.1.dev20241119134715
3
+ Version: 0.38.1.dev20241125112529
4
4
  Summary: give me your bags
5
5
  Author: Cyrill Püntener, Dominique Garmier, Johann Schwabe
6
6
  Classifier: Programming Language :: Python :: 3
@@ -109,5 +109,7 @@ klein --help
109
109
  ```bash
110
110
  pytest .
111
111
  ```
112
-
113
- You can also look in `scripts` for some scripts that might be useful for testing.
112
+ or if you want to skip slow tests...
113
+ ```bash
114
+ pytest -m "not slow" .
115
+ ```
@@ -0,0 +1,37 @@
1
+ kleinkram/__init__.py,sha256=adI-FqfuuH56n8U-lJa3uZkH_saxi7dr4Hox_HBuf9A,107
2
+ kleinkram/__main__.py,sha256=B9RiZxfO4jpCmWPUHyKJ7_EoZlEG4sPpH-nz7T_YhhQ,125
3
+ kleinkram/_version.py,sha256=QYJyRTcqFcJj4qWYpqs7WcoOP6jxDMqyvxLY-cD6KcE,129
4
+ kleinkram/app.py,sha256=dhXHl9xYXnfahXKbkyNI_EpTvtmmsrEjxbpPOANI7SY,5584
5
+ kleinkram/auth.py,sha256=G1RRyJBMR1IFLL2lR3D2RjkYtlkHWXZwCHRP-bRKKmk,2857
6
+ kleinkram/config.py,sha256=-MEgsSAzQg7jUSr8czRj8Y2DxbqMIKPDy4HBvnZ2oaI,4373
7
+ kleinkram/consts.py,sha256=70GELDssDm-YeIbChBRTscnNRcyWRUDWWlYBjVWNLDk,205
8
+ kleinkram/core.py,sha256=XmNhg1i520w-9et8r0LSQRsVN09gJgSXfyHRV1tu2rM,227
9
+ kleinkram/enums.py,sha256=bX0H8_xkh_7DRycJYII8MTjHmjbcFW9ZJ3tzlzRhT2k,149
10
+ kleinkram/errors.py,sha256=PVwgUAIuPie8uufN1UuuEAGQR-K41jFSygE1bMdhCwo,1869
11
+ kleinkram/main.py,sha256=hmFuSnE2p-E4nZ2zDVToOsoELZhosLN0r4wsXnbmsas,168
12
+ kleinkram/models.py,sha256=FFsbgcWN6GH3dFcbRDN2IPiVZ1wQG-FbYGtM64JaI_E,4303
13
+ kleinkram/resources.py,sha256=LqSLU5WPQOZZGG6w6-8E_Uy3B2AOc6dRjyZYiTByunY,4684
14
+ kleinkram/utils.py,sha256=BG6BrNc5eNARQ0nG4J2_rEK28bX--8KwwA2eIdXZo3o,4619
15
+ kleinkram/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ kleinkram/api/client.py,sha256=L0e6-KxpEmhNH-Z0_FgAIFqhAERRphlpyffjky8umOA,3385
17
+ kleinkram/api/file_transfer.py,sha256=pI9QKSpZFeIPY6fFwWsBxQr0PE9UW97Dp8UlKRZ5owY,13144
18
+ kleinkram/api/parsing.py,sha256=bvUwrSrM9SnDs_TGRq-HHOvH9hu3aTAq5S_bNLHA3Wk,2549
19
+ kleinkram/api/routes.py,sha256=o-ZoQlK3pZ1jx-sD2-EXEXAa5XZ8BsIXa0jLQ0Ogst4,6062
20
+ kleinkram/commands/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
21
+ kleinkram/commands/download.py,sha256=LydLgo3MMBfp35eENOKxuvV8z3eTSmmANcMcSQpgB88,3368
22
+ kleinkram/commands/endpoint.py,sha256=VgaleKTev8Muu4OmS4tptbhrbl58u1UTAxEmoLBCQew,1642
23
+ kleinkram/commands/list.py,sha256=NmTI6j-w-pp4Xf-U02HgKayb2U5H_3TvUytudY1lMNg,3316
24
+ kleinkram/commands/mission.py,sha256=on1mYcYbixOSqhciqB2GugmO2WyzZN4jgoS0mA78BaU,2214
25
+ kleinkram/commands/project.py,sha256=q-kJ1YQr-Axo-Zl0qe2J7eGGgKlSbcdDjpAJIynRLaM,587
26
+ kleinkram/commands/upload.py,sha256=rKS7_zPfHpOm6UG595Wfn9AKEAJ0sr9aqScpyaKruwo,5102
27
+ kleinkram/commands/verify.py,sha256=96yBA7rpQRsAdSGPZXE6gpvnw7e_patex2XqvNeDJLc,4841
28
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ tests/test_end_to_end.py,sha256=uGNsNz9HszzKYSXMUcTYzjMuYJkCEWjE9yt3IszcsY0,2855
30
+ tests/test_resources.py,sha256=y6Ibi1fn7oBV19-XVtgwqLLOYKAGwi7DcimkG5CLPI8,3802
31
+ tests/test_utils.py,sha256=zFtr66_TV68xcGchX64jRS-08mwWE-WghS6F3GXRpIc,4018
32
+ kleinkram-0.38.1.dev20241125112529.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
33
+ kleinkram-0.38.1.dev20241125112529.dist-info/METADATA,sha256=NIoNLmkeTm4u4ap17SyRZ8yU96pqQvN5ciQjN1JBnO4,2324
34
+ kleinkram-0.38.1.dev20241125112529.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
35
+ kleinkram-0.38.1.dev20241125112529.dist-info/entry_points.txt,sha256=SaB2l5aqhSr8gmaMw2kvQU90a8Bnl7PedU8cWYxkfYo,46
36
+ kleinkram-0.38.1.dev20241125112529.dist-info/top_level.txt,sha256=G1Lj9vHAtZn402Ukkrfll-6BCmnDNy_HVtWeNvXzdDA,16
37
+ kleinkram-0.38.1.dev20241125112529.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.5.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,105 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import secrets
5
+ import shutil
6
+ from pathlib import Path
7
+
8
+ import pytest
9
+ from kleinkram.api.routes import _get_api_version
10
+ from rich.console import Console
11
+ from rich.text import Text
12
+
13
+ VERBOSE = True
14
+
15
+ CLI = "klein"
16
+ PROJECT_NAME = "automated-testing"
17
+
18
+ DATA_DIR = Path(__file__).parent.parent / "data" / "testing"
19
+ _IN_DIR = DATA_DIR / "in"
20
+ _OUT_DIR = DATA_DIR / "out"
21
+
22
+
23
+ @pytest.fixture(scope="session")
24
+ def api():
25
+ try:
26
+ _get_api_version()
27
+ return True
28
+ except Exception:
29
+ print("API is not available")
30
+ return False
31
+
32
+
33
+ @pytest.fixture(scope="session")
34
+ def in_dir():
35
+ return _IN_DIR
36
+
37
+
38
+ @pytest.fixture(scope="session")
39
+ def out_dir():
40
+ try:
41
+ _OUT_DIR.mkdir(exist_ok=True)
42
+ yield _OUT_DIR
43
+ finally:
44
+ shutil.rmtree(_OUT_DIR)
45
+
46
+
47
+ @pytest.fixture(scope="session")
48
+ def name():
49
+ return secrets.token_hex(8)
50
+
51
+
52
+ def run_cmd(command, *, verbose=VERBOSE):
53
+ msg = ("\n", "#" * 50, "\n\n", "running command:", Text(command, style="bold"))
54
+ Console().print(*msg)
55
+
56
+ if not verbose:
57
+ command += ">/dev/null 2>&1"
58
+ ret = os.system(command)
59
+ Console().print("got return code:", ret, style="bold red")
60
+ return ret
61
+
62
+
63
+ @pytest.mark.slow
64
+ def test_upload_verify_update_download_mission(name, in_dir, out_dir, api):
65
+ assert api
66
+
67
+ upload = (
68
+ f"{CLI} upload -p {PROJECT_NAME} -m {name} --create {in_dir.absolute()}/*.bag"
69
+ )
70
+ verify = f"{CLI} verify -p {PROJECT_NAME} -m {name} {in_dir.absolute()}/*.bag"
71
+ update = f"{CLI} mission update -p {PROJECT_NAME} -m {name} --metadata {in_dir.absolute()}/metadata.yaml"
72
+ download = f"{CLI} download -p {PROJECT_NAME} -m {name} --dest {out_dir.absolute()}"
73
+
74
+ assert run_cmd(upload) == 0
75
+ assert run_cmd(verify) == 0
76
+ assert run_cmd(update) == 0
77
+ assert run_cmd(download) == 0
78
+
79
+
80
+ @pytest.mark.slow
81
+ def test_list_files(api):
82
+ assert api
83
+ assert run_cmd(f"{CLI} list files -p {PROJECT_NAME}") == 0
84
+ assert run_cmd(f"{CLI} list files -p {PROJECT_NAME} -m {secrets.token_hex(8)}") == 0
85
+ assert run_cmd(f"{CLI} list files") == 0
86
+ assert run_cmd(f"{CLI} list files -p {secrets.token_hex(8)}") == 0
87
+ assert run_cmd(f'{CLI} list files -p "*" -m "*" "*"') == 0
88
+
89
+
90
+ @pytest.mark.slow
91
+ def test_list_missions(api):
92
+ assert api
93
+ assert run_cmd(f"{CLI} list missions -p {PROJECT_NAME}") == 0
94
+ assert run_cmd(f"{CLI} list missions -p {secrets.token_hex(8)}") == 0
95
+ assert run_cmd(f"{CLI} list missions") == 0
96
+ assert run_cmd(f'{CLI} list missions -p "*" "*"') == 0
97
+
98
+
99
+ @pytest.mark.slow
100
+ def test_list_projects(api):
101
+ assert api
102
+ assert run_cmd(f"{CLI} list projects") == 0
103
+ assert run_cmd(f"{CLI} list projects {PROJECT_NAME}") == 0
104
+ assert run_cmd(f"{CLI} list projects {secrets.token_hex(8)}") == 0
105
+ assert run_cmd(f'{CLI} list projects "*"') == 0
@@ -0,0 +1,137 @@
1
+ from __future__ import annotations
2
+
3
+ from uuid import uuid4
4
+
5
+ import pytest
6
+ from kleinkram.resources import check_mission_spec_is_creatable
7
+ from kleinkram.resources import check_project_spec_is_creatable
8
+ from kleinkram.resources import InvalidMissionSpec
9
+ from kleinkram.resources import InvalidProjectSpec
10
+ from kleinkram.resources import mission_spec_is_unique
11
+ from kleinkram.resources import MissionSpec
12
+ from kleinkram.resources import project_spec_is_unique
13
+ from kleinkram.resources import ProjectSpec
14
+
15
+
16
+ @pytest.mark.parametrize(
17
+ "spec, expected",
18
+ [
19
+ pytest.param(MissionSpec(), False, id="match all"),
20
+ pytest.param(MissionSpec(patterns=["*"]), False, id="mission name match all"),
21
+ pytest.param(
22
+ MissionSpec(patterns=["test"]),
23
+ False,
24
+ id="mission name without project",
25
+ ),
26
+ pytest.param(
27
+ MissionSpec(patterns=["test"], project_spec=ProjectSpec()),
28
+ False,
29
+ id="mission name with non-unique project",
30
+ ),
31
+ pytest.param(
32
+ MissionSpec(
33
+ patterns=["test"],
34
+ project_spec=ProjectSpec(ids=[uuid4()]),
35
+ ),
36
+ True,
37
+ id="mission name with unique project",
38
+ ),
39
+ pytest.param(
40
+ MissionSpec(ids=[uuid4()]),
41
+ True,
42
+ id="mission by id",
43
+ ),
44
+ pytest.param(
45
+ MissionSpec(ids=[uuid4(), uuid4()]),
46
+ False,
47
+ id="multiple mission ids",
48
+ ),
49
+ ],
50
+ )
51
+ def test_mission_spec_is_unique(spec, expected):
52
+ assert mission_spec_is_unique(spec) == expected
53
+
54
+
55
+ @pytest.mark.parametrize(
56
+ "spec, expected",
57
+ [
58
+ pytest.param(ProjectSpec(), False, id="match all"),
59
+ pytest.param(ProjectSpec(patterns=["*"]), False, id="project name match all"),
60
+ pytest.param(
61
+ ProjectSpec(patterns=["test"]),
62
+ True,
63
+ id="project name",
64
+ ),
65
+ pytest.param(
66
+ ProjectSpec(ids=[uuid4()]),
67
+ True,
68
+ id="project by id",
69
+ ),
70
+ pytest.param(
71
+ ProjectSpec(ids=[uuid4(), uuid4()]),
72
+ False,
73
+ id="multiple project ids",
74
+ ),
75
+ ],
76
+ )
77
+ def test_project_spec_is_unique(spec, expected):
78
+ assert project_spec_is_unique(spec) == expected
79
+
80
+
81
+ @pytest.mark.parametrize(
82
+ "spec, valid",
83
+ [
84
+ pytest.param(
85
+ MissionSpec(patterns=["test"], project_spec=ProjectSpec()),
86
+ False,
87
+ id="non-unique project",
88
+ ),
89
+ pytest.param(
90
+ MissionSpec(
91
+ patterns=["test"],
92
+ project_spec=ProjectSpec(ids=[uuid4()]),
93
+ ),
94
+ True,
95
+ id="valid spec",
96
+ ),
97
+ pytest.param(
98
+ MissionSpec(ids=[uuid4()]),
99
+ False,
100
+ id="mission by id",
101
+ ),
102
+ ],
103
+ )
104
+ def test_check_mission_spec_is_createable(spec, valid):
105
+ if not valid:
106
+ with pytest.raises(InvalidMissionSpec):
107
+ check_mission_spec_is_creatable(spec)
108
+ else:
109
+ check_mission_spec_is_creatable(spec)
110
+
111
+
112
+ @pytest.mark.parametrize(
113
+ "spec, valid",
114
+ [
115
+ pytest.param(
116
+ ProjectSpec(patterns=["test"]),
117
+ True,
118
+ id="project name",
119
+ ),
120
+ pytest.param(
121
+ ProjectSpec(ids=[uuid4()]),
122
+ False,
123
+ id="project by id",
124
+ ),
125
+ pytest.param(
126
+ ProjectSpec(ids=[uuid4(), uuid4()]),
127
+ False,
128
+ id="multiple project ids",
129
+ ),
130
+ ],
131
+ )
132
+ def test_check_project_spec_is_creatable(spec, valid):
133
+ if not valid:
134
+ with pytest.raises(InvalidProjectSpec):
135
+ check_project_spec_is_creatable(spec)
136
+ else:
137
+ check_project_spec_is_creatable(spec)
tests/test_utils.py CHANGED
@@ -6,23 +6,28 @@ from uuid import uuid4
6
6
 
7
7
  import pytest
8
8
  from kleinkram.errors import FileTypeNotSupported
9
- from kleinkram.errors import InvalidFileSpec
10
- from kleinkram.errors import InvalidMissionSpec
11
- from kleinkram.models import FilesById
12
- from kleinkram.models import FilesByMission
13
- from kleinkram.models import MissionById
14
- from kleinkram.models import MissionByName
15
9
  from kleinkram.utils import b64_md5
16
10
  from kleinkram.utils import check_file_paths
17
11
  from kleinkram.utils import filtered_by_patterns
18
12
  from kleinkram.utils import get_filename
19
13
  from kleinkram.utils import get_filename_map
20
- from kleinkram.utils import get_valid_file_spec
21
- from kleinkram.utils import get_valid_mission_spec
22
14
  from kleinkram.utils import is_valid_uuid4
15
+ from kleinkram.utils import split_args
23
16
  from kleinkram.utils import to_name_or_uuid
24
17
 
25
18
 
19
+ def test_split_args():
20
+ uuid = uuid4()
21
+ assert split_args([str(uuid)]) == ([uuid], [])
22
+ assert split_args(["name"]) == ([], ["name"])
23
+ assert split_args([str(uuid), "name"]) == ([uuid], ["name"])
24
+ assert split_args(["name", str(uuid)]) == ([uuid], ["name"])
25
+ assert split_args(["name", "name"]) == ([], ["name", "name"])
26
+ assert split_args([str(uuid), str(uuid)]) == ([uuid, uuid], [])
27
+ assert split_args([]) == ([], [])
28
+ assert split_args(["*", str(uuid)]) == ([uuid], ["*"])
29
+
30
+
26
31
  def test_check_file_paths():
27
32
  with TemporaryDirectory() as temp_dir:
28
33
  exits_txt = Path(temp_dir) / "exists.txt"
@@ -114,57 +119,6 @@ def test_b64_md5():
114
119
  assert b64_md5(file) == "XrY7u+Ae7tCTyyK7j1rNww=="
115
120
 
116
121
 
117
- def test_get_valid_mission_spec():
118
- # only mission name
119
- with pytest.raises(InvalidMissionSpec):
120
- get_valid_mission_spec("mission")
121
-
122
- # only mission id
123
- id_ = uuid4()
124
- assert get_valid_mission_spec(id_) == MissionById(id_)
125
-
126
- # mission name and project name
127
- assert get_valid_mission_spec("mission", "project") == MissionByName(
128
- "mission", "project"
129
- )
130
-
131
- # mission name and project id
132
- project_id = uuid4()
133
- assert get_valid_mission_spec("mission", project_id) == MissionByName(
134
- "mission", project_id
135
- )
136
-
137
- # mission id and project name
138
- assert get_valid_mission_spec(id_, "project") == MissionById(id_)
139
-
140
-
141
- def test_get_valid_file_spec():
142
- # no information
143
- with pytest.raises(InvalidFileSpec):
144
- get_valid_file_spec([], None, None)
145
-
146
- # only file ids
147
- file_ids = [uuid4(), uuid4()]
148
- assert get_valid_file_spec(file_ids, None, None) == FilesById(file_ids)
149
-
150
- # only file names
151
- with pytest.raises(InvalidFileSpec):
152
- get_valid_file_spec(["foo"], None, None)
153
-
154
- # missing mission
155
- with pytest.raises(InvalidMissionSpec):
156
- get_valid_file_spec([], None, "project")
157
-
158
- # mission name and file names
159
- assert get_valid_file_spec([], "mission", "project") == FilesByMission(
160
- MissionByName("mission", "project"), []
161
- )
162
-
163
- assert get_valid_file_spec(
164
- file_ids + ["name"], "mission", "project"
165
- ) == FilesByMission(MissionByName("mission", "project"), file_ids + ["name"])
166
-
167
-
168
122
  def test_to_name_or_uuid():
169
123
  id_ = uuid4()
170
124
  not_id = "not an id"
@@ -1,33 +0,0 @@
1
- kleinkram/__init__.py,sha256=adI-FqfuuH56n8U-lJa3uZkH_saxi7dr4Hox_HBuf9A,107
2
- kleinkram/__main__.py,sha256=B9RiZxfO4jpCmWPUHyKJ7_EoZlEG4sPpH-nz7T_YhhQ,125
3
- kleinkram/_version.py,sha256=QYJyRTcqFcJj4qWYpqs7WcoOP6jxDMqyvxLY-cD6KcE,129
4
- kleinkram/app.py,sha256=C5NwoFJ4FsUZwx6h5PInjq6j-NveGBgfbpHQ9Vb8Igo,5553
5
- kleinkram/auth.py,sha256=QAwT3VWdHEv5cxNnRbZoVykYwdeaoZjtBQBBXfejFdQ,2953
6
- kleinkram/config.py,sha256=QZWBXOCRjXa-wcSynJkCaYSE_0kU85j2zsdp-miR-eU,4447
7
- kleinkram/consts.py,sha256=70GELDssDm-YeIbChBRTscnNRcyWRUDWWlYBjVWNLDk,205
8
- kleinkram/core.py,sha256=XmNhg1i520w-9et8r0LSQRsVN09gJgSXfyHRV1tu2rM,227
9
- kleinkram/enums.py,sha256=bX0H8_xkh_7DRycJYII8MTjHmjbcFW9ZJ3tzlzRhT2k,149
10
- kleinkram/errors.py,sha256=bZ92LLweQaorsKZWWsL7BAPxFxODQ01nEeenHOHKrv0,1200
11
- kleinkram/main.py,sha256=hmFuSnE2p-E4nZ2zDVToOsoELZhosLN0r4wsXnbmsas,168
12
- kleinkram/models.py,sha256=dOrvK-H6cW8tPbZUbBeE6MROp17c5hp5FeULKZRpZ3s,4329
13
- kleinkram/utils.py,sha256=F0SAnA_U9rjjKx0VSpoN_LU7bCv2c0p66mIvzvNnPYk,5577
14
- kleinkram/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- kleinkram/api/client.py,sha256=b1mUwpu7zrXVTNjTDfW8aA0hgmsisRIlMOqQTSbd7bg,2142
16
- kleinkram/api/file_transfer.py,sha256=LdXHsFkvNnZrpCYAEi17iQINAHFs4k3FeCrWzThiQJQ,9210
17
- kleinkram/api/routes.py,sha256=Os022OSIv7nYvrRMYfVkY03lsDSnVemFScoMQ8aXYt8,12825
18
- kleinkram/commands/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
19
- kleinkram/commands/download.py,sha256=393n9kaJJJmsAJGdPTrkd-H2giNsJuihr1JD1mdF6rk,3415
20
- kleinkram/commands/endpoint.py,sha256=VgaleKTev8Muu4OmS4tptbhrbl58u1UTAxEmoLBCQew,1642
21
- kleinkram/commands/list.py,sha256=bfuzWckZE46Y25EynOxZH0DPIXu_TJEBNFBoLbb4LfM,2926
22
- kleinkram/commands/mission.py,sha256=BXnGUnOBTSHZipy50P2NtornXUAxDCdyqmGpVUMzfxc,1751
23
- kleinkram/commands/project.py,sha256=q-kJ1YQr-Axo-Zl0qe2J7eGGgKlSbcdDjpAJIynRLaM,587
24
- kleinkram/commands/upload.py,sha256=Wc3OkmdtbrloTA4FaE2i1BD2gBcsjkR4T8G9qlIqe-M,4450
25
- kleinkram/commands/verify.py,sha256=CGndDooBIdnYGPpaaBRNvs-3SWoBUquzAJc-3YB6_Yo,3692
26
- tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- tests/test_utils.py,sha256=ob-7lNHP20hnB8E8O242l1IbWqSWvFYqTdYuPAbBoLU,5331
28
- kleinkram-0.38.1.dev20241119134715.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
29
- kleinkram-0.38.1.dev20241119134715.dist-info/METADATA,sha256=dxfT8PfVuADv5Fl-GSHx_zh8JcvLP3VTB50cfJmuTX4,2335
30
- kleinkram-0.38.1.dev20241119134715.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
31
- kleinkram-0.38.1.dev20241119134715.dist-info/entry_points.txt,sha256=SaB2l5aqhSr8gmaMw2kvQU90a8Bnl7PedU8cWYxkfYo,46
32
- kleinkram-0.38.1.dev20241119134715.dist-info/top_level.txt,sha256=G1Lj9vHAtZn402Ukkrfll-6BCmnDNy_HVtWeNvXzdDA,16
33
- kleinkram-0.38.1.dev20241119134715.dist-info/RECORD,,