kscale 0.0.1__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
kscale-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Benjamin Bolte
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ recursive-include kscale/ *.py *.txt py.typed MANIFEST.in
kscale-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.1
2
+ Name: kscale
3
+ Version: 0.0.1
4
+ Summary: The kscale project
5
+ Home-page: https://github.com/kscalelabs/kscale
6
+ Author: Benjamin Bolte
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: omegaconf
11
+ Provides-Extra: dev
12
+ Requires-Dist: black; extra == "dev"
13
+ Requires-Dist: darglint; extra == "dev"
14
+ Requires-Dist: mypy; extra == "dev"
15
+ Requires-Dist: pytest; extra == "dev"
16
+ Requires-Dist: ruff; extra == "dev"
17
+ Requires-Dist: datamodel-code-generator; extra == "dev"
18
+
19
+ # K-Scale Command Line Interface
20
+
21
+ This is a command line tool for interacting with various services provided by K-Scale Labs, such as:
22
+
23
+ - [K-Scale Store](https://kscale.store/)
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install kscale
29
+ ```
kscale-0.0.1/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # K-Scale Command Line Interface
2
+
3
+ This is a command line tool for interacting with various services provided by K-Scale Labs, such as:
4
+
5
+ - [K-Scale Store](https://kscale.store/)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install kscale
11
+ ```
@@ -0,0 +1 @@
1
+ __version__ = "0.0.1"
@@ -0,0 +1,53 @@
1
+ """Defines the bot environment settings."""
2
+
3
+ import functools
4
+ import os
5
+ import warnings
6
+ from dataclasses import dataclass, field
7
+ from pathlib import Path
8
+
9
+ from omegaconf import II, OmegaConf
10
+
11
+
12
+ def get_path() -> Path:
13
+ if "KSCALE_CONFIG_DIR" in os.environ:
14
+ return Path(os.environ["KSCALE_CONFIG_DIR"]).expanduser().resolve()
15
+ return Path("~/.kscale/").expanduser().resolve()
16
+
17
+
18
+ @dataclass
19
+ class StoreSettings:
20
+ api_key: str = field(default=II("oc.env:KSCALE_API_KEY"))
21
+
22
+ def get_api_key(self) -> str:
23
+ try:
24
+ return self.api_key
25
+ except AttributeError:
26
+ raise ValueError(
27
+ "API key not found! Get one here and set it as the `KSCALE_API_KEY` "
28
+ "environment variable: https://kscale.store/keys"
29
+ )
30
+
31
+
32
+ @dataclass
33
+ class Settings:
34
+ store: StoreSettings = StoreSettings()
35
+
36
+ def save(self) -> None:
37
+ (dir_path := get_path()).mkdir(parents=True, exist_ok=True)
38
+ with open(dir_path / "settings.yaml", "w") as f:
39
+ OmegaConf.save(config=self, f=f)
40
+
41
+ @functools.lru_cache
42
+ @staticmethod
43
+ def load() -> "Settings":
44
+ config = OmegaConf.structured(Settings)
45
+ if not (dir_path := get_path()).exists():
46
+ warnings.warn(f"Settings directory does not exist: {dir_path}. Creating it now.")
47
+ dir_path.mkdir(parents=True)
48
+ OmegaConf.save(config, dir_path / "settings.yaml")
49
+ else:
50
+ with open(dir_path / "settings.yaml", "r") as f:
51
+ raw_settings = OmegaConf.load(f)
52
+ config = OmegaConf.merge(config, raw_settings)
53
+ return config
File without changes
@@ -0,0 +1,11 @@
1
+ # requirements-dev.txt
2
+
3
+ # For linting code.
4
+ black
5
+ darglint
6
+ mypy
7
+ pytest
8
+ ruff
9
+
10
+ # For generating API types.
11
+ datamodel-code-generator
@@ -0,0 +1,3 @@
1
+ # requirements.txt
2
+
3
+ omegaconf
File without changes
@@ -0,0 +1,13 @@
1
+ """Defines utility functions for authenticating the K-Scale Store API."""
2
+
3
+ from kscale.conf import Settings
4
+
5
+
6
+ def get_api_key() -> str:
7
+ try:
8
+ return Settings.load().store.api_key
9
+ except AttributeError:
10
+ raise ValueError(
11
+ "API key not found! Get one here and set it as the `KSCALE_API_KEY` "
12
+ "environment variable: https://kscale.store/keys"
13
+ )
File without changes
@@ -0,0 +1,267 @@
1
+ """Auto-generated by generate.sh script."""
2
+
3
+ # generated by datamodel-codegen:
4
+ # filename: openapi.json
5
+ # timestamp: 2024-08-19T06:07:36+00:00
6
+
7
+ from __future__ import annotations
8
+
9
+ from enum import Enum
10
+ from typing import List, Optional, Union
11
+
12
+ from pydantic import BaseModel, EmailStr, Field
13
+
14
+
15
+ class ArtifactUrls(BaseModel):
16
+ small: Optional[str] = Field(None, title="Small")
17
+ large: str = Field(..., title="Large")
18
+
19
+
20
+ class AuthResponse(BaseModel):
21
+ api_key: str = Field(..., title="Api Key")
22
+
23
+
24
+ class BodySetUrdfUrdfUploadListingIdPost(BaseModel):
25
+ file: bytes = Field(..., title="File")
26
+
27
+
28
+ class BodyUploadArtifactsUploadListingIdPost(BaseModel):
29
+ files: List[bytes] = Field(..., title="Files")
30
+
31
+
32
+ class ClientIdResponse(BaseModel):
33
+ client_id: str = Field(..., title="Client Id")
34
+
35
+
36
+ class DeleteTokenResponse(BaseModel):
37
+ message: str = Field(..., title="Message")
38
+
39
+
40
+ class EmailSignUpRequest(BaseModel):
41
+ email: EmailStr = Field(..., title="Email")
42
+
43
+
44
+ class EmailSignUpResponse(BaseModel):
45
+ message: str = Field(..., title="Message")
46
+
47
+
48
+ class GetListingResponse(BaseModel):
49
+ id: str = Field(..., title="Id")
50
+ name: str = Field(..., title="Name")
51
+ description: Optional[str] = Field(..., title="Description")
52
+ child_ids: List[str] = Field(..., title="Child Ids")
53
+ tags: List[str] = Field(..., title="Tags")
54
+ can_edit: bool = Field(..., title="Can Edit")
55
+
56
+
57
+ class GetTokenResponse(BaseModel):
58
+ id: str = Field(..., title="Id")
59
+ email: str = Field(..., title="Email")
60
+
61
+
62
+ class GithubAuthRequest(BaseModel):
63
+ code: str = Field(..., title="Code")
64
+
65
+
66
+ class GithubAuthResponse(BaseModel):
67
+ api_key: str = Field(..., title="Api Key")
68
+
69
+
70
+ class GoogleLogin(BaseModel):
71
+ token: str = Field(..., title="Token")
72
+
73
+
74
+ class Permission(Enum):
75
+ read = "read"
76
+ write = "write"
77
+ admin = "admin"
78
+
79
+
80
+ class KeysResponseItem(BaseModel):
81
+ token: str = Field(..., title="Token")
82
+ permissions: Optional[List[Permission]] = Field(..., title="Permissions")
83
+
84
+
85
+ class ArtifactType(Enum):
86
+ image = "image"
87
+
88
+
89
+ class ArtifactType1(Enum):
90
+ urdf = "urdf"
91
+ mjcf = "mjcf"
92
+
93
+
94
+ class ArtifactType2(Enum):
95
+ stl = "stl"
96
+ obj = "obj"
97
+ dae = "dae"
98
+ ply = "ply"
99
+
100
+
101
+ class ArtifactType3(Enum):
102
+ tgz = "tgz"
103
+ zip = "zip"
104
+
105
+
106
+ class ListArtifactsItem(BaseModel):
107
+ artifact_id: str = Field(..., title="Artifact Id")
108
+ listing_id: str = Field(..., title="Listing Id")
109
+ name: str = Field(..., title="Name")
110
+ artifact_type: Union[ArtifactType, ArtifactType1, ArtifactType2, ArtifactType3] = Field(..., title="Artifact Type")
111
+ description: Optional[str] = Field(..., title="Description")
112
+ timestamp: int = Field(..., title="Timestamp")
113
+ urls: ArtifactUrls
114
+ is_new: Optional[bool] = Field(None, title="Is New")
115
+
116
+
117
+ class ListArtifactsResponse(BaseModel):
118
+ artifacts: List[ListArtifactsItem] = Field(..., title="Artifacts")
119
+
120
+
121
+ class ListKeysResponse(BaseModel):
122
+ keys: List[KeysResponseItem] = Field(..., title="Keys")
123
+
124
+
125
+ class ListListingsResponse(BaseModel):
126
+ listing_ids: List[str] = Field(..., title="Listing Ids")
127
+ has_next: Optional[bool] = Field(False, title="Has Next")
128
+
129
+
130
+ class Listing(BaseModel):
131
+ id: str = Field(..., title="Id")
132
+ user_id: str = Field(..., title="User Id")
133
+ name: str = Field(..., title="Name")
134
+ child_ids: List[str] = Field(..., title="Child Ids")
135
+ description: Optional[str] = Field(..., title="Description")
136
+
137
+
138
+ class ListingInfoResponse(BaseModel):
139
+ id: str = Field(..., title="Id")
140
+ name: str = Field(..., title="Name")
141
+ description: Optional[str] = Field(..., title="Description")
142
+ child_ids: List[str] = Field(..., title="Child Ids")
143
+ image_url: Optional[str] = Field(..., title="Image Url")
144
+
145
+
146
+ class LoginRequest(BaseModel):
147
+ email: EmailStr = Field(..., title="Email")
148
+ password: str = Field(..., title="Password")
149
+
150
+
151
+ class LoginResponse(BaseModel):
152
+ user_id: str = Field(..., title="User Id")
153
+ token: str = Field(..., title="Token")
154
+
155
+
156
+ class Permission1(Enum):
157
+ is_admin = "is_admin"
158
+
159
+
160
+ class MyUserInfoResponse(BaseModel):
161
+ user_id: str = Field(..., title="User Id")
162
+ email: str = Field(..., title="Email")
163
+ github_id: Optional[str] = Field(..., title="Github Id")
164
+ google_id: Optional[str] = Field(..., title="Google Id")
165
+ permissions: Optional[List[Permission1]] = Field(..., title="Permissions")
166
+
167
+
168
+ class NewKeyRequest(BaseModel):
169
+ readonly: Optional[bool] = Field(True, title="Readonly")
170
+
171
+
172
+ class NewKeyResponse(BaseModel):
173
+ user_id: str = Field(..., title="User Id")
174
+ key: KeysResponseItem
175
+
176
+
177
+ class NewListingRequest(BaseModel):
178
+ name: str = Field(..., title="Name")
179
+ child_ids: List[str] = Field(..., title="Child Ids")
180
+ description: Optional[str] = Field(..., title="Description")
181
+
182
+
183
+ class NewListingResponse(BaseModel):
184
+ listing_id: str = Field(..., title="Listing Id")
185
+
186
+
187
+ class PublicUserInfoResponseItem(BaseModel):
188
+ id: str = Field(..., title="Id")
189
+ email: str = Field(..., title="Email")
190
+ permissions: Optional[List[Permission1]] = Field(None, title="Permissions")
191
+ created_at: Optional[int] = Field(None, title="Created At")
192
+ updated_at: Optional[int] = Field(None, title="Updated At")
193
+ first_name: Optional[str] = Field(None, title="First Name")
194
+ last_name: Optional[str] = Field(None, title="Last Name")
195
+ name: Optional[str] = Field(None, title="Name")
196
+ bio: Optional[str] = Field(None, title="Bio")
197
+
198
+
199
+ class PublicUsersInfoResponse(BaseModel):
200
+ users: List[PublicUserInfoResponseItem] = Field(..., title="Users")
201
+
202
+
203
+ class UpdateArtifactRequest(BaseModel):
204
+ name: Optional[str] = Field(None, title="Name")
205
+ description: Optional[str] = Field(None, title="Description")
206
+
207
+
208
+ class UpdateListingRequest(BaseModel):
209
+ name: Optional[str] = Field(None, title="Name")
210
+ child_ids: Optional[List[str]] = Field(None, title="Child Ids")
211
+ description: Optional[str] = Field(None, title="Description")
212
+ tags: Optional[List[str]] = Field(None, title="Tags")
213
+
214
+
215
+ class UploadArtifactResponse(BaseModel):
216
+ artifacts: List[ListArtifactsItem] = Field(..., title="Artifacts")
217
+
218
+
219
+ class UrdfInfo(BaseModel):
220
+ artifact_id: str = Field(..., title="Artifact Id")
221
+ url: str = Field(..., title="Url")
222
+
223
+
224
+ class UrdfResponse(BaseModel):
225
+ urdf: Optional[UrdfInfo]
226
+ listing_id: str = Field(..., title="Listing Id")
227
+
228
+
229
+ class UserInfoResponseItem(BaseModel):
230
+ id: str = Field(..., title="Id")
231
+ email: str = Field(..., title="Email")
232
+
233
+
234
+ class UserPublic(BaseModel):
235
+ id: str = Field(..., title="Id")
236
+ email: str = Field(..., title="Email")
237
+ permissions: Optional[List[Permission1]] = Field(None, title="Permissions")
238
+ created_at: Optional[int] = Field(None, title="Created At")
239
+ updated_at: Optional[int] = Field(None, title="Updated At")
240
+ first_name: Optional[str] = Field(None, title="First Name")
241
+ last_name: Optional[str] = Field(None, title="Last Name")
242
+ name: Optional[str] = Field(None, title="Name")
243
+ bio: Optional[str] = Field(None, title="Bio")
244
+
245
+
246
+ class UserSignup(BaseModel):
247
+ signup_token_id: str = Field(..., title="Signup Token Id")
248
+ email: str = Field(..., title="Email")
249
+ password: str = Field(..., title="Password")
250
+
251
+
252
+ class ValidationError(BaseModel):
253
+ loc: List[Union[str, int]] = Field(..., title="Location")
254
+ msg: str = Field(..., title="Message")
255
+ type: str = Field(..., title="Error Type")
256
+
257
+
258
+ class DumpListingsResponse(BaseModel):
259
+ listings: List[Listing] = Field(..., title="Listings")
260
+
261
+
262
+ class GetBatchListingsResponse(BaseModel):
263
+ listings: List[ListingInfoResponse] = Field(..., title="Listings")
264
+
265
+
266
+ class HTTPValidationError(BaseModel):
267
+ detail: Optional[List[ValidationError]] = Field(None, title="Detail")
@@ -0,0 +1 @@
1
+ """Utility functions for managing artifacts in the K-Scale store."""
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.1
2
+ Name: kscale
3
+ Version: 0.0.1
4
+ Summary: The kscale project
5
+ Home-page: https://github.com/kscalelabs/kscale
6
+ Author: Benjamin Bolte
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: omegaconf
11
+ Provides-Extra: dev
12
+ Requires-Dist: black; extra == "dev"
13
+ Requires-Dist: darglint; extra == "dev"
14
+ Requires-Dist: mypy; extra == "dev"
15
+ Requires-Dist: pytest; extra == "dev"
16
+ Requires-Dist: ruff; extra == "dev"
17
+ Requires-Dist: datamodel-code-generator; extra == "dev"
18
+
19
+ # K-Scale Command Line Interface
20
+
21
+ This is a command line tool for interacting with various services provided by K-Scale Labs, such as:
22
+
23
+ - [K-Scale Store](https://kscale.store/)
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install kscale
29
+ ```
@@ -0,0 +1,22 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ pyproject.toml
5
+ setup.cfg
6
+ setup.py
7
+ kscale/__init__.py
8
+ kscale/conf.py
9
+ kscale/py.typed
10
+ kscale/requirements-dev.txt
11
+ kscale/requirements.txt
12
+ kscale.egg-info/PKG-INFO
13
+ kscale.egg-info/SOURCES.txt
14
+ kscale.egg-info/dependency_links.txt
15
+ kscale.egg-info/requires.txt
16
+ kscale.egg-info/top_level.txt
17
+ kscale/store/__init__.py
18
+ kscale/store/auth.py
19
+ kscale/store/urdf.py
20
+ kscale/store/gen/__init__.py
21
+ kscale/store/gen/api.py
22
+ tests/test_dummy.py
@@ -0,0 +1,9 @@
1
+ omegaconf
2
+
3
+ [dev]
4
+ black
5
+ darglint
6
+ mypy
7
+ pytest
8
+ ruff
9
+ datamodel-code-generator
@@ -0,0 +1 @@
1
+ kscale
@@ -0,0 +1,72 @@
1
+ [tool.black]
2
+
3
+ line-length = 120
4
+ target-version = ["py311"]
5
+ include = '\.pyi?$'
6
+
7
+ [tool.pytest.ini_options]
8
+
9
+ addopts = "-rx -rf -x -q --full-trace"
10
+ testpaths = ["tests"]
11
+
12
+ markers = [
13
+ "slow: Marks test as being slow",
14
+ ]
15
+
16
+ [tool.mypy]
17
+
18
+ pretty = true
19
+ show_column_numbers = true
20
+ show_error_context = true
21
+ show_error_codes = true
22
+ show_traceback = true
23
+ disallow_untyped_defs = true
24
+ strict_equality = true
25
+ allow_redefinition = true
26
+
27
+ warn_unused_ignores = true
28
+ warn_redundant_casts = true
29
+
30
+ incremental = true
31
+ namespace_packages = false
32
+
33
+ # Uncomment to exclude modules from Mypy.
34
+ # [[tool.mypy.overrides]]
35
+ # module = []
36
+ # ignore_missing_imports = true
37
+
38
+ [tool.isort]
39
+
40
+ profile = "black"
41
+
42
+ [tool.ruff]
43
+
44
+ line-length = 120
45
+ target-version = "py310"
46
+
47
+ [tool.ruff.lint]
48
+
49
+ select = ["ANN", "D", "E", "F", "I", "N", "PGH", "PLC", "PLE", "PLR", "PLW", "W"]
50
+
51
+ ignore = [
52
+ "ANN101", "ANN102",
53
+ "D101", "D102", "D103", "D104", "D105", "D106", "D107",
54
+ "N812", "N817",
55
+ "PLR0911", "PLR0912", "PLR0913", "PLR0915", "PLR2004",
56
+ "PLW0603", "PLW2901",
57
+ ]
58
+
59
+ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
60
+
61
+ [tool.ruff.lint.per-file-ignores]
62
+
63
+ "__init__.py" = ["E402", "F401", "F403", "F811"]
64
+
65
+ [tool.ruff.lint.isort]
66
+
67
+ known-first-party = ["kscale", "tests"]
68
+ combine-as-imports = true
69
+
70
+ [tool.ruff.lint.pydocstyle]
71
+
72
+ convention = "google"
kscale-0.0.1/setup.cfg ADDED
@@ -0,0 +1,11 @@
1
+ [options]
2
+ packages = find:
3
+
4
+ [options.packages.find]
5
+ exclude =
6
+ tests
7
+
8
+ [egg_info]
9
+ tag_build =
10
+ tag_date = 0
11
+
kscale-0.0.1/setup.py ADDED
@@ -0,0 +1,39 @@
1
+ # mypy: disable-error-code="import-untyped"
2
+ #!/usr/bin/env python
3
+ """Setup script for the project."""
4
+
5
+ import re
6
+
7
+ from setuptools import setup
8
+
9
+ with open("README.md", "r", encoding="utf-8") as f:
10
+ long_description: str = f.read()
11
+
12
+
13
+ with open("kscale/requirements.txt", "r", encoding="utf-8") as f:
14
+ requirements: list[str] = f.read().splitlines()
15
+
16
+
17
+ with open("kscale/requirements-dev.txt", "r", encoding="utf-8") as f:
18
+ requirements_dev: list[str] = f.read().splitlines()
19
+
20
+
21
+ with open("kscale/__init__.py", "r", encoding="utf-8") as fh:
22
+ version_re = re.search(r"^__version__ = \"([^\"]*)\"", fh.read(), re.MULTILINE)
23
+ assert version_re is not None, "Could not find version in kscale/__init__.py"
24
+ version: str = version_re.group(1)
25
+
26
+
27
+ setup(
28
+ name="kscale",
29
+ version=version,
30
+ description="The kscale project",
31
+ author="Benjamin Bolte",
32
+ url="https://github.com/kscalelabs/kscale",
33
+ long_description=long_description,
34
+ long_description_content_type="text/markdown",
35
+ python_requires=">=3.11",
36
+ install_requires=requirements,
37
+ tests_require=requirements_dev,
38
+ extras_require={"dev": requirements_dev},
39
+ )
@@ -0,0 +1,12 @@
1
+ """Defines a dummy test."""
2
+
3
+ import pytest
4
+
5
+
6
+ def test_dummy() -> None:
7
+ assert True
8
+
9
+
10
+ @pytest.mark.slow
11
+ def test_slow() -> None:
12
+ assert True