kleinkram 0.38.1.dev20250113080249__tar.gz → 0.38.1.dev20250207122632__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.

Files changed (56) hide show
  1. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/PKG-INFO +1 -1
  2. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/api/routes.py +0 -4
  3. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/app.py +7 -3
  4. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/error_handling.py +23 -0
  5. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/utils.py +6 -2
  6. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram.egg-info/PKG-INFO +1 -1
  7. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram.egg-info/SOURCES.txt +1 -0
  8. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/setup.cfg +1 -1
  9. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/testing/backend_fixtures.py +0 -2
  10. kleinkram-0.38.1.dev20250207122632/tests/test_error_handling.py +44 -0
  11. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/test_fixtures.py +5 -0
  12. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/test_utils.py +12 -0
  13. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/README.md +0 -0
  14. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/__init__.py +0 -0
  15. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/__main__.py +0 -0
  16. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/_version.py +0 -0
  17. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/api/__init__.py +0 -0
  18. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/api/client.py +0 -0
  19. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/api/deser.py +0 -0
  20. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/api/file_transfer.py +0 -0
  21. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/api/pagination.py +0 -0
  22. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/api/query.py +0 -0
  23. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/auth.py +0 -0
  24. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/__init__.py +0 -0
  25. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/_download.py +0 -0
  26. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/_endpoint.py +0 -0
  27. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/_list.py +0 -0
  28. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/_mission.py +0 -0
  29. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/_project.py +0 -0
  30. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/_upload.py +0 -0
  31. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/cli/_verify.py +0 -0
  32. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/config.py +0 -0
  33. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/core.py +0 -0
  34. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/errors.py +0 -0
  35. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/main.py +0 -0
  36. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/models.py +0 -0
  37. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/printing.py +0 -0
  38. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/py.typed +0 -0
  39. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/types.py +0 -0
  40. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram/wrappers.py +0 -0
  41. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram.egg-info/dependency_links.txt +0 -0
  42. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram.egg-info/entry_points.txt +0 -0
  43. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram.egg-info/requires.txt +0 -0
  44. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/kleinkram.egg-info/top_level.txt +0 -0
  45. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/pyproject.toml +0 -0
  46. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/requirements.txt +0 -0
  47. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/setup.py +0 -0
  48. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/testing/__init__.py +0 -0
  49. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/__init__.py +0 -0
  50. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/conftest.py +0 -0
  51. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/test_config.py +0 -0
  52. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/test_core.py +0 -0
  53. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/test_end_to_end.py +0 -0
  54. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/test_printing.py +0 -0
  55. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/test_query.py +0 -0
  56. {kleinkram-0.38.1.dev20250113080249 → kleinkram-0.38.1.dev20250207122632}/tests/test_wrappers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: kleinkram
3
- Version: 0.38.1.dev20250113080249
3
+ Version: 0.38.1.dev20250207122632
4
4
  Summary: give me your bags
5
5
  Author: Cyrill Püntener, Dominique Garmier, Johann Schwabe
6
6
  Classifier: Programming Language :: Python :: 3
@@ -75,7 +75,6 @@ FILE_ENDPOINT = "/file/many"
75
75
  MISSION_ENDPOINT = "/mission/many"
76
76
  PROJECT_ENDPOINT = "/project/many"
77
77
 
78
- MISSION_BY_NAME = "/mission/byName"
79
78
  TAG_TYPE_BY_NAME = "/tag/filtered"
80
79
 
81
80
 
