kscale 0.3.11__tar.gz → 0.3.13__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.
Files changed (42) hide show
  1. {kscale-0.3.11/kscale.egg-info → kscale-0.3.13}/PKG-INFO +2 -2
  2. {kscale-0.3.11 → kscale-0.3.13}/README.md +1 -1
  3. {kscale-0.3.11 → kscale-0.3.13}/kscale/__init__.py +1 -1
  4. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/cli/robot_class.py +2 -1
  5. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/clients/base.py +21 -5
  6. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/clients/robot_class.py +17 -4
  7. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/gen/api.py +45 -4
  8. {kscale-0.3.11 → kscale-0.3.13/kscale.egg-info}/PKG-INFO +2 -2
  9. {kscale-0.3.11 → kscale-0.3.13}/LICENSE +0 -0
  10. {kscale-0.3.11 → kscale-0.3.13}/MANIFEST.in +0 -0
  11. {kscale-0.3.11 → kscale-0.3.13}/kscale/artifacts/__init__.py +0 -0
  12. {kscale-0.3.11 → kscale-0.3.13}/kscale/artifacts/plane.obj +0 -0
  13. {kscale-0.3.11 → kscale-0.3.13}/kscale/artifacts/plane.urdf +0 -0
  14. {kscale-0.3.11 → kscale-0.3.13}/kscale/cli.py +0 -0
  15. {kscale-0.3.11 → kscale-0.3.13}/kscale/conf.py +0 -0
  16. {kscale-0.3.11 → kscale-0.3.13}/kscale/py.typed +0 -0
  17. {kscale-0.3.11 → kscale-0.3.13}/kscale/requirements-dev.txt +0 -0
  18. {kscale-0.3.11 → kscale-0.3.13}/kscale/requirements.txt +0 -0
  19. {kscale-0.3.11 → kscale-0.3.13}/kscale/utils/__init__.py +0 -0
  20. {kscale-0.3.11 → kscale-0.3.13}/kscale/utils/api_base.py +0 -0
  21. {kscale-0.3.11 → kscale-0.3.13}/kscale/utils/checksum.py +0 -0
  22. {kscale-0.3.11 → kscale-0.3.13}/kscale/utils/cli.py +0 -0
  23. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/__init__.py +0 -0
  24. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/cli/__init__.py +0 -0
  25. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/cli/robot.py +0 -0
  26. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/cli/user.py +0 -0
  27. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/clients/__init__.py +0 -0
  28. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/clients/client.py +0 -0
  29. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/clients/robot.py +0 -0
  30. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/clients/user.py +0 -0
  31. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/gen/__init__.py +0 -0
  32. {kscale-0.3.11 → kscale-0.3.13}/kscale/web/utils.py +0 -0
  33. {kscale-0.3.11 → kscale-0.3.13}/kscale.egg-info/SOURCES.txt +0 -0
  34. {kscale-0.3.11 → kscale-0.3.13}/kscale.egg-info/dependency_links.txt +0 -0
  35. {kscale-0.3.11 → kscale-0.3.13}/kscale.egg-info/entry_points.txt +0 -0
  36. {kscale-0.3.11 → kscale-0.3.13}/kscale.egg-info/not-zip-safe +0 -0
  37. {kscale-0.3.11 → kscale-0.3.13}/kscale.egg-info/requires.txt +0 -0
  38. {kscale-0.3.11 → kscale-0.3.13}/kscale.egg-info/top_level.txt +0 -0
  39. {kscale-0.3.11 → kscale-0.3.13}/pyproject.toml +0 -0
  40. {kscale-0.3.11 → kscale-0.3.13}/setup.cfg +0 -0
  41. {kscale-0.3.11 → kscale-0.3.13}/setup.py +0 -0
  42. {kscale-0.3.11 → kscale-0.3.13}/tests/test_dummy.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kscale
3
- Version: 0.3.11
3
+ Version: 0.3.13
4
4
  Summary: The kscale project
5
5
  Home-page: https://github.com/kscalelabs/kscale
6
6
  Author: Benjamin Bolte
@@ -55,7 +55,7 @@ Dynamic: summary
55
55
 
56
56
  # K-Scale Command Line Interface
57
57
 
58
- This is a command line tool for interacting with various services provided by K-Scale Labs. For more information, see the [documentation](https://docs.kscale.dev/pkg/intro).
58
+ This is a command line tool for interacting with various services provided by K-Scale Labs. For more information, see the [documentation](https://docs.kscale.dev/docs/k-scale-api).
59
59
 
60
60
  ## Installation
61
61
 
@@ -15,7 +15,7 @@
15
15
 
16
16
  # K-Scale Command Line Interface
17
17
 
18
- This is a command line tool for interacting with various services provided by K-Scale Labs. For more information, see the [documentation](https://docs.kscale.dev/pkg/intro).
18
+ This is a command line tool for interacting with various services provided by K-Scale Labs. For more information, see the [documentation](https://docs.kscale.dev/docs/k-scale-api).
19
19
 
20
20
  ## Installation
21
21
 
@@ -1,6 +1,6 @@
1
1
  """Defines the common interface for the K-Scale Python API."""
2
2
 
3
- __version__ = "0.3.11"
3
+ __version__ = "0.3.13"
4
4
 
5
5
  from pathlib import Path
6
6
 
@@ -41,10 +41,11 @@ async def list() -> None:
41
41
  click.style(rc.id, fg="blue"),
42
42
  click.style(rc.class_name, fg="green"),
43
43
  rc.description or "N/A",
44
+ "N/A" if rc.num_downloads is None else f"{rc.num_downloads:,}",
44
45
  ]
45
46
  for rc in robot_classes
46
47
  ]
47
- click.echo(tabulate(table_data, headers=["ID", "Name", "Description"], tablefmt="simple"))
48
+ click.echo(tabulate(table_data, headers=["ID", "Name", "Description", "Downloads"], tablefmt="simple"))
48
49
  else:
49
50
  click.echo(click.style("No robot classes found", fg="red"))
50
51
 
@@ -9,7 +9,7 @@ import sys
9
9
  import time
10
10
  import webbrowser
11
11
  from types import TracebackType
12
- from typing import Any, Self, Type
12
+ from typing import Any, Mapping, Self, Type
13
13
  from urllib.parse import urljoin
14
14
 
15
15
  import aiohttp
@@ -363,6 +363,7 @@ class BaseClient:
363
363
  params: dict[str, Any] | None = None,
364
364
  data: BaseModel | dict[str, Any] | None = None,
365
365
  files: dict[str, Any] | None = None,
366
+ error_code_suggestions: dict[int, str] | None = None,
366
367
  ) -> dict[str, Any]:
367
368
  url = urljoin(self.base_url, endpoint)
368
369
  kwargs: dict[str, Any] = {}
@@ -380,12 +381,27 @@ class BaseClient:
380
381
  response = await client.request(method, url, **kwargs)
381
382
 
382
383
  if response.is_error:
383
- logger.error("Got %d error K-Scale: %s", response.status_code, response.text)
384
- if verbose_error():
384
+ error_code = response.status_code
385
+ error_json = response.json()
386
+ use_verbose_error = verbose_error()
387
+
388
+ if not use_verbose_error:
389
+ logger.info("Use KSCALE_VERBOSE_ERROR=1 to see the full error message")
390
+ logger.info("If this persists, please create an issue here: https://github.com/kscalelabs/kscale")
391
+
392
+ logger.error("Got error %d from the K-Scale API", error_code)
393
+ if isinstance(error_json, Mapping):
394
+ for key, value in error_json.items():
395
+ logger.error(" [%s] %s", key, value)
396
+ else:
397
+ logger.error(" %s", error_json)
398
+
399
+ if error_code_suggestions is not None and error_code in error_code_suggestions:
400
+ logger.error("Hint: %s", error_code_suggestions[error_code])
401
+
402
+ if use_verbose_error:
385
403
  response.raise_for_status()
386
404
  else:
387
- logger.error("Use KSCALE_VERBOSE_ERROR=1 to see the full error message")
388
- logger.error("If this persists, please create an issue here: https://github.com/kscalelabs/kscale")
389
405
  sys.exit(1)
390
406
 
391
407
  return response.json()
@@ -3,6 +3,7 @@
3
3
  import hashlib
4
4
  import json
5
5
  import logging
6
+ import shutil
6
7
  import tarfile
7
8
  from pathlib import Path
8
9
  from typing import Any
@@ -31,7 +32,7 @@ class RobotClassClient(BaseClient):
31
32
  data = await self._request(
32
33
  "GET",
33
34
  "/robots/",
34
- auth=True,
35
+ auth=False,
35
36
  )
36
37
  return [RobotClass.model_validate(item) for item in data]
37
38
 
@@ -39,7 +40,7 @@ class RobotClassClient(BaseClient):
39
40
  data = await self._request(
40
41
  "GET",
41
42
  f"/robots/name/{class_name}",
42
- auth=True,
43
+ auth=False,
43
44
  )
44
45
  return RobotClass.model_validate(data)
45
46
 
@@ -117,7 +118,12 @@ class RobotClassClient(BaseClient):
117
118
  cache_path = get_robots_dir() / class_name / "robot.tgz"
118
119
  if cache and cache_path.exists() and not should_refresh_file(cache_path):
119
120
  return cache_path
120
- data = await self._request("GET", f"/robots/urdf/{class_name}", auth=True)
121
+ data = await self._request(
122
+ "GET",
123
+ f"/robots/urdf/{class_name}",
124
+ auth=False,
125
+ error_code_suggestions={404: "Use `kscale robot list` to view classes."},
126
+ )
121
127
  response = RobotDownloadURDFResponse.model_validate(data)
122
128
  expected_hash = response.md5_hash
123
129
  cache_path.parent.mkdir(parents=True, exist_ok=True)
@@ -166,9 +172,16 @@ class RobotClassClient(BaseClient):
166
172
 
167
173
  # Unpacks the file if requested.
168
174
  unpack_path = cache_path.parent / "robot"
169
- unpack_path.mkdir(parents=True, exist_ok=True)
170
175
  unpacked_path_info = unpack_path / INFO_FILE_NAME
171
176
 
177
+ if not cache:
178
+ # If not using cache, remove the existing unpacked directory.
179
+ if unpack_path.exists():
180
+ logger.info("Removing existing unpacked directory")
181
+ shutil.rmtree(unpack_path)
182
+
183
+ unpack_path.mkdir(parents=True, exist_ok=True)
184
+
172
185
  # If the file has already been unpacked, return the path.
173
186
  if unpacked_path_info.exists():
174
187
  with open(unpacked_path_info, "r") as f:
@@ -2,7 +2,7 @@
2
2
 
3
3
  # generated by datamodel-codegen:
4
4
  # filename: openapi.json
5
- # timestamp: 2025-01-22T23:12:27+00:00
5
+ # timestamp: 2025-05-04T22:45:26+00:00
6
6
 
7
7
  from __future__ import annotations
8
8
 
@@ -19,6 +19,40 @@ class APIKeyResponse(BaseModel):
19
19
  api_key: str = Field(..., title="Api Key")
20
20
 
21
21
 
22
+ class ActuatorMetadataInput(BaseModel):
23
+ actuator_type: Optional[str] = Field(None, title="Actuator Type")
24
+ sysid: Optional[str] = Field(None, title="Sysid")
25
+ max_torque: Optional[Union[float, str]] = Field(None, title="Max Torque")
26
+ armature: Optional[Union[float, str]] = Field(None, title="Armature")
27
+ damping: Optional[Union[float, str]] = Field(None, title="Damping")
28
+ frictionloss: Optional[Union[float, str]] = Field(None, title="Frictionloss")
29
+ vin: Optional[Union[float, str]] = Field(None, title="Vin")
30
+ kt: Optional[Union[float, str]] = Field(None, title="Kt")
31
+ R: Optional[Union[float, str]] = Field(None, title="R")
32
+ vmax: Optional[Union[float, str]] = Field(None, title="Vmax")
33
+ amax: Optional[Union[float, str]] = Field(None, title="Amax")
34
+ max_velocity: Optional[Union[float, str]] = Field(None, title="Max Velocity")
35
+ max_pwm: Optional[Union[float, str]] = Field(None, title="Max Pwm")
36
+ error_gain: Optional[Union[float, str]] = Field(None, title="Error Gain")
37
+
38
+
39
+ class ActuatorMetadataOutput(BaseModel):
40
+ actuator_type: Optional[str] = Field(None, title="Actuator Type")
41
+ sysid: Optional[str] = Field(None, title="Sysid")
42
+ max_torque: Optional[str] = Field(None, title="Max Torque")
43
+ armature: Optional[str] = Field(None, title="Armature")
44
+ damping: Optional[str] = Field(None, title="Damping")
45
+ frictionloss: Optional[str] = Field(None, title="Frictionloss")
46
+ vin: Optional[str] = Field(None, title="Vin")
47
+ kt: Optional[str] = Field(None, title="Kt")
48
+ R: Optional[str] = Field(None, title="R")
49
+ vmax: Optional[str] = Field(None, title="Vmax")
50
+ amax: Optional[str] = Field(None, title="Amax")
51
+ max_velocity: Optional[str] = Field(None, title="Max Velocity")
52
+ max_pwm: Optional[str] = Field(None, title="Max Pwm")
53
+ error_gain: Optional[str] = Field(None, title="Error Gain")
54
+
55
+
22
56
  class AddRobotClassRequest(BaseModel):
23
57
  description: Optional[str] = Field(None, title="Description")
24
58
 
@@ -37,8 +71,8 @@ class JointMetadataInput(BaseModel):
37
71
  offset: Optional[Union[float, str]] = Field(None, title="Offset")
38
72
  flipped: Optional[bool] = Field(None, title="Flipped")
39
73
  actuator_type: Optional[str] = Field(None, title="Actuator Type")
40
- nn_id: Optional[int] = Field(None, title="Neural Network Id")
41
- soft_torque_limit: Optional[str] = Field(None, title="Soft Torque Limit")
74
+ nn_id: Optional[int] = Field(None, title="Nn Id")
75
+ soft_torque_limit: Optional[Union[float, str]] = Field(None, title="Soft Torque Limit")
42
76
 
43
77
 
44
78
  class JointMetadataOutput(BaseModel):
@@ -50,7 +84,7 @@ class JointMetadataOutput(BaseModel):
50
84
  offset: Optional[str] = Field(None, title="Offset")
51
85
  flipped: Optional[bool] = Field(None, title="Flipped")
52
86
  actuator_type: Optional[str] = Field(None, title="Actuator Type")
53
- nn_id: Optional[int] = Field(None, title="Neural Network Id")
87
+ nn_id: Optional[int] = Field(None, title="Nn Id")
54
88
  soft_torque_limit: Optional[str] = Field(None, title="Soft Torque Limit")
55
89
 
56
90
 
@@ -82,11 +116,17 @@ class RobotResponse(BaseModel):
82
116
 
83
117
  class RobotURDFMetadataInput(BaseModel):
84
118
  joint_name_to_metadata: Optional[Dict[str, JointMetadataInput]] = Field(None, title="Joint Name To Metadata")
119
+ actuator_type_to_metadata: Optional[Dict[str, ActuatorMetadataInput]] = Field(
120
+ None, title="Actuator Type To Metadata"
121
+ )
85
122
  control_frequency: Optional[Union[float, str]] = Field(None, title="Control Frequency")
86
123
 
87
124
 
88
125
  class RobotURDFMetadataOutput(BaseModel):
89
126
  joint_name_to_metadata: Optional[Dict[str, JointMetadataOutput]] = Field(None, title="Joint Name To Metadata")
127
+ actuator_type_to_metadata: Optional[Dict[str, ActuatorMetadataOutput]] = Field(
128
+ None, title="Actuator Type To Metadata"
129
+ )
90
130
  control_frequency: Optional[str] = Field(None, title="Control Frequency")
91
131
 
92
132
 
@@ -141,3 +181,4 @@ class RobotClass(BaseModel):
141
181
  description: str = Field(..., title="Description")
142
182
  user_id: str = Field(..., title="User Id")
143
183
  metadata: Optional[RobotURDFMetadataOutput] = None
184
+ num_downloads: Optional[int] = Field(0, title="Num Downloads")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kscale
3
- Version: 0.3.11
3
+ Version: 0.3.13
4
4
  Summary: The kscale project
5
5
  Home-page: https://github.com/kscalelabs/kscale
6
6
  Author: Benjamin Bolte
@@ -55,7 +55,7 @@ Dynamic: summary
55
55
 
56
56
  # K-Scale Command Line Interface
57
57
 
58
- This is a command line tool for interacting with various services provided by K-Scale Labs. For more information, see the [documentation](https://docs.kscale.dev/pkg/intro).
58
+ This is a command line tool for interacting with various services provided by K-Scale Labs. For more information, see the [documentation](https://docs.kscale.dev/docs/k-scale-api).
59
59
 
60
60
  ## Installation
61
61
 
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