kleinkram 0.37.0.dev20241118113347__py3-none-any.whl → 0.37.0.dev20241119090040__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/routes.py CHANGED
@@ -25,11 +25,11 @@ from kleinkram.models import MissionById
25
25
  from kleinkram.models import MissionByName
26
26
  from kleinkram.models import Project
27
27
  from kleinkram.models import TagType
28
+ from kleinkram.utils import filtered_by_patterns
28
29
  from kleinkram.utils import is_valid_uuid4
29
30
 
30
31
 
31
- # TODO: change to 10000
32
- MAX_PAGINATION = 1_000
32
+ MAX_PAGINATION = 10_000
33
33
 
34
34
  TEMP_CREDS = "/file/temporaryAccess"
35
35
  CLAIM_ADMIN = "/user/claimAdmin"
@@ -384,10 +384,16 @@ def get_files_by_file_spec(
384
384
  raise ValueError("mission not found")
385
385
 
386
386
  if spec.files:
387
+ file_ids = [id for id_ in spec.files if isinstance(id_, UUID)]
388
+ file_names = filtered_by_patterns(
389
+ [file.name for file in parsed_mission.files],
390
+ [name for name in spec.files if isinstance(name, str)],
391
+ )
392
+
387
393
  filtered = [
388
- f
389
- for f in parsed_mission.files
390
- if f.id in spec.files or f.name in spec.files
394
+ file
395
+ for file in parsed_mission.files
396
+ if file.id in file_ids or file.name in file_names
391
397
  ]
392
398
  return filtered
393
399
 
@@ -5,16 +5,19 @@ from typing import Optional
5
5
 
6
6
  import typer
7
7
  from kleinkram.api.client import AuthenticatedClient
8
- from kleinkram.api.routes import get_files
8
+ from kleinkram.api.routes import get_files_by_file_spec
9
9
  from kleinkram.api.routes import get_missions
10
10
  from kleinkram.api.routes import get_projects
11
11
  from kleinkram.config import get_shared_state
12
12
  from kleinkram.models import files_to_table
13
13
  from kleinkram.models import missions_to_table
14
14
  from kleinkram.models import projects_to_table
15
+ from kleinkram.utils import get_valid_file_spec
16
+ from kleinkram.utils import to_name_or_uuid
15
17
  from rich.console import Console
16
18
  from typer import BadParameter
17
19
 
20
+
18
21
  HELP = """\
19
22
  List projects, missions, or files.
20
23
  """
@@ -37,26 +40,32 @@ def _parse_metadata(raw: List[str]) -> dict:
37
40
 
38
41
  @list_typer.command()
39
42
  def files(
40
- project: Optional[str] = typer.Option(None, "--project", "-p", help="project name"),
41
- mission: Optional[str] = typer.Option(None, "--mission", "-m", help="mission name"),
42
- topics: List[str] = typer.Option(None, "--topics", "-t", help="topics"),
43
- metadata: Optional[List[str]] = typer.Argument(None, help="tag=value pairs"),
43
+ files: Optional[List[str]] = typer.Argument(
44
+ None, help="file names, ids or patterns"
45
+ ),
46
+ project: Optional[str] = typer.Option(
47
+ None, "--project", "-p", help="project name or id"
48
+ ),
49
+ mission: Optional[str] = typer.Option(
50
+ None, "--mission", "-m", help="mission name or id"
51
+ ),
44
52
  ) -> None:
45
53
  client = AuthenticatedClient()
46
54
 
47
- _topics = topics if topics else None
48
- _metadata = _parse_metadata(metadata or [])
55
+ _files = [to_name_or_uuid(f) for f in files or []]
56
+ _project = to_name_or_uuid(project) if project else None
57
+ _mission = to_name_or_uuid(mission) if mission else None
49
58
 
50
- files = get_files(
51
- client, project=project, mission=mission, tags=_metadata, topics=_topics
52
- )
59
+ client = AuthenticatedClient()
60
+ file_spec = get_valid_file_spec(_files, mission=_mission, project=_project)
61
+ parsed_files = get_files_by_file_spec(client, file_spec)
53
62
 
54
63
  if get_shared_state().verbose:
55
- table = files_to_table(files)
64
+ table = files_to_table(parsed_files)
56
65
  console = Console()
57
66
  console.print(table)
58
67
  else:
59
- for file in files:
68
+ for file in parsed_files:
60
69
  print(file.id)
61
70
 
62
71
 
kleinkram/utils.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import base64
4
- import glob
4
+ import fnmatch
5
5
  import hashlib
6
6
  import os
7
7
  import string
@@ -44,6 +44,14 @@ def check_file_paths(files: Sequence[Path]) -> None:
44
44
  )