@@ -109,7 +108,6 @@ def _project_query_to_params(
109
108
  params[Params.PROJECT_PATTERNS.value] = project_query.patterns
110
109
  if project_query.ids:
111
110
  params[Params.PROJECT_IDS.value] = list(map(str, project_query.ids))
112
- params = _handle_list_params(params)
113
111
  return params
114
112
 
115
113
 
@@ -119,7 +117,6 @@ def _mission_query_to_params(mission_query: MissionQuery) -> Dict[str, List[str]
119
117
  params[Params.MISSION_PATTERNS.value] = mission_query.patterns
120
118
  if mission_query.ids:
121
119
  params[Params.MISSION_IDS.value] = list(map(str, mission_query.ids))
122
- params = _handle_list_params(params)
123
120
  return params
124
121
 
125
122
 
@@ -129,7 +126,6 @@ def _file_query_to_params(file_query: FileQuery) -> Dict[str, List[str]]:
129
126
  params[Params.FILE_PATTERNS.value] = list(file_query.patterns)
130
127
  if file_query.ids:
131
128
  params[Params.FILE_IDS.value] = list(map(str, file_query.ids))
132
- params = _handle_list_params(params)
133
129
  return params
134
130
 
135
131
 
@@ -27,6 +27,7 @@ from kleinkram.cli._project import project_typer
27
27
  from kleinkram.cli._upload import upload_typer
28
28
  from kleinkram.cli._verify import verify_typer
29
29
  from kleinkram.cli.error_handling import ErrorHandledTyper
30
+ from kleinkram.cli.error_handling import display_error
30
31
  from kleinkram.config import Config
31
32
  from kleinkram.config import check_config_compatibility
32
33
  from kleinkram.config import get_config
@@ -109,9 +110,12 @@ app.add_typer(project_typer, name="project", rich_help_panel=CommandTypes.CRUD)
109
110
  # attach error handler to app
110
111
  @app.error_handler(Exception)
111
112
  def base_handler(exc: Exception) -> int:
112
- if not get_shared_state().debug:
113
- Console(file=sys.stderr).print(f"{type(exc).__name__}: {exc}", style="red")
114
- logger.error(format_traceback(exc))
113
+ shared_state = get_shared_state()
114
+
115
+ display_error(exc=exc, verbose=shared_state.verbose)
116
+ logger.error(format_traceback(exc))
117
+
118
+ if not shared_state.debug:
115
119
  return 1
116
120
  raise exc
117
121
 
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import sys
3
4
  from collections import OrderedDict
4
5
  from typing import Any
5
6
  from typing import Callable
@@ -7,6 +8,10 @@ from typing import Type
7
8
 
8
9
  import typer
9
10
  from click import ClickException
11
+ from rich.console import Console
12
+ from rich.panel import Panel
13
+
14
+ from kleinkram.utils import upper_camel_case_to_words
10
15
 
11
16
  ExceptionHandler = Callable[[Exception], int]
12
17
 
@@ -42,3 +47,21 @@ class ErrorHandledTyper(typer.Typer):
42
47
  exit_code = handler(e)
43
48
  raise SystemExit(exit_code)
44
49
  raise
50
+
51
+
52
+ def display_error(*, exc: Exception, verbose: bool) -> None:
53
+ split_exc_name = upper_camel_case_to_words(type(exc).__name__)
54
+
55
+ if verbose:
56
+ panel = Panel(
57
+ str(exc), # get the error message
58
+ title=" ".join(split_exc_name),
59
+ style="red",
60
+ border_style="bold",
61
+ )
62
+ Console(file=sys.stderr).print(panel)
63
+ else:
64
+ text = f"{type(exc).__name__}"
65
+ if str(exc):
66
+ text += f": {exc}"
67
+ print(text, file=sys.stderr)
@@ -1,8 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import base64
4
- import fnmatch
5
4
  import hashlib
5
+ import re
6
6
  import string
7
7
  import traceback
8
8
  from hashlib import md5
@@ -14,7 +14,6 @@ from typing import Optional
14
14
  from typing import Sequence
15
15
  from typing import Tuple
16
16
  from typing import TypeVar
17
- from typing import Union
18
17
  from uuid import UUID
19
18
 
20
19
  import yaml
@@ -55,6 +54,11 @@ def file_paths_from_files(
55
54
  }
56
55
 
57
56
 
57
+ def upper_camel_case_to_words(s: str) -> List[str]:
58
+ """split `s` given upper camel case to words"""
59
+ return re.sub("([a-z])([A-Z])", r"\1 \2", s).split()
60
+
61
+
58
62
  def split_args(args: Sequence[str]) -> Tuple[List[UUID], List[str]]:
59
63
  """\
60
64
  split a sequece of strings into a list of UUIDs and a list of names
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: kleinkram
3
- Version: 0.38.1.dev20250113080249
3
+ Version: 0.38.1.dev20250207122632
4
4
  Summary: give me your bags
5
5
  Author: Cyrill Püntener, Dominique Garmier, Johann Schwabe
6
6
  Classifier: Programming Language :: Python :: 3
@@ -47,6 +47,7 @@ tests/conftest.py
47
47
  tests/test_config.py
48
48
  tests/test_core.py
49
49
  tests/test_end_to_end.py
50
+ tests/test_error_handling.py
50
51
  tests/test_fixtures.py
51
52
  tests/test_printing.py
52
53
  tests/test_query.py
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = kleinkram
3
- version = 0.38.1-dev20250113080249
3
+ version = 0.38.1-dev20250207122632
4
4
  description = give me your bags
5
5
  long_description = file: README.md
6
6
  long_description_content_type = text/markdown
@@ -8,9 +8,7 @@ import pytest
8
8
 
9
9
  from kleinkram import create_mission
10
10
  from kleinkram import create_project
11
- from kleinkram import delete_mission
12
11
  from kleinkram import delete_project
13
- from kleinkram import list_files
14
12
  from kleinkram import list_missions
15
13
  from kleinkram import list_projects
16
14
  from kleinkram import upload
@@ -0,0 +1,44 @@
1
+ from __future__ import annotations
2
+
3
+ import pytest
4
+
5
+ from kleinkram.cli.error_handling import display_error
6
+
7
+
8
+ class MyException(Exception):
9
+ pass
10
+
11
+
12
+ def test_display_error_not_verbose(capsys):
13
+ exc = MyException("hello")
14
+
15
+ display_error(exc=exc, verbose=False)
16
+
17
+ out, err = capsys.readouterr()
18
+
19
+ assert out == ""
20
+ assert err == "MyException: hello\n"
21
+
22
+ exc = MyException()
23
+
24
+ display_error(exc=exc, verbose=False)
25
+
26
+ out, err = capsys.readouterr()
27
+
28
+ assert out == ""
29
+ assert err == "MyException\n"
30
+
31
+
32
+ def test_display_error_verbose(capsys):
33
+ exc = MyException("hello")
34
+
35
+ display_error(exc=exc, verbose=True)
36
+
37
+ out, err = capsys.readouterr()
38
+
39
+ assert out == ""
40
+ assert err == (
41
+ "╭──────────────────────────────── My Exception ────────────────────────────────╮\n"
42
+ "│ hello │\n"
43
+ "╰──────────────────────────────────────────────────────────────────────────────╯\n"
44
+ )
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import pytest
4
+
3
5
  from kleinkram import list_files
4
6
  from kleinkram import list_missions
5
7
  from kleinkram import list_projects
@@ -7,11 +9,13 @@ from testing.backend_fixtures import DATA_FILES
7
9
  from testing.backend_fixtures import PROJECT_DESCRIPTION
8
10
 
9
11
 
12
+ @pytest.mark.slow
10
13
  def test_project_fixture(project):
11
14
  assert list_projects(project_ids=[project.id])[0].id == project.id
12
15
  assert project.description == PROJECT_DESCRIPTION
13
16
 
14
17
 
18
+ @pytest.mark.slow
15
19
  def test_mission_fixture(mission, project):
16
20
  assert mission.project_id == project.id
17
21
  assert list_missions(mission_ids=[mission.id])[0].id == mission.id
@@ -23,6 +27,7 @@ def test_mission_fixture(mission, project):
23
27
  )
24
28
 
25
29
 
30
+ @pytest.mark.slow
26
31
  def test_empty_mission_fixture(empty_mission, project):
27
32
  assert empty_mission.project_id == project.id
28
33
  assert list_missions(mission_ids=[empty_mission.id])[0].id == empty_mission.id
@@ -17,6 +17,7 @@ from kleinkram.utils import parse_path_like
17
17
  from kleinkram.utils import parse_uuid_like
18
18
  from kleinkram.utils import singleton_list
19
19
  from kleinkram.utils import split_args
20
+ from kleinkram.utils import upper_camel_case_to_words
20
21
 
21
22
 
22
23
  def test_split_args():
@@ -135,3 +136,14 @@ def test_parse_uuid_like() -> None:
135
136
  def test_parse_path_like() -> None:
136
137
  assert parse_path_like("test") == Path("test")
137
138
  assert parse_path_like(Path("test")) == Path("test")
139
+
140
+
141
+ def test_upper_camel_case_to_words() -> None:
142
+ assert upper_camel_case_to_words("HelloWorld") == ["Hello", "World"]
143
+ assert upper_camel_case_to_words("HelloWorldAgain") == ["Hello", "World", "Again"]
144
+ assert upper_camel_case_to_words("Hello") == ["Hello"]
145
+ assert upper_camel_case_to_words("hello") == ["hello"]
146
+ assert upper_camel_case_to_words("") == []
147
+ assert upper_camel_case_to_words("not_camel_case") == ["not_camel_case"]
148
+ assert upper_camel_case_to_words("*#?-_") == ["*#?-_"]
149
+ assert upper_camel_case_to_words("helloWorld") == ["hello", "World"]