kleinkram 0.36.3.dev20241113174857__py3-none-any.whl → 0.37.0__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/__init__.py +6 -0
- kleinkram/__main__.py +6 -0
- kleinkram/_version.py +6 -0
- kleinkram/api/__init__.py +0 -0
- kleinkram/api/client.py +65 -0
- kleinkram/api/file_transfer.py +337 -0
- kleinkram/api/routes.py +460 -0
- kleinkram/app.py +180 -0
- kleinkram/auth.py +96 -0
- kleinkram/commands/__init__.py +1 -0
- kleinkram/commands/download.py +103 -0
- kleinkram/commands/endpoint.py +62 -0
- kleinkram/commands/list.py +93 -0
- kleinkram/commands/mission.py +57 -0
- kleinkram/commands/project.py +24 -0
- kleinkram/commands/upload.py +138 -0
- kleinkram/commands/verify.py +117 -0
- kleinkram/config.py +171 -0
- kleinkram/consts.py +8 -1
- kleinkram/core.py +14 -0
- kleinkram/enums.py +10 -0
- kleinkram/errors.py +59 -0
- kleinkram/main.py +6 -489
- kleinkram/models.py +186 -0
- kleinkram/utils.py +179 -0
- {kleinkram-0.36.3.dev20241113174857.dist-info/licenses → kleinkram-0.37.0.dist-info}/LICENSE +1 -1
- kleinkram-0.37.0.dist-info/METADATA +113 -0
- kleinkram-0.37.0.dist-info/RECORD +33 -0
- {kleinkram-0.36.3.dev20241113174857.dist-info → kleinkram-0.37.0.dist-info}/WHEEL +2 -1
- kleinkram-0.37.0.dist-info/entry_points.txt +2 -0
- kleinkram-0.37.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/test_utils.py +153 -0
- kleinkram/api_client.py +0 -63
- kleinkram/auth/auth.py +0 -160
- kleinkram/endpoint/endpoint.py +0 -58
- kleinkram/error_handling.py +0 -177
- kleinkram/file/file.py +0 -144
- kleinkram/helper.py +0 -272
- kleinkram/mission/mission.py +0 -310
- kleinkram/project/project.py +0 -138
- kleinkram/queue/queue.py +0 -8
- kleinkram/tag/tag.py +0 -71
- kleinkram/topic/topic.py +0 -55
- kleinkram/user/user.py +0 -75
- kleinkram-0.36.3.dev20241113174857.dist-info/METADATA +0 -24
- kleinkram-0.36.3.dev20241113174857.dist-info/RECORD +0 -20
- kleinkram-0.36.3.dev20241113174857.dist-info/entry_points.txt +0 -2
kleinkram/project/project.py
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import httpx
|
|
2
|
-
import typer
|
|
3
|
-
from rich.console import Console
|
|
4
|
-
from rich.table import Table
|
|
5
|
-
from typing_extensions import Annotated
|
|
6
|
-
|
|
7
|
-
from kleinkram.api_client import AuthenticatedClient
|
|
8
|
-
|
|
9
|
-
project = typer.Typer(
|
|
10
|
-
name="project",
|
|
11
|
-
help="Project operations",
|
|
12
|
-
no_args_is_help=True,
|
|
13
|
-
context_settings={"help_option_names": ["-h", "--help"]},
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@project.command("list", help="List all projects")
|
|
18
|
-
def list_projects():
|
|
19
|
-
"""
|
|
20
|
-
List all projects.
|
|
21
|
-
"""
|
|
22
|
-
client = AuthenticatedClient()
|
|
23
|
-
response = client.get("/project/filtered")
|
|
24
|
-
response.raise_for_status()
|
|
25
|
-
projects = response.json()[0]
|
|
26
|
-
|
|
27
|
-
if len(projects) == 0:
|
|
28
|
-
print("No projects found. Create a new project using 'klein project create'")
|
|
29
|
-
return
|
|
30
|
-
|
|
31
|
-
stdout_console = Console(stderr=False)
|
|
32
|
-
stderr_console = Console(stderr=True)
|
|
33
|
-
stderr_console.print(f"\nfound {len(projects)} projects with the following UUIDs:")
|
|
34
|
-
|
|
35
|
-
# print the uuids to stdout for simple piping
|
|
36
|
-
for p in projects:
|
|
37
|
-
stderr_console.print(" - ", end="")
|
|
38
|
-
stdout_console.print(p["uuid"])
|
|
39
|
-
stderr_console.print("\n")
|
|
40
|
-
|
|
41
|
-
# Print a summary table using rich to stderr
|
|
42
|
-
table = Table(title="Projects", expand=True)
|
|
43
|
-
table.add_column("Project UUID", width=10)
|
|
44
|
-
table.add_column("Project Name", width=12)
|
|
45
|
-
table.add_column("Description")
|
|
46
|
-
for p in projects:
|
|
47
|
-
table.add_row(p["uuid"], p["name"], p["description"])
|
|
48
|
-
|
|
49
|
-
stderr_console.print(table)
|
|
50
|
-
stderr_console.print("\n")
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
@project.command("details", help="Get details of a project", no_args_is_help=True)
|
|
54
|
-
def project_details(
|
|
55
|
-
project_uuid: Annotated[
|
|
56
|
-
str, typer.Argument(help="UUID of the project to get details of")
|
|
57
|
-
]
|
|
58
|
-
):
|
|
59
|
-
"""
|
|
60
|
-
Get details of a project
|
|
61
|
-
"""
|
|
62
|
-
client = AuthenticatedClient()
|
|
63
|
-
response = client.get(f"/project/one?uuid={project_uuid}")
|
|
64
|
-
response.raise_for_status()
|
|
65
|
-
project = response.json()
|
|
66
|
-
|
|
67
|
-
stdout_console = Console(stderr=False)
|
|
68
|
-
stderr_console = Console(stderr=True)
|
|
69
|
-
stderr_console.print(
|
|
70
|
-
f"\nDetails of project with UUID {project_uuid}:", highlight=False
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
# Print the details to stderr using rich
|
|
74
|
-
table = Table(title="Project Details", expand=True)
|
|
75
|
-
table.add_column("Key", width=16)
|
|
76
|
-
table.add_column("Value")
|
|
77
|
-
for key, value in project.items():
|
|
78
|
-
|
|
79
|
-
access_name_map = {0: "READ", 10: "CREATE", 20: "WRITE", 30: "DELETE"}
|
|
80
|
-
|
|
81
|
-
if key == "project_accesses":
|
|
82
|
-
value = ", ".join(
|
|
83
|
-
[
|
|
84
|
-
f"'{access['accessGroup']['name']}' ({access_name_map[access['rights']]})"
|
|
85
|
-
for access in value
|
|
86
|
-
]
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
if key == "missions":
|
|
90
|
-
value = ", ".join([f"'{mission['name']}'" for mission in value])
|
|
91
|
-
|
|
92
|
-
if key == "creator":
|
|
93
|
-
value = value["name"]
|
|
94
|
-
|
|
95
|
-
table.add_row(key, f"{value}")
|
|
96
|
-
|
|
97
|
-
stderr_console.print(table)
|
|
98
|
-
stderr_console.print("\nList of missions:")
|
|
99
|
-
for mission in project["missions"]:
|
|
100
|
-
stderr_console.print(" - ", end="")
|
|
101
|
-
stdout_console.print(mission["uuid"])
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@project.command("create", no_args_is_help=True, help="Create a new project")
|
|
105
|
-
def create_project(
|
|
106
|
-
name: Annotated[str, typer.Option(help="Name of Project")],
|
|
107
|
-
description: Annotated[str, typer.Option(help="Description of Project")],
|
|
108
|
-
):
|
|
109
|
-
"""
|
|
110
|
-
Create a new project
|
|
111
|
-
"""
|
|
112
|
-
# Todo add required tags as option.
|
|
113
|
-
try:
|
|
114
|
-
url = "/project/create"
|
|
115
|
-
client = AuthenticatedClient()
|
|
116
|
-
response = client.post(
|
|
117
|
-
url, json={"name": name, "description": description, "requiredTags": []}
|
|
118
|
-
) # TODO: Add required tags as option
|
|
119
|
-
if response.status_code >= 400:
|
|
120
|
-
response_json = response.json()
|
|
121
|
-
response_text = response_json["message"]
|
|
122
|
-
raise ValueError(f"Failed to create project\n » {response_text}!")
|
|
123
|
-
|
|
124
|
-
stderr_console = Console(stderr=True)
|
|
125
|
-
stderr_console.print(f"Project '{name}' created successfully.")
|
|
126
|
-
|
|
127
|
-
stdout_console = Console(stderr=False)
|
|
128
|
-
stderr_console.print("\nProject UUID:\n - ", end="")
|
|
129
|
-
stdout_console.print(response.json()["uuid"])
|
|
130
|
-
|
|
131
|
-
except httpx.HTTPError as e:
|
|
132
|
-
print(f"Failed to create project: {e}")
|
|
133
|
-
raise e
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
@project.command("delete", help="Delete a project")
|
|
137
|
-
def delete_project():
|
|
138
|
-
raise NotImplementedError()
|
kleinkram/queue/queue.py
DELETED
kleinkram/tag/tag.py
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
from typing_extensions import Annotated
|
|
2
|
-
|
|
3
|
-
import httpx
|
|
4
|
-
import typer
|
|
5
|
-
from rich.console import Console
|
|
6
|
-
from rich.table import Table
|
|
7
|
-
|
|
8
|
-
from kleinkram.api_client import AuthenticatedClient
|
|
9
|
-
|
|
10
|
-
tag = typer.Typer(
|
|
11
|
-
name="tag",
|
|
12
|
-
help="Tag operations",
|
|
13
|
-
no_args_is_help=True,
|
|
14
|
-
context_settings={"help_option_names": ["-h", "--help"]},
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@tag.command("list-tag-types")
|
|
19
|
-
def tag_types(
|
|
20
|
-
verbose: Annotated[bool, typer.Option()] = False,
|
|
21
|
-
):
|
|
22
|
-
"""
|
|
23
|
-
List all tagtypes
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
try:
|
|
27
|
-
client = AuthenticatedClient()
|
|
28
|
-
response = client.get("/tag/all")
|
|
29
|
-
response.raise_for_status()
|
|
30
|
-
data = response.json()
|
|
31
|
-
|
|
32
|
-
if not data or len(data) == 0:
|
|
33
|
-
print("No tagtypes found")
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
if verbose:
|
|
37
|
-
table = Table("UUID", "Name", "Datatype")
|
|
38
|
-
for tagtype in data:
|
|
39
|
-
table.add_row(tagtype["uuid"], tagtype["name"], tagtype["datatype"])
|
|
40
|
-
else:
|
|
41
|
-
table = Table("Name", "Datatype")
|
|
42
|
-
for tagtype in data:
|
|
43
|
-
table.add_row(tagtype["name"], tagtype["datatype"])
|
|
44
|
-
console = Console()
|
|
45
|
-
console.print(table)
|
|
46
|
-
|
|
47
|
-
except:
|
|
48
|
-
print("Failed to fetch tagtypes")
|
|
49
|
-
raise Exception("Failed to fetch tagtypes")
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@tag.command("delete")
|
|
53
|
-
def delete_tag(
|
|
54
|
-
taguuid: Annotated[str, typer.Argument()],
|
|
55
|
-
):
|
|
56
|
-
"""
|
|
57
|
-
Delete a tag
|
|
58
|
-
"""
|
|
59
|
-
|
|
60
|
-
try:
|
|
61
|
-
client = AuthenticatedClient()
|
|
62
|
-
response = client.delete(f"/tag/{taguuid}")
|
|
63
|
-
if response.status_code < 400:
|
|
64
|
-
print("Deleted tag")
|
|
65
|
-
else:
|
|
66
|
-
print(response)
|
|
67
|
-
print("Failed to delete tag")
|
|
68
|
-
raise Exception("Failed to delete tag")
|
|
69
|
-
except httpx.HTTPError as e:
|
|
70
|
-
print("Failed to delete tag")
|
|
71
|
-
raise Exception("Failed to delete tag")
|
kleinkram/topic/topic.py
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
from typing_extensions import Annotated
|
|
2
|
-
|
|
3
|
-
import httpx
|
|
4
|
-
import typer
|
|
5
|
-
from rich.table import Table
|
|
6
|
-
|
|
7
|
-
from kleinkram.api_client import AuthenticatedClient
|
|
8
|
-
|
|
9
|
-
topic = typer.Typer(
|
|
10
|
-
name="topic",
|
|
11
|
-
help="Topic operations",
|
|
12
|
-
no_args_is_help=True,
|
|
13
|
-
context_settings={"help_option_names": ["-h", "--help"]},
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@topic.command("list")
|
|
18
|
-
def topics(
|
|
19
|
-
file: Annotated[str, typer.Option(help="Name of File")],
|
|
20
|
-
full: Annotated[
|
|
21
|
-
bool, typer.Option(help="As a table with additional parameters")
|
|
22
|
-
] = False,
|
|
23
|
-
# Todo add mission / project as optional argument as filenames are not unique or handle multiple files
|
|
24
|
-
):
|
|
25
|
-
"""
|
|
26
|
-
List topics for a file
|
|
27
|
-
|
|
28
|
-
Only makes sense with MCAP files as we don't associate topics with BAGs as that would be redundant.
|
|
29
|
-
"""
|
|
30
|
-
if file.endswith(".bag"):
|
|
31
|
-
print("BAG files generally do not have topics")
|
|
32
|
-
try:
|
|
33
|
-
url = "/file/byName"
|
|
34
|
-
client = AuthenticatedClient()
|
|
35
|
-
response = client.get(url, params={"name": file})
|
|
36
|
-
response.raise_for_status()
|
|
37
|
-
data = response.json()
|
|
38
|
-
if not full:
|
|
39
|
-
for topic in data["topics"]:
|
|
40
|
-
print(f" - {topic['name']}")
|
|
41
|
-
else:
|
|
42
|
-
table = Table("UUID", "name", "type", "nrMessages", "frequency")
|
|
43
|
-
for topic in data["topics"]:
|
|
44
|
-
table.add_row(
|
|
45
|
-
topic["uuid"],
|
|
46
|
-
topic["name"],
|
|
47
|
-
topic["type"],
|
|
48
|
-
topic["nrMessages"],
|
|
49
|
-
f"{topic['frequency']}",
|
|
50
|
-
)
|
|
51
|
-
print(table)
|
|
52
|
-
|
|
53
|
-
except httpx.HTTPError as e:
|
|
54
|
-
print(f"Failed")
|
|
55
|
-
raise e
|
kleinkram/user/user.py
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
|
|
3
|
-
import typer
|
|
4
|
-
from rich.console import Console
|
|
5
|
-
from rich.table import Table
|
|
6
|
-
from typing_extensions import Annotated
|
|
7
|
-
|
|
8
|
-
from kleinkram.api_client import AuthenticatedClient
|
|
9
|
-
|
|
10
|
-
user = typer.Typer(
|
|
11
|
-
name="users",
|
|
12
|
-
help="User operations",
|
|
13
|
-
no_args_is_help=True,
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@user.command("list")
|
|
18
|
-
def users():
|
|
19
|
-
"""List all users"""
|
|
20
|
-
|
|
21
|
-
client = AuthenticatedClient()
|
|
22
|
-
response = client.get("/user/all")
|
|
23
|
-
response.raise_for_status()
|
|
24
|
-
data = response.json()
|
|
25
|
-
|
|
26
|
-
console = Console(file=sys.stderr)
|
|
27
|
-
console_stdout = Console(file=sys.stdout)
|
|
28
|
-
|
|
29
|
-
####
|
|
30
|
-
# Print user UUIDs for command piping
|
|
31
|
-
####
|
|
32
|
-
console.print("\nUser UUIDs: ")
|
|
33
|
-
for _user in data:
|
|
34
|
-
console.print(" - ", end="")
|
|
35
|
-
console_stdout.print(_user["uuid"])
|
|
36
|
-
console.print("\n")
|
|
37
|
-
|
|
38
|
-
####
|
|
39
|
-
# Print table of the users
|
|
40
|
-
####
|
|
41
|
-
table = Table("UUID", "Name", "Email", "Role", expand=True, highlight=False)
|
|
42
|
-
for _user in data:
|
|
43
|
-
table.add_row(_user["uuid"], _user["name"], _user["email"], _user["role"])
|
|
44
|
-
console.print(table)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
@user.command("info")
|
|
48
|
-
def user_info():
|
|
49
|
-
"""Get logged in user info"""
|
|
50
|
-
client = AuthenticatedClient()
|
|
51
|
-
response = client.get("/user/me")
|
|
52
|
-
response.raise_for_status()
|
|
53
|
-
data = response.json()
|
|
54
|
-
|
|
55
|
-
# print prettified user info
|
|
56
|
-
console = Console()
|
|
57
|
-
console.print(data)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@user.command("promote")
|
|
61
|
-
def promote(email: Annotated[str, typer.Option()]):
|
|
62
|
-
"""Promote another user to admin"""
|
|
63
|
-
client = AuthenticatedClient()
|
|
64
|
-
response = client.post("/user/promote", json={"email": email})
|
|
65
|
-
response.raise_for_status()
|
|
66
|
-
print("User promoted.")
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
@user.command("demote")
|
|
70
|
-
def demote(email: Annotated[str, typer.Option()]):
|
|
71
|
-
"""Demote another user from admin"""
|
|
72
|
-
client = AuthenticatedClient()
|
|
73
|
-
response = client.post("/user/demote", json={"email": email})
|
|
74
|
-
response.raise_for_status()
|
|
75
|
-
print("User demoted.")
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: kleinkram
|
|
3
|
-
Version: 0.36.3.dev20241113174857
|
|
4
|
-
Summary: A CLI for the ETH project kleinkram
|
|
5
|
-
Project-URL: Homepage, https://github.com/leggedrobotics/kleinkram
|
|
6
|
-
Project-URL: Issues, https://github.com/leggedrobotics/kleinkram/issues
|
|
7
|
-
Author-email: Johann Schwabe <jschwab@ethz.ch>
|
|
8
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
-
Classifier: Operating System :: OS Independent
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Requires-Python: >=3.7
|
|
12
|
-
Requires-Dist: boto3
|
|
13
|
-
Requires-Dist: botocore
|
|
14
|
-
Requires-Dist: httpx
|
|
15
|
-
Requires-Dist: requests
|
|
16
|
-
Requires-Dist: setuptools
|
|
17
|
-
Requires-Dist: tqdm
|
|
18
|
-
Requires-Dist: typer
|
|
19
|
-
Description-Content-Type: text/markdown
|
|
20
|
-
|
|
21
|
-
# Kleinkram: CLI
|
|
22
|
-
|
|
23
|
-
Used as an alternative to the webtool at https://datasets.leggedrobotics.com/ \
|
|
24
|
-
Use --help to get an overview over available commands.
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
kleinkram/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
kleinkram/api_client.py,sha256=1GPsM-XFbPYEKP7RfWmzMTwxRqnVh4wtHVuW25KT8kA,2264
|
|
3
|
-
kleinkram/consts.py,sha256=pm_6OuQcO-tYcRhwauTtyRRsuYY0y0yb6EGuIl49LnI,50
|
|
4
|
-
kleinkram/error_handling.py,sha256=vvNtXSOnXs4b-aYEUIA0GVQWXLRW5I5FtNE1PZPHEPc,4704
|
|
5
|
-
kleinkram/helper.py,sha256=ELvs-p7zpJUP_rtTIVpcUCTz0D4WegoUZQ11UqUrUkg,9288
|
|
6
|
-
kleinkram/main.py,sha256=uEaAgUiqfq8Tc0iHA7OFcG_0_ymrgeogBt7uBAcWvqM,18083
|
|
7
|
-
kleinkram/auth/auth.py,sha256=w3-TsxWxURzLQ3_p43zgV4Rlh4dVL_WqI6HG2aes-b4,4991
|
|
8
|
-
kleinkram/endpoint/endpoint.py,sha256=WmHUH10_OSZUMrovh2yBeth9dBcn0yE7PxnnD4yPW-Y,1582
|
|
9
|
-
kleinkram/file/file.py,sha256=1IRXTxGGH5tIvvmMoee5jvmN4QGyIJSJ2xtHraHGFHE,5390
|
|
10
|
-
kleinkram/mission/mission.py,sha256=2S8Xopb45fr2y21FrUlABGXtklo9BvY3B-yUFCzLIJI,9790
|
|
11
|
-
kleinkram/project/project.py,sha256=4BOT3iOZZnMrZuALzBxQ5r-8dC8eZkel1OjxUFzK0w4,4336
|
|
12
|
-
kleinkram/queue/queue.py,sha256=MaLBjAu8asi9BkPvbbT-5AobCcpy3ex5rxM1kHpRINA,181
|
|
13
|
-
kleinkram/tag/tag.py,sha256=JSHbDPVfsvP34MuQhw__DPQk-Bah5G9BgwYsj_K_JGc,1805
|
|
14
|
-
kleinkram/topic/topic.py,sha256=IaXhrIHcJ3FSIr0WC-N7u9fkz-lAvSBgQklTX67t0Yc,1641
|
|
15
|
-
kleinkram/user/user.py,sha256=SzUM-CTTmC3TYCNt4Crizc7n3Rpf2ObJeNWEeEmMfpo,1893
|
|
16
|
-
kleinkram-0.36.3.dev20241113174857.dist-info/METADATA,sha256=Bc8CeQycvvxA24Hn9zXBvUl0_5HdX9Ulq5nrs0j04yc,823
|
|
17
|
-
kleinkram-0.36.3.dev20241113174857.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
18
|
-
kleinkram-0.36.3.dev20241113174857.dist-info/entry_points.txt,sha256=RHXtRzcreVHImatgjhQwZQ6GdJThElYjHEWcR1BPXUI,45
|
|
19
|
-
kleinkram-0.36.3.dev20241113174857.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
|
20
|
-
kleinkram-0.36.3.dev20241113174857.dist-info/RECORD,,
|