45
45
 
46
46
 
47
+ def filtered_by_patterns(names: Sequence[str], patterns: List[str]) -> List[str]:
48
+ filtered = []
49
+ for name in names:
50
+ if any(fnmatch.fnmatch(name, p) for p in patterns):
51
+ filtered.append(name)
52
+ return filtered
53
+
54
+
47
55
  def raw_rich(*objects: Any, **kwargs: Any) -> str:
48
56
  """\
49
57
  accepts any object that Console.print can print
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kleinkram
3
- Version: 0.37.0.dev20241118113347
3
+ Version: 0.37.0.dev20241119090040
4
4
  Summary: give me your bags
5
5
  Author: Cyrill Püntener, Dominique Garmier, Johann Schwabe
6
6
  Classifier: Programming Language :: Python :: 3
@@ -10,24 +10,24 @@ kleinkram/enums.py,sha256=bX0H8_xkh_7DRycJYII8MTjHmjbcFW9ZJ3tzlzRhT2k,149
10
10
  kleinkram/errors.py,sha256=bZ92LLweQaorsKZWWsL7BAPxFxODQ01nEeenHOHKrv0,1200
11
11
  kleinkram/main.py,sha256=hmFuSnE2p-E4nZ2zDVToOsoELZhosLN0r4wsXnbmsas,168
12
12
  kleinkram/models.py,sha256=dOrvK-H6cW8tPbZUbBeE6MROp17c5hp5FeULKZRpZ3s,4329
13
- kleinkram/utils.py,sha256=72PuaARDOlrxTjh5sHS6llvZng2q78j4IpiUP1RG1qA,5335
13
+ kleinkram/utils.py,sha256=F0SAnA_U9rjjKx0VSpoN_LU7bCv2c0p66mIvzvNnPYk,5577
14
14
  kleinkram/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  kleinkram/api/client.py,sha256=b1mUwpu7zrXVTNjTDfW8aA0hgmsisRIlMOqQTSbd7bg,2142
16
16
  kleinkram/api/file_transfer.py,sha256=LdXHsFkvNnZrpCYAEi17iQINAHFs4k3FeCrWzThiQJQ,9210
17
- kleinkram/api/routes.py,sha256=ojAB5Kfnofw6oyeAe_9VS__-YahpWGsiBWl4jjbQO10,12537
17
+ kleinkram/api/routes.py,sha256=pjedtUCvfITumCh-EeTE7-RJzlcFgfRLswGMroF5ejY,12824
18
18
  kleinkram/commands/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
19
19
  kleinkram/commands/download.py,sha256=393n9kaJJJmsAJGdPTrkd-H2giNsJuihr1JD1mdF6rk,3415
20
20
  kleinkram/commands/endpoint.py,sha256=VgaleKTev8Muu4OmS4tptbhrbl58u1UTAxEmoLBCQew,1642
21
- kleinkram/commands/list.py,sha256=QEhD6mSDn_dVc9XI_5HpBrfjG93IowzFxH4rOyVHjCI,2666
21
+ kleinkram/commands/list.py,sha256=bfuzWckZE46Y25EynOxZH0DPIXu_TJEBNFBoLbb4LfM,2926
22
22
  kleinkram/commands/mission.py,sha256=BXnGUnOBTSHZipy50P2NtornXUAxDCdyqmGpVUMzfxc,1751
23
23
  kleinkram/commands/project.py,sha256=q-kJ1YQr-Axo-Zl0qe2J7eGGgKlSbcdDjpAJIynRLaM,587
24
24
  kleinkram/commands/upload.py,sha256=Wc3OkmdtbrloTA4FaE2i1BD2gBcsjkR4T8G9qlIqe-M,4450
25
25
  kleinkram/commands/verify.py,sha256=CGndDooBIdnYGPpaaBRNvs-3SWoBUquzAJc-3YB6_Yo,3692
26
26
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- tests/test_utils.py,sha256=1OOimNDLfLU5IWSwCtJRrXLw4SCbEe5rV4Z2XA7wCiU,4611
28
- kleinkram-0.37.0.dev20241118113347.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
29
- kleinkram-0.37.0.dev20241118113347.dist-info/METADATA,sha256=yx6jAxZ0HbqTl09cmOPiGhh8NRBRlsOt0jF2Dep-fZc,2335
30
- kleinkram-0.37.0.dev20241118113347.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
31
- kleinkram-0.37.0.dev20241118113347.dist-info/entry_points.txt,sha256=SaB2l5aqhSr8gmaMw2kvQU90a8Bnl7PedU8cWYxkfYo,46
32
- kleinkram-0.37.0.dev20241118113347.dist-info/top_level.txt,sha256=G1Lj9vHAtZn402Ukkrfll-6BCmnDNy_HVtWeNvXzdDA,16
33
- kleinkram-0.37.0.dev20241118113347.dist-info/RECORD,,
27
+ tests/test_utils.py,sha256=ob-7lNHP20hnB8E8O242l1IbWqSWvFYqTdYuPAbBoLU,5331
28
+ kleinkram-0.37.0.dev20241119090040.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
29
+ kleinkram-0.37.0.dev20241119090040.dist-info/METADATA,sha256=HYyAomahzudM9SZ7vzgH-F_S_jQwOesobHZURUkGW3A,2335
30
+ kleinkram-0.37.0.dev20241119090040.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
31
+ kleinkram-0.37.0.dev20241119090040.dist-info/entry_points.txt,sha256=SaB2l5aqhSr8gmaMw2kvQU90a8Bnl7PedU8cWYxkfYo,46
32
+ kleinkram-0.37.0.dev20241119090040.dist-info/top_level.txt,sha256=G1Lj9vHAtZn402Ukkrfll-6BCmnDNy_HVtWeNvXzdDA,16
33
+ kleinkram-0.37.0.dev20241119090040.dist-info/RECORD,,
tests/test_utils.py CHANGED
@@ -14,6 +14,7 @@ from kleinkram.models import MissionById
14
14
  from kleinkram.models import MissionByName
15
15
  from kleinkram.utils import b64_md5
16
16
  from kleinkram.utils import check_file_paths
17
+ from kleinkram.utils import filtered_by_patterns
17
18
  from kleinkram.utils import get_filename
18
19
  from kleinkram.utils import get_filename_map
19
20
  from kleinkram.utils import get_valid_file_spec
@@ -47,6 +48,25 @@ def test_check_file_paths():
47
48
  assert check_file_paths([exists_bag, exits_mcap]) is None
48
49
 
49
50
 
51
+ @pytest.mark.parametrize(
52
+ "names, patterns, expected",
53
+ [
54
+ pytest.param(["a.bag", "b.mcap"], ["*.bag"], ["a.bag"], id="one pattern"),
55
+ pytest.param(["a", "b", "c"], ["*"], ["a", "b", "c"], id="match all"),
56
+ pytest.param(["a", "b", "c"], ["*.bag"], [], id="no match"),
57
+ pytest.param(
58
+ ["a.bag", "b.mcap"],
59
+ ["*.bag", "*.mcap"],
60
+ ["a.bag", "b.mcap"],
61
+ id="all match",
62
+ ),
63
+ pytest.param(["a", "b", "c"], ["a", "b"], ["a", "b"], id="full name match"),
64
+ ],
65
+ )
66
+ def test_filtered_by_patterns(names, patterns, expected):
67
+ assert filtered_by_patterns(names, patterns) == expected
68
+
69
+
50
70
  def test_is_valid_uuid4():
51
71
  valid = "e896313b-2ab0-466b-b458-8911575fdee9"
52
72
  invalid = "hello world"