kscale 0.1.5__tar.gz → 0.2.1__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. {kscale-0.1.5/kscale.egg-info → kscale-0.2.1}/PKG-INFO +1 -1
  2. {kscale-0.1.5 → kscale-0.2.1}/kscale/__init__.py +2 -2
  3. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/cli/robot_class.py +1 -1
  4. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/clients/client.py +4 -0
  5. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/clients/robot_class.py +37 -6
  6. {kscale-0.1.5 → kscale-0.2.1/kscale.egg-info}/PKG-INFO +1 -1
  7. {kscale-0.1.5 → kscale-0.2.1}/kscale.egg-info/SOURCES.txt +0 -2
  8. kscale-0.1.5/kscale/api.py +0 -11
  9. kscale-0.1.5/kscale/web/api.py +0 -18
  10. {kscale-0.1.5 → kscale-0.2.1}/LICENSE +0 -0
  11. {kscale-0.1.5 → kscale-0.2.1}/MANIFEST.in +0 -0
  12. {kscale-0.1.5 → kscale-0.2.1}/README.md +0 -0
  13. {kscale-0.1.5 → kscale-0.2.1}/kscale/artifacts/__init__.py +0 -0
  14. {kscale-0.1.5 → kscale-0.2.1}/kscale/artifacts/plane.obj +0 -0
  15. {kscale-0.1.5 → kscale-0.2.1}/kscale/artifacts/plane.urdf +0 -0
  16. {kscale-0.1.5 → kscale-0.2.1}/kscale/cli.py +0 -0
  17. {kscale-0.1.5 → kscale-0.2.1}/kscale/conf.py +0 -0
  18. {kscale-0.1.5 → kscale-0.2.1}/kscale/py.typed +0 -0
  19. {kscale-0.1.5 → kscale-0.2.1}/kscale/requirements-dev.txt +0 -0
  20. {kscale-0.1.5 → kscale-0.2.1}/kscale/requirements.txt +0 -0
  21. {kscale-0.1.5 → kscale-0.2.1}/kscale/utils/__init__.py +0 -0
  22. {kscale-0.1.5 → kscale-0.2.1}/kscale/utils/api_base.py +0 -0
  23. {kscale-0.1.5 → kscale-0.2.1}/kscale/utils/checksum.py +0 -0
  24. {kscale-0.1.5 → kscale-0.2.1}/kscale/utils/cli.py +0 -0
  25. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/__init__.py +0 -0
  26. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/cli/__init__.py +0 -0
  27. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/cli/robot.py +0 -0
  28. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/cli/token.py +0 -0
  29. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/cli/user.py +0 -0
  30. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/clients/__init__.py +0 -0
  31. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/clients/base.py +0 -0
  32. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/clients/robot.py +0 -0
  33. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/clients/user.py +0 -0
  34. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/gen/__init__.py +0 -0
  35. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/gen/api.py +0 -0
  36. {kscale-0.1.5 → kscale-0.2.1}/kscale/web/utils.py +0 -0
  37. {kscale-0.1.5 → kscale-0.2.1}/kscale.egg-info/dependency_links.txt +0 -0
  38. {kscale-0.1.5 → kscale-0.2.1}/kscale.egg-info/entry_points.txt +0 -0
  39. {kscale-0.1.5 → kscale-0.2.1}/kscale.egg-info/not-zip-safe +0 -0
  40. {kscale-0.1.5 → kscale-0.2.1}/kscale.egg-info/requires.txt +0 -0
  41. {kscale-0.1.5 → kscale-0.2.1}/kscale.egg-info/top_level.txt +0 -0
  42. {kscale-0.1.5 → kscale-0.2.1}/pyproject.toml +0 -0
  43. {kscale-0.1.5 → kscale-0.2.1}/setup.cfg +0 -0
  44. {kscale-0.1.5 → kscale-0.2.1}/setup.py +0 -0
  45. {kscale-0.1.5 → kscale-0.2.1}/tests/test_dummy.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: kscale
3
- Version: 0.1.5
3
+ Version: 0.2.1
4
4
  Summary: The kscale project
5
5
  Home-page: https://github.com/kscalelabs/kscale
6
6
  Author: Benjamin Bolte
@@ -1,9 +1,9 @@
1
1
  """Defines the common interface for the K-Scale Python API."""
2
2
 
3
- __version__ = "0.1.5"
3
+ __version__ = "0.2.1"
4
4
 
5
5
  from pathlib import Path
6
6
 
7
- from kscale.api import K
7
+ from kscale.web.clients.client import WWWClient as K
8
8
 
9
9
  ROOT_DIR = Path(__file__).parent
@@ -105,7 +105,7 @@ async def upload(class_name: str, urdf_file: str) -> None:
105
105
  async def download(class_name: str, no_cache: bool) -> None:
106
106
  """Downloads a URDF file from a robot class."""
107
107
  async with RobotClassClient() as client:
108
- urdf_file = await client.download_robot_class_urdf(class_name, cache=not no_cache)
108
+ urdf_file = await client.download_compressed_urdf(class_name, cache=not no_cache)
109
109
  click.echo(f"URDF downloaded: {click.style(urdf_file, fg='green')}")
110
110
 
111
111
 
@@ -1,10 +1,14 @@
1
1
  """Defines a unified client for the K-Scale WWW API."""
2
2
 
3
3
  from kscale.web.clients.base import BaseClient
4
+ from kscale.web.clients.robot import RobotClient
5
+ from kscale.web.clients.robot_class import RobotClassClient
4
6
  from kscale.web.clients.user import UserClient
5
7
 
6
8
 
7
9
  class WWWClient(
10
+ RobotClient,
11
+ RobotClassClient,
8
12
  UserClient,
9
13
  BaseClient,
10
14
  ):
@@ -21,6 +21,8 @@ logger = logging.getLogger(__name__)
21
21
  UPLOAD_TIMEOUT = 300.0
22
22
  DOWNLOAD_TIMEOUT = 60.0
23
23
 
24
+ INFO_FILE_NAME = ".info.json"
25
+
24
26
 
25
27
  class RobotClassClient(BaseClient):
26
28
  async def get_robot_classes(self) -> list[RobotClass]:
@@ -98,7 +100,7 @@ class RobotClassClient(BaseClient):
98
100
  r.raise_for_status()
99
101
  return response
100
102
 
101
- async def download_robot_class_urdf(self, class_name: str, *, cache: bool = True) -> Path:
103
+ async def download_compressed_urdf(self, class_name: str, *, cache: bool = True) -> Path:
102
104
  cache_path = get_robots_dir() / class_name / "robot.tgz"
103
105
  if cache and cache_path.exists() and not should_refresh_file(cache_path):
104
106
  return cache_path
@@ -108,7 +110,7 @@ class RobotClassClient(BaseClient):
108
110
  cache_path.parent.mkdir(parents=True, exist_ok=True)
109
111
 
110
112
  # Checks the md5 hash of the file.
111
- cache_path_info = cache_path.parent / "info.json"
113
+ cache_path_info = cache_path.parent / INFO_FILE_NAME
112
114
  if cache_path_info.exists():
113
115
  with open(cache_path_info, "r") as f:
114
116
  info = json.load(f)
@@ -133,13 +135,42 @@ class RobotClassClient(BaseClient):
133
135
  if hash_value_hex != expected_hash:
134
136
  raise ValueError(f"MD5 hash mismatch: {hash_value_hex} != {expected_hash}")
135
137
 
136
- logger.info("Unpacking downloaded file")
137
- with tarfile.open(cache_path, "r:gz") as tar:
138
- tar.extractall(path=cache_path.parent)
139
-
140
138
  logger.info("Updating downloaded file information")
141
139
  info = {"md5_hash": hash_value_hex}
142
140
  with open(cache_path_info, "w") as f:
143
141
  json.dump(info, f)
144
142
 
145
143
  return cache_path
144
+
145
+ async def download_and_extract_urdf(self, class_name: str, *, cache: bool = True) -> Path:
146
+ cache_path = await self.download_compressed_urdf(class_name, cache=cache)
147
+
148
+ # Reads the MD5 hash from the info file.
149
+ cache_path_info = cache_path.parent / INFO_FILE_NAME
150
+ with open(cache_path_info, "r") as f:
151
+ info = json.load(f)
152
+ expected_hash = info["md5_hash"]
153
+
154
+ # Unpacks the file if requested.
155
+ unpack_path = cache_path.parent / "robot"
156
+ unpack_path.mkdir(parents=True, exist_ok=True)
157
+ unpacked_path_info = unpack_path / INFO_FILE_NAME
158
+
159
+ # If the file has already been unpacked, return the path.
160
+ if unpacked_path_info.exists():
161
+ with open(unpacked_path_info, "r") as f:
162
+ info = json.load(f)
163
+ if info["md5_hash"] == expected_hash:
164
+ unpack_path.touch()
165
+ return unpack_path
166
+
167
+ logger.info("Unpacking URDF file")
168
+ with tarfile.open(cache_path, "r:gz") as tar:
169
+ tar.extractall(path=unpack_path)
170
+
171
+ logger.info("Updating downloaded file information")
172
+ info = {"md5_hash": expected_hash}
173
+ with open(unpacked_path_info, "w") as f:
174
+ json.dump(info, f)
175
+
176
+ return unpack_path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: kscale
3
- Version: 0.1.5
3
+ Version: 0.2.1
4
4
  Summary: The kscale project
5
5
  Home-page: https://github.com/kscalelabs/kscale
6
6
  Author: Benjamin Bolte
@@ -4,7 +4,6 @@ README.md
4
4
  pyproject.toml
5
5
  setup.py
6
6
  kscale/__init__.py
7
- kscale/api.py
8
7
  kscale/cli.py
9
8
  kscale/conf.py
10
9
  kscale/py.typed
@@ -25,7 +24,6 @@ kscale/utils/api_base.py
25
24
  kscale/utils/checksum.py
26
25
  kscale/utils/cli.py
27
26
  kscale/web/__init__.py
28
- kscale/web/api.py
29
27
  kscale/web/utils.py
30
28
  kscale/web/cli/__init__.py
31
29
  kscale/web/cli/robot.py
@@ -1,11 +0,0 @@
1
- """Defines common functionality for the K-Scale API."""
2
-
3
- from kscale.utils.api_base import APIBase
4
- from kscale.web.api import WebAPI
5
-
6
-
7
- class K(
8
- WebAPI,
9
- APIBase,
10
- ):
11
- """Defines a common interface for the K-Scale API."""
@@ -1,18 +0,0 @@
1
- """Defines a common interface for the K-Scale WWW API."""
2
-
3
- from kscale.utils.api_base import APIBase
4
- from kscale.web.clients.client import WWWClient
5
- from kscale.web.gen.api import ProfileResponse
6
-
7
-
8
- class WebAPI(APIBase):
9
- async def www_client(self) -> WWWClient:
10
- return WWWClient()
11
-
12
- async def get_profile_info(self) -> ProfileResponse:
13
- client = await self.www_client()
14
- return await client.get_profile_info()
15
-
16
- async def get_api_key(self, num_hours: int = 24) -> str:
17
- client = await self.www_client()
18
- return await client.get_api_key(num_hours)
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