kleinkram 0.26.1.dev20241008105540__tar.gz → 0.27.0.dev20241008141236__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 (24) hide show
  1. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/PKG-INFO +1 -1
  2. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/pyproject.toml +1 -1
  3. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/error_handling.py +7 -6
  4. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/file/file.py +49 -1
  5. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/mission/mission.py +1 -1
  6. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/.gitignore +0 -0
  7. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/LICENSE +0 -0
  8. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/README.md +0 -0
  9. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/deploy.sh +0 -0
  10. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/dev.sh +0 -0
  11. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/requirements.txt +0 -0
  12. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/klein.py +0 -0
  13. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/__init__.py +0 -0
  14. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/api_client.py +0 -0
  15. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/auth/auth.py +0 -0
  16. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/consts.py +0 -0
  17. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/endpoint/endpoint.py +0 -0
  18. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/helper.py +0 -0
  19. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/main.py +0 -0
  20. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/project/project.py +0 -0
  21. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/queue/queue.py +0 -0
  22. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/tag/tag.py +0 -0
  23. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/topic/topic.py +0 -0
  24. {kleinkram-0.26.1.dev20241008105540 → kleinkram-0.27.0.dev20241008141236}/src/kleinkram/user/user.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kleinkram
3
- Version: 0.26.1.dev20241008105540
3
+ Version: 0.27.0.dev20241008141236
4
4
  Summary: A CLI for the ETH project kleinkram
5
5
  Project-URL: Homepage, https://github.com/leggedrobotics/kleinkram
6
6
  Project-URL: Issues, https://github.com/leggedrobotics/kleinkram/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "kleinkram"
7
- version = "0.26.1-dev20241008105540"
7
+ version = "0.27.0-dev20241008141236"
8
8
  description = "A CLI for the ETH project kleinkram"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.7"
@@ -1,3 +1,4 @@
1
+ import sys
1
2
  import typing
2
3
 
3
4
  import typer
@@ -20,7 +21,7 @@ class AccessDeniedException(Exception):
20
21
 
21
22
 
22
23
  def not_yet_implemented_handler(e: Exception):
23
- console = Console()
24
+ console = Console(file=sys.stderr)
24
25
  panel = Panel(
25
26
  "This feature is not yet implemented, please check for updates.",
26
27
  title="Not Yet Implemented",
@@ -34,7 +35,7 @@ def not_yet_implemented_handler(e: Exception):
34
35
 
35
36
 
36
37
  def not_authenticated_handler(e: NotAuthenticatedException):
37
- console = Console()
38
+ console = Console(file=sys.stderr)
38
39
  panel = Panel(
39
40
  f"{e.message}\n » Please run 'klein login' to authenticate.",
40
41
  title="Not Authenticated",
@@ -48,7 +49,7 @@ def not_authenticated_handler(e: NotAuthenticatedException):
48
49
 
49
50
 
50
51
  def access_denied_handler(e: AccessDeniedException):
51
- console = Console()
52
+ console = Console(file=sys.stderr)
52
53
  panel = Panel(
53
54
  f"{e.message}\n » API Response: {e.api_error}",
54
55
  title="Access Denied",
@@ -62,7 +63,7 @@ def access_denied_handler(e: AccessDeniedException):
62
63
 
63
64
 
64
65
  def value_error_handler(e: Exception):
65
- console = Console()
66
+ console = Console(file=sys.stderr)
66
67
  panel = Panel(
67
68
  str(e),
68
69
  title="Invalid Argument",
@@ -76,7 +77,7 @@ def value_error_handler(e: Exception):
76
77
 
77
78
 
78
79
  def http_status_error_handler(e: HTTPStatusError):
79
- console = Console()
80
+ console = Console(file=sys.stderr)
80
81
  panel = Panel(
81
82
  f"An HTTP error occurred: {e}\n\n » Please report this error to the developers.",
82
83
  title="HTTP Status Error",
@@ -90,7 +91,7 @@ def http_status_error_handler(e: HTTPStatusError):
90
91
 
91
92
 
92
93
  def remote_down_handler(e: Exception):
93
- console = Console()
94
+ console = Console(file=sys.stderr)
94
95
  panel = Panel(
95
96
  f"An error occurred while communicating with the remote server: {e}\n"
96
97
  f"\n » The server may be down or unreachable; please try again.",
@@ -1,5 +1,5 @@
1
1
  import os
2
- from typing_extensions import Optional, Annotated
2
+ from typing_extensions import Optional, Annotated, List
3
3
 
4
4
  import httpx
5
5
  import requests
@@ -15,6 +15,54 @@ file = typer.Typer(
15
15
  context_settings={"help_option_names": ["-h", "--help"]},
16
16
  )
17
17
 
18
+ @file.command('download')
19
+ def download_file(
20
+ file_uuid: Annotated[List[str], typer.Option( help="UUIDs of the files")],
21
+ local_path: Annotated[str, typer.Option( prompt=True, help="Local path to save the file",)],
22
+ ):
23
+ """
24
+ Download files by UUIDs to a local path.\n
25
+ Examples:\n
26
+ klein file download --file-uuid="9d5a9..." --file-uuid="9833f..." --local-path="~/Downloads" \n
27
+ klein file download --file-uuid="9d5a9..." --local-path="~/Downloads/example.bag"
28
+
29
+ """
30
+ client = AuthenticatedClient()
31
+ url = f"/file/download"
32
+
33
+ fixed_local_path = os.path.expanduser(local_path)
34
+
35
+ isDir = os.path.isdir(fixed_local_path)
36
+ chunk_size = 1024 * 100 # 100 KB chunks, adjust size if needed
37
+
38
+
39
+ for file in file_uuid:
40
+ response = client.get(
41
+ url,
42
+ params={"uuid": file, "expires": True},
43
+ )
44
+ if response.status_code >= 400:
45
+ raise AccessDeniedException(
46
+ f"Failed to download file: {response.json()['message']}",
47
+ "Status Code: " + str(response.status_code),
48
+ )
49
+ download_url = response.text
50
+ if isDir:
51
+ filename = download_url.split("/")[6].split("?")[0] # Trust me bro
52
+ filepath = os.path.join(fixed_local_path, filename)
53
+ elif not isDir and len(file_uuid) == 1:
54
+ filepath = fixed_local_path
55
+ else:
56
+ raise ValueError("Multiple files can only be downloaded to a directory")
57
+ if os.path.exists(filepath):
58
+ raise FileExistsError(f"File already exists: {filepath}")
59
+ print(f"Downloading to: {filepath}")
60
+ filestream = requests.get(download_url, stream=True)
61
+ with open(filepath, "wb") as f:
62
+ for chunk in filestream.iter_content(chunk_size=chunk_size):
63
+ if chunk: # Filter out keep-alive new chunks
64
+ f.write(chunk)
65
+ print(f"Completed")
18
66
 
19
67
  @file.command("list")
20
68
  def list_files(
@@ -192,7 +192,7 @@ def download(
192
192
  print(f" - {filename}")
193
193
 
194
194
  response = requests.get(path, stream=True) # Enable streaming mode
195
- chunk_size = 1024 # 1 KB chunks, adjust size if needed
195
+ chunk_size = 1024 * 100 # 100 KB chunks, adjust size if needed
196
196
 
197
197
  # Open the file for writing in binary mode
198
198
  with open(os.path.join(local_path, filename), "wb") as f: