kscale 0.0.5__tar.gz → 0.0.7__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {kscale-0.0.5/kscale.egg-info → kscale-0.0.7}/PKG-INFO +6 -5
- {kscale-0.0.5 → kscale-0.0.7}/kscale/__init__.py +1 -1
- kscale-0.0.7/kscale/requirements.txt +10 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/api.py +5 -1
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/client.py +6 -3
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/pybullet.py +4 -1
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/urdf.py +26 -9
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/utils.py +15 -1
- {kscale-0.0.5 → kscale-0.0.7/kscale.egg-info}/PKG-INFO +6 -5
- kscale-0.0.7/kscale.egg-info/requires.txt +13 -0
- kscale-0.0.5/kscale/requirements.txt +0 -9
- kscale-0.0.5/kscale.egg-info/requires.txt +0 -12
- {kscale-0.0.5 → kscale-0.0.7}/LICENSE +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/MANIFEST.in +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/README.md +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/api.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/conf.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/py.typed +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/requirements-dev.txt +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/__init__.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/bullet/MANIFEST.in +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/cli.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/gen/__init__.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/store/gen/api.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/utils/__init__.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale/utils/api_base.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale.egg-info/SOURCES.txt +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale.egg-info/dependency_links.txt +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale.egg-info/entry_points.txt +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/kscale.egg-info/top_level.txt +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/pyproject.toml +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/setup.cfg +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/setup.py +0 -0
- {kscale-0.0.5 → kscale-0.0.7}/tests/test_dummy.py +0 -0
@@ -1,16 +1,17 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: kscale
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.7
|
4
4
|
Summary: The kscale project
|
5
5
|
Home-page: https://github.com/kscalelabs/kscale
|
6
6
|
Author: Benjamin Bolte
|
7
7
|
Requires-Python: >=3.11
|
8
8
|
Description-Content-Type: text/markdown
|
9
9
|
License-File: LICENSE
|
10
|
-
Requires-Dist: omegaconf
|
11
|
-
Requires-Dist: email_validator
|
12
|
-
Requires-Dist: httpx
|
13
|
-
Requires-Dist: requests
|
10
|
+
Requires-Dist: omegaconf
|
11
|
+
Requires-Dist: email_validator
|
12
|
+
Requires-Dist: httpx
|
13
|
+
Requires-Dist: requests
|
14
|
+
Requires-Dist: pydantic
|
14
15
|
Provides-Extra: dev
|
15
16
|
Requires-Dist: black; extra == "dev"
|
16
17
|
Requires-Dist: darglint; extra == "dev"
|
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
from pathlib import Path
|
4
4
|
|
5
|
-
from kscale.store.
|
5
|
+
from kscale.store.gen.api import UploadArtifactResponse
|
6
|
+
from kscale.store.urdf import download_urdf, upload_urdf
|
6
7
|
from kscale.utils.api_base import APIBase
|
7
8
|
|
8
9
|
|
@@ -18,3 +19,6 @@ class StoreAPI(APIBase):
|
|
18
19
|
|
19
20
|
async def urdf(self, artifact_id: str) -> Path:
|
20
21
|
return await download_urdf(artifact_id)
|
22
|
+
|
23
|
+
async def upload_urdf(self, listing_id: str, root_dir: Path) -> UploadArtifactResponse:
|
24
|
+
return await upload_urdf(listing_id, root_dir)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"""Defines a typed client for the K-Scale Store API."""
|
2
2
|
|
3
3
|
import logging
|
4
|
+
from pathlib import Path
|
4
5
|
from types import TracebackType
|
5
6
|
from typing import Any, Dict, Type
|
6
7
|
from urllib.parse import urljoin
|
@@ -14,17 +15,18 @@ from kscale.store.gen.api import (
|
|
14
15
|
SingleArtifactResponse,
|
15
16
|
UploadArtifactResponse,
|
16
17
|
)
|
17
|
-
from kscale.store.utils import
|
18
|
+
from kscale.store.utils import get_api_key, get_api_root
|
18
19
|
|
19
20
|
logger = logging.getLogger(__name__)
|
20
21
|
|
21
22
|
|
22
23
|
class KScaleStoreClient:
|
23
|
-
def __init__(self, base_url: str =
|
24
|
+
def __init__(self, base_url: str = get_api_root()) -> None:
|
24
25
|
self.base_url = base_url
|
25
26
|
self.client = httpx.AsyncClient(
|
26
27
|
base_url=self.base_url,
|
27
28
|
headers={"Authorization": f"Bearer {get_api_key()}"},
|
29
|
+
timeout=httpx.Timeout(30.0),
|
28
30
|
)
|
29
31
|
|
30
32
|
async def _request(
|
@@ -55,8 +57,9 @@ class KScaleStoreClient:
|
|
55
57
|
return SingleArtifactResponse(**data)
|
56
58
|
|
57
59
|
async def upload_artifact(self, listing_id: str, file_path: str) -> UploadArtifactResponse:
|
60
|
+
file_name = Path(file_path).name
|
58
61
|
with open(file_path, "rb") as f:
|
59
|
-
files = {"files": (
|
62
|
+
files = {"files": (file_name, f, "application/gzip")}
|
60
63
|
data = await self._request("POST", f"/artifacts/upload/{listing_id}", files=files)
|
61
64
|
return UploadArtifactResponse(**data)
|
62
65
|
|
@@ -27,7 +27,10 @@ async def main(args: Sequence[str] | None = None) -> None:
|
|
27
27
|
parsed_args = parser.parse_args(args)
|
28
28
|
|
29
29
|
# Gets the URDF path.
|
30
|
-
|
30
|
+
urdf_dir = await download_urdf(parsed_args.listing_id)
|
31
|
+
urdf_path = next(urdf_dir.glob("*.urdf"), None)
|
32
|
+
if urdf_path is None:
|
33
|
+
raise ValueError(f"No URDF found in {urdf_dir}")
|
31
34
|
|
32
35
|
try:
|
33
36
|
import pybullet as p # type: ignore[import-not-found]
|
@@ -14,13 +14,24 @@ import requests
|
|
14
14
|
|
15
15
|
from kscale.conf import Settings
|
16
16
|
from kscale.store.client import KScaleStoreClient
|
17
|
-
from kscale.store.gen.api import SingleArtifactResponse
|
17
|
+
from kscale.store.gen.api import SingleArtifactResponse, UploadArtifactResponse
|
18
18
|
from kscale.store.utils import get_api_key
|
19
19
|
|
20
20
|
# Set up logging
|
21
21
|
logging.basicConfig(level=logging.INFO)
|
22
22
|
logger = logging.getLogger(__name__)
|
23
23
|
|
24
|
+
ALLOWED_SUFFIXES = {
|
25
|
+
".urdf",
|
26
|
+
".mjcf",
|
27
|
+
".stl",
|
28
|
+
".obj",
|
29
|
+
".dae",
|
30
|
+
".png",
|
31
|
+
".jpg",
|
32
|
+
".jpeg",
|
33
|
+
}
|
34
|
+
|
24
35
|
|
25
36
|
def get_cache_dir() -> Path:
|
26
37
|
return Path(Settings.load().store.cache_dir).expanduser().resolve()
|
@@ -75,7 +86,7 @@ def create_tarball(folder_path: Path, output_filename: str, cache_dir: Path) ->
|
|
75
86
|
tarball_path = cache_dir / output_filename
|
76
87
|
with tarfile.open(tarball_path, "w:gz") as tar:
|
77
88
|
for file_path in folder_path.rglob("*"):
|
78
|
-
if file_path.is_file() and file_path.suffix.lower() in
|
89
|
+
if file_path.is_file() and file_path.suffix.lower() in ALLOWED_SUFFIXES:
|
79
90
|
tar.add(file_path, arcname=file_path.relative_to(folder_path))
|
80
91
|
logger.info("Added %s to tarball", file_path)
|
81
92
|
else:
|
@@ -128,18 +139,24 @@ async def remove_local_urdf(artifact_id: str) -> None:
|
|
128
139
|
raise
|
129
140
|
|
130
141
|
|
131
|
-
async def upload_urdf(listing_id: str,
|
132
|
-
parser = argparse.ArgumentParser(description="K-Scale URDF Store", add_help=False)
|
133
|
-
parser.add_argument("root_dir", type=Path, help="The path to the root directory to upload")
|
134
|
-
parsed_args = parser.parse_args(args)
|
135
|
-
|
136
|
-
root_dir = parsed_args.root_dir
|
142
|
+
async def upload_urdf(listing_id: str, root_dir: Path) -> UploadArtifactResponse:
|
137
143
|
tarball_path = create_tarball(root_dir, "robot.tgz", get_artifact_dir(listing_id))
|
138
144
|
|
139
145
|
async with KScaleStoreClient() as client:
|
140
146
|
response = await client.upload_artifact(listing_id, str(tarball_path))
|
141
147
|
|
142
148
|
logger.info("Uploaded artifacts: %s", [artifact.artifact_id for artifact in response.artifacts])
|
149
|
+
return response
|
150
|
+
|
151
|
+
|
152
|
+
async def upload_urdf_cli(listing_id: str, args: Sequence[str]) -> UploadArtifactResponse:
|
153
|
+
parser = argparse.ArgumentParser(description="K-Scale URDF Store", add_help=False)
|
154
|
+
parser.add_argument("root_dir", type=Path, help="The path to the root directory to upload")
|
155
|
+
parsed_args = parser.parse_args(args)
|
156
|
+
|
157
|
+
root_dir = parsed_args.root_dir
|
158
|
+
response = await upload_urdf(listing_id, root_dir)
|
159
|
+
return response
|
143
160
|
|
144
161
|
|
145
162
|
Command = Literal["download", "info", "upload", "remove-local"]
|
@@ -165,7 +182,7 @@ async def main(args: Sequence[str] | None = None) -> None:
|
|
165
182
|
await remove_local_urdf(id)
|
166
183
|
|
167
184
|
case "upload":
|
168
|
-
await
|
185
|
+
await upload_urdf_cli(id, remaining_args)
|
169
186
|
|
170
187
|
case _:
|
171
188
|
logger.error("Invalid command")
|
@@ -4,10 +4,24 @@ import os
|
|
4
4
|
|
5
5
|
from kscale.conf import Settings
|
6
6
|
|
7
|
-
|
7
|
+
|
8
|
+
def get_api_root() -> str:
|
9
|
+
"""Returns the base URL for the K-Scale Store API.
|
10
|
+
|
11
|
+
This can be overridden when targetting a different server.
|
12
|
+
|
13
|
+
Returns:
|
14
|
+
The base URL for the K-Scale Store API.
|
15
|
+
"""
|
16
|
+
return os.getenv("KSCALE_API_ROOT", "https://api.kscale.store")
|
8
17
|
|
9
18
|
|
10
19
|
def get_api_key() -> str:
|
20
|
+
"""Returns the API key for the K-Scale Store API.
|
21
|
+
|
22
|
+
Returns:
|
23
|
+
The API key for the K-Scale Store API.
|
24
|
+
"""
|
11
25
|
api_key = Settings.load().store.api_key
|
12
26
|
if api_key is None:
|
13
27
|
api_key = os.getenv("KSCALE_API_KEY")
|
@@ -1,16 +1,17 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: kscale
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.7
|
4
4
|
Summary: The kscale project
|
5
5
|
Home-page: https://github.com/kscalelabs/kscale
|
6
6
|
Author: Benjamin Bolte
|
7
7
|
Requires-Python: >=3.11
|
8
8
|
Description-Content-Type: text/markdown
|
9
9
|
License-File: LICENSE
|
10
|
-
Requires-Dist: omegaconf
|
11
|
-
Requires-Dist: email_validator
|
12
|
-
Requires-Dist: httpx
|
13
|
-
Requires-Dist: requests
|
10
|
+
Requires-Dist: omegaconf
|
11
|
+
Requires-Dist: email_validator
|
12
|
+
Requires-Dist: httpx
|
13
|
+
Requires-Dist: requests
|
14
|
+
Requires-Dist: pydantic
|
14
15
|
Provides-Extra: dev
|
15
16
|
Requires-Dist: black; extra == "dev"
|
16
17
|
Requires-Dist: darglint; extra == "dev"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|