keyrunes-python-sdk 0.0.1__tar.gz → 0.1.0__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.
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/PKG-INFO +1 -1
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/keyrunes_sdk/client.py +35 -4
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/keyrunes_sdk/config.py +9 -1
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/keyrunes_sdk/models.py +6 -2
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/pyproject.toml +4 -2
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/CHANGELOG.md +0 -0
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/LICENSE +0 -0
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/README.md +0 -0
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/keyrunes_sdk/__init__.py +0 -0
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/keyrunes_sdk/decorators.py +0 -0
- {keyrunes_python_sdk-0.0.1 → keyrunes_python_sdk-0.1.0}/keyrunes_sdk/exceptions.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Keyrunes API Client."""
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
from typing import Any, Dict, List, Optional
|
|
4
5
|
from urllib.parse import urljoin
|
|
5
6
|
|
|
@@ -38,6 +39,8 @@ class KeyrunesClient:
|
|
|
38
39
|
base_url: Base URL of the Keyrunes API
|
|
39
40
|
(e.g., "https://keyrunes.example.com")
|
|
40
41
|
api_key: Optional API key for authentication
|
|
42
|
+
organization_key: Optional Organization Key (required for v0.2.0+)
|
|
43
|
+
If not provided, looks for KEYRUNES_ORG_KEY env var
|
|
41
44
|
timeout: Request timeout in seconds (default: 30)
|
|
42
45
|
|
|
43
46
|
Example:
|
|
@@ -50,11 +53,16 @@ class KeyrunesClient:
|
|
|
50
53
|
self,
|
|
51
54
|
base_url: str,
|
|
52
55
|
api_key: Optional[str] = None,
|
|
56
|
+
organization_key: Optional[str] = None,
|
|
53
57
|
timeout: int = 30,
|
|
54
58
|
) -> None:
|
|
55
59
|
"""Initialize Keyrunes client."""
|
|
56
60
|
self.base_url = base_url.rstrip("/")
|
|
57
61
|
self.api_key = api_key
|
|
62
|
+
# Prioritize explicit argument, then env var
|
|
63
|
+
self.organization_key = organization_key or os.getenv(
|
|
64
|
+
"KEYRUNES_ORG_KEY"
|
|
65
|
+
)
|
|
58
66
|
self.timeout = timeout
|
|
59
67
|
self._token: Optional[str] = None
|
|
60
68
|
self._token_data: Optional[Dict[str, Any]] = None
|
|
@@ -63,6 +71,11 @@ class KeyrunesClient:
|
|
|
63
71
|
if api_key:
|
|
64
72
|
self._client.headers.update({"X-API-Key": api_key})
|
|
65
73
|
|
|
74
|
+
if self.organization_key:
|
|
75
|
+
self._client.headers.update(
|
|
76
|
+
{"X-Organization-Key": self.organization_key}
|
|
77
|
+
)
|
|
78
|
+
|
|
66
79
|
def _make_request(
|
|
67
80
|
self,
|
|
68
81
|
method: str,
|
|
@@ -190,13 +203,16 @@ class KeyrunesClient:
|
|
|
190
203
|
user=user_model,
|
|
191
204
|
)
|
|
192
205
|
|
|
193
|
-
def login(
|
|
206
|
+
def login(
|
|
207
|
+
self, username: str, password: str, namespace: str = "public"
|
|
208
|
+
) -> Token:
|
|
194
209
|
"""
|
|
195
210
|
Authenticate user and obtain access token.
|
|
196
211
|
|
|
197
212
|
Args:
|
|
198
213
|
username: Username or email
|
|
199
214
|
password: User password
|
|
215
|
+
namespace: User namespace (default: "public")
|
|
200
216
|
|
|
201
217
|
Returns:
|
|
202
218
|
Token object containing access token and user info
|
|
@@ -206,10 +222,14 @@ class KeyrunesClient:
|
|
|
206
222
|
|
|
207
223
|
Example:
|
|
208
224
|
>>> client = KeyrunesClient("https://keyrunes.example.com")
|
|
209
|
-
>>> token = client.login(
|
|
225
|
+
>>> token = client.login(
|
|
226
|
+
... "user@example.com", "password123", namespace="public"
|
|
227
|
+
... )
|
|
210
228
|
>>> client.set_token(token.access_token)
|
|
211
229
|
"""
|
|
212
|
-
credentials = LoginCredentials(
|
|
230
|
+
credentials = LoginCredentials(
|
|
231
|
+
identity=username, password=password, namespace=namespace
|
|
232
|
+
)
|
|
213
233
|
response = self._make_request(
|
|
214
234
|
"POST",
|
|
215
235
|
"/api/login",
|
|
@@ -228,7 +248,12 @@ class KeyrunesClient:
|
|
|
228
248
|
return token
|
|
229
249
|
|
|
230
250
|
def register_user(
|
|
231
|
-
self,
|
|
251
|
+
self,
|
|
252
|
+
username: str,
|
|
253
|
+
email: str,
|
|
254
|
+
password: str,
|
|
255
|
+
namespace: str = "public",
|
|
256
|
+
**attributes: Any,
|
|
232
257
|
) -> User:
|
|
233
258
|
"""
|
|
234
259
|
Register a new user.
|
|
@@ -237,6 +262,7 @@ class KeyrunesClient:
|
|
|
237
262
|
username: Username (3-50 characters)
|
|
238
263
|
email: User email address
|
|
239
264
|
password: Password (minimum 8 characters)
|
|
265
|
+
namespace: User namespace (default: "public")
|
|
240
266
|
**attributes: Additional user attributes
|
|
241
267
|
|
|
242
268
|
Returns:
|
|
@@ -251,6 +277,7 @@ class KeyrunesClient:
|
|
|
251
277
|
... username="newuser",
|
|
252
278
|
... email="newuser@example.com",
|
|
253
279
|
... password="securepass123",
|
|
280
|
+
... namespace="my-app",
|
|
254
281
|
... department="Engineering"
|
|
255
282
|
... )
|
|
256
283
|
"""
|
|
@@ -258,6 +285,7 @@ class KeyrunesClient:
|
|
|
258
285
|
username=username,
|
|
259
286
|
email=email,
|
|
260
287
|
password=password,
|
|
288
|
+
namespace=namespace,
|
|
261
289
|
attributes=attributes,
|
|
262
290
|
)
|
|
263
291
|
response = self._make_request(
|
|
@@ -283,6 +311,7 @@ class KeyrunesClient:
|
|
|
283
311
|
email: str,
|
|
284
312
|
password: str,
|
|
285
313
|
admin_key: str,
|
|
314
|
+
namespace: str = "public",
|
|
286
315
|
**attributes: Any,
|
|
287
316
|
) -> User:
|
|
288
317
|
"""
|
|
@@ -293,6 +322,7 @@ class KeyrunesClient:
|
|
|
293
322
|
email: Admin email address
|
|
294
323
|
password: Password (minimum 8 characters)
|
|
295
324
|
admin_key: Admin registration key
|
|
325
|
+
namespace: User namespace (default: "public")
|
|
296
326
|
**attributes: Additional user attributes
|
|
297
327
|
|
|
298
328
|
Returns:
|
|
@@ -316,6 +346,7 @@ class KeyrunesClient:
|
|
|
316
346
|
email=email,
|
|
317
347
|
password=password,
|
|
318
348
|
admin_key=admin_key,
|
|
349
|
+
namespace=namespace,
|
|
319
350
|
attributes=attributes,
|
|
320
351
|
)
|
|
321
352
|
response = self._make_request(
|
|
@@ -69,6 +69,7 @@ class _GlobalConfig:
|
|
|
69
69
|
self,
|
|
70
70
|
base_url: str,
|
|
71
71
|
api_key: Optional[str] = None,
|
|
72
|
+
organization_key: Optional[str] = None,
|
|
72
73
|
timeout: int = 30,
|
|
73
74
|
) -> KeyrunesClient:
|
|
74
75
|
"""
|
|
@@ -77,6 +78,7 @@ class _GlobalConfig:
|
|
|
77
78
|
Args:
|
|
78
79
|
base_url: Base URL of the Keyrunes API
|
|
79
80
|
api_key: Optional API key for authentication
|
|
81
|
+
organization_key: Optional Organization Key (required for v0.2.0+)
|
|
80
82
|
timeout: Request timeout in seconds (default: 30)
|
|
81
83
|
|
|
82
84
|
Returns:
|
|
@@ -91,7 +93,10 @@ class _GlobalConfig:
|
|
|
91
93
|
... )
|
|
92
94
|
"""
|
|
93
95
|
client = KeyrunesClient(
|
|
94
|
-
base_url=base_url,
|
|
96
|
+
base_url=base_url,
|
|
97
|
+
api_key=api_key,
|
|
98
|
+
organization_key=organization_key,
|
|
99
|
+
timeout=timeout,
|
|
95
100
|
)
|
|
96
101
|
self.set_client(client)
|
|
97
102
|
return client
|
|
@@ -133,6 +138,7 @@ def get_config() -> _GlobalConfig:
|
|
|
133
138
|
def configure(
|
|
134
139
|
base_url: str,
|
|
135
140
|
api_key: Optional[str] = None,
|
|
141
|
+
organization_key: Optional[str] = None,
|
|
136
142
|
timeout: int = 30,
|
|
137
143
|
) -> KeyrunesClient:
|
|
138
144
|
"""
|
|
@@ -145,6 +151,7 @@ def configure(
|
|
|
145
151
|
Args:
|
|
146
152
|
base_url: Base URL of the Keyrunes API
|
|
147
153
|
api_key: Optional API key for authentication
|
|
154
|
+
organization_key: Optional Organization Key (required for v0.2.0+)
|
|
148
155
|
timeout: Request timeout in seconds (default: 30)
|
|
149
156
|
|
|
150
157
|
Returns:
|
|
@@ -167,6 +174,7 @@ def configure(
|
|
|
167
174
|
return _config.configure(
|
|
168
175
|
base_url=base_url,
|
|
169
176
|
api_key=api_key,
|
|
177
|
+
organization_key=organization_key,
|
|
170
178
|
timeout=timeout,
|
|
171
179
|
)
|
|
172
180
|
|
|
@@ -64,6 +64,7 @@ class UserRegistration(BaseModel):
|
|
|
64
64
|
)
|
|
65
65
|
email: EmailStr = Field(..., description="User email")
|
|
66
66
|
password: str = Field(..., min_length=8, description="Password")
|
|
67
|
+
namespace: str = Field("default", description="User namespace")
|
|
67
68
|
attributes: Dict[str, Any] = Field(
|
|
68
69
|
default_factory=dict, description="Additional attributes"
|
|
69
70
|
)
|
|
@@ -80,11 +81,14 @@ class LoginCredentials(BaseModel):
|
|
|
80
81
|
|
|
81
82
|
identity: str = Field(..., description="Username or email")
|
|
82
83
|
password: str = Field(..., description="Password")
|
|
84
|
+
namespace: str = Field("default", description="User namespace")
|
|
83
85
|
|
|
84
86
|
@classmethod
|
|
85
|
-
def from_username(
|
|
87
|
+
def from_username(
|
|
88
|
+
cls, username: str, password: str, namespace: str = "default"
|
|
89
|
+
) -> "LoginCredentials":
|
|
86
90
|
"""Create from username parameter (for backward compatibility)."""
|
|
87
|
-
return cls(identity=username, password=password)
|
|
91
|
+
return cls(identity=username, password=password, namespace=namespace)
|
|
88
92
|
|
|
89
93
|
|
|
90
94
|
class GroupCheck(BaseModel):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "keyrunes-python-sdk"
|
|
3
|
-
version = "0.0
|
|
3
|
+
version = "0.1.0"
|
|
4
4
|
description = "Python SDK for Keyrunes Authorization System"
|
|
5
5
|
authors = ["keyrunes <contact@singularjourney.host>"]
|
|
6
6
|
maintainers = ["jonatasoli <contact@jonatasoli.dev>"]
|
|
@@ -40,12 +40,14 @@ pytest-cov = "^4.1.0"
|
|
|
40
40
|
pytest-mock = "^3.11.1"
|
|
41
41
|
factory-boy = "^3.3.0"
|
|
42
42
|
faker = "^19.0.0"
|
|
43
|
-
black = "^
|
|
43
|
+
black = "^25.12.0"
|
|
44
44
|
isort = "^5.12.0"
|
|
45
45
|
flake8 = "^6.1.0"
|
|
46
46
|
mypy = "^1.5.0"
|
|
47
47
|
taskipy = "^1.12.0"
|
|
48
48
|
towncrier = "^25.8.0"
|
|
49
|
+
pre-commit = "^4.5.1"
|
|
50
|
+
safety = "^3.7.0"
|
|
49
51
|
|
|
50
52
|
[build-system]
|
|
51
53
|
requires = ["poetry-core>=1.0.0"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|