subspacecomputing 0.1.1__tar.gz → 0.1.2__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.
- {subspacecomputing-0.1.1/subspacecomputing.egg-info → subspacecomputing-0.1.2}/PKG-INFO +12 -1
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/README.md +11 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/pyproject.toml +2 -1
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/setup.py +1 -1
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing/__init__.py +1 -1
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing/client.py +35 -2
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing/errors.py +15 -3
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2/subspacecomputing.egg-info}/PKG-INFO +12 -1
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/LICENSE +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/MANIFEST.in +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/setup.cfg +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing/utils/__init__.py +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing/utils/pandas_integration.py +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing.egg-info/SOURCES.txt +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing.egg-info/dependency_links.txt +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing.egg-info/requires.txt +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing.egg-info/top_level.txt +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/tests/test_client_integration.py +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/tests/test_client_unit.py +0 -0
- {subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/tests/test_pandas_integration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: subspacecomputing
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Python SDK for Subspace Computing Engine API (by Beausoft)
|
|
5
5
|
Home-page: https://www.subspacecomputing.com/developer
|
|
6
6
|
Author: Beausoft
|
|
@@ -49,6 +49,17 @@ bsce = BSCE(api_key='your-api-key-here')
|
|
|
49
49
|
# bsce = BSCE(api_key='your-api-key-here', base_url='http://localhost:8000')
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### Teams (`X-Team-Id`)
|
|
53
|
+
|
|
54
|
+
Keys can carry a `default_team_id` from the portal. If the user is in **several** teams, some endpoints require an explicit team: pass `team_id=...` or call `set_team_id` so the SDK sends `X-Team-Id`.
|
|
55
|
+
|
|
56
|
+
If you omit it when required, the API returns **400** with `error.reason` **`team_context_required`**. Use `ValidationError` and read `exc.reason`.
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
bsce = BSCE(api_key="...", team_id="00000000-0000-0000-0000-000000000000")
|
|
60
|
+
bsce.set_team_id(None) # clear override for following requests
|
|
61
|
+
```
|
|
62
|
+
|
|
52
63
|
### Simple Projection (1 scenario)
|
|
53
64
|
|
|
54
65
|
```python
|
|
@@ -22,6 +22,17 @@ bsce = BSCE(api_key='your-api-key-here')
|
|
|
22
22
|
# bsce = BSCE(api_key='your-api-key-here', base_url='http://localhost:8000')
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
### Teams (`X-Team-Id`)
|
|
26
|
+
|
|
27
|
+
Keys can carry a `default_team_id` from the portal. If the user is in **several** teams, some endpoints require an explicit team: pass `team_id=...` or call `set_team_id` so the SDK sends `X-Team-Id`.
|
|
28
|
+
|
|
29
|
+
If you omit it when required, the API returns **400** with `error.reason` **`team_context_required`**. Use `ValidationError` and read `exc.reason`.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
bsce = BSCE(api_key="...", team_id="00000000-0000-0000-0000-000000000000")
|
|
33
|
+
bsce.set_team_id(None) # clear override for following requests
|
|
34
|
+
```
|
|
35
|
+
|
|
25
36
|
### Simple Projection (1 scenario)
|
|
26
37
|
|
|
27
38
|
```python
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "subspacecomputing"
|
|
9
|
-
version = "0.1.
|
|
9
|
+
version = "0.1.2"
|
|
10
10
|
description = "Python SDK for Subspace Computing Engine API (by Beausoft)"
|
|
11
11
|
authors = [{name = "Beausoft", email = "contact@beausoft.ca"}]
|
|
12
12
|
readme = "README.md"
|
|
@@ -25,6 +25,7 @@ dev = [
|
|
|
25
25
|
"fastapi>=0.100.0", # Pour tests d'intégration
|
|
26
26
|
]
|
|
27
27
|
|
|
28
|
+
# No Git repository URL: built from a private monorepo; only public product URLs are published on PyPI.
|
|
28
29
|
[project.urls]
|
|
29
30
|
Documentation = "https://www.subspacecomputing.com/developer"
|
|
30
31
|
Homepage = "https://www.subspacecomputing.com/developer"
|
|
@@ -13,7 +13,7 @@ except FileNotFoundError:
|
|
|
13
13
|
|
|
14
14
|
setup(
|
|
15
15
|
name="subspacecomputing",
|
|
16
|
-
version="0.1.
|
|
16
|
+
version="0.1.2",
|
|
17
17
|
description="Python SDK for Subspace Computing Engine API (by Beausoft)",
|
|
18
18
|
long_description=long_description,
|
|
19
19
|
long_description_content_type="text/markdown",
|
|
@@ -26,6 +26,8 @@ class BSCE:
|
|
|
26
26
|
api_key: str,
|
|
27
27
|
base_url: Optional[str] = None,
|
|
28
28
|
timeout: Optional[int] = None,
|
|
29
|
+
*,
|
|
30
|
+
team_id: Optional[str] = None,
|
|
29
31
|
):
|
|
30
32
|
"""
|
|
31
33
|
Initialize the BSCE client.
|
|
@@ -36,6 +38,7 @@ class BSCE:
|
|
|
36
38
|
base_url: API base URL (optional, defaults to https://api.subspacecomputing.com).
|
|
37
39
|
Only useful for local testing or custom environments.
|
|
38
40
|
timeout: Request timeout in seconds (optional, defaults to 60).
|
|
41
|
+
team_id: Optional team UUID for header ``X-Team-Id`` (override default_team_id on the key).
|
|
39
42
|
|
|
40
43
|
Raises:
|
|
41
44
|
ValueError: If api_key is empty or None.
|
|
@@ -47,13 +50,25 @@ class BSCE:
|
|
|
47
50
|
self.api_key = api_key.strip()
|
|
48
51
|
self.base_url = (base_url or "https://api.subspacecomputing.com").rstrip("/")
|
|
49
52
|
self.timeout = timeout if timeout is not None else DEFAULT_TIMEOUT
|
|
53
|
+
self._team_id = (team_id or "").strip() or None
|
|
50
54
|
self.session = requests.Session()
|
|
51
|
-
|
|
55
|
+
headers = {
|
|
52
56
|
"X-API-Key": self.api_key,
|
|
53
57
|
"Content-Type": "application/json",
|
|
54
|
-
}
|
|
58
|
+
}
|
|
59
|
+
if self._team_id:
|
|
60
|
+
headers["X-Team-Id"] = self._team_id
|
|
61
|
+
self.session.headers.update(headers)
|
|
55
62
|
self.last_response = None # Store last response for header access
|
|
56
63
|
|
|
64
|
+
def set_team_id(self, team_id: Optional[str] = None) -> None:
|
|
65
|
+
"""Set or clear ``X-Team-Id`` for subsequent requests."""
|
|
66
|
+
self._team_id = (team_id or "").strip() or None
|
|
67
|
+
if self._team_id:
|
|
68
|
+
self.session.headers["X-Team-Id"] = self._team_id
|
|
69
|
+
else:
|
|
70
|
+
self.session.headers.pop("X-Team-Id", None)
|
|
71
|
+
|
|
57
72
|
def _handle_response(self, response: requests.Response):
|
|
58
73
|
"""
|
|
59
74
|
Handle HTTP errors and raise appropriate exceptions.
|
|
@@ -445,6 +460,24 @@ class BSCE:
|
|
|
445
460
|
self._handle_response(response)
|
|
446
461
|
# 204 No Content, no body
|
|
447
462
|
|
|
463
|
+
def get_run_artifact(self, artifact_id: str) -> Dict[str, Any]:
|
|
464
|
+
"""
|
|
465
|
+
Fetch a run artifact by id (authZ: view on parent projection).
|
|
466
|
+
|
|
467
|
+
Args:
|
|
468
|
+
artifact_id: run_artifacts.id
|
|
469
|
+
|
|
470
|
+
Returns:
|
|
471
|
+
Artifact payload (may include final_values or url).
|
|
472
|
+
"""
|
|
473
|
+
response = self.session.get(
|
|
474
|
+
f"{self.base_url}/run-artifacts/{artifact_id}",
|
|
475
|
+
timeout=self.timeout,
|
|
476
|
+
)
|
|
477
|
+
self.last_response = response
|
|
478
|
+
self._handle_response(response)
|
|
479
|
+
return response.json()
|
|
480
|
+
|
|
448
481
|
# Helper methods for accessing rate limit and quota info
|
|
449
482
|
|
|
450
483
|
@staticmethod
|
|
@@ -3,7 +3,7 @@ Custom exceptions for the Subspace Computing SDK.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
|
-
from typing import Optional
|
|
6
|
+
from typing import Any, Optional
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class BSCEError(Exception):
|
|
@@ -13,19 +13,31 @@ class BSCEError(Exception):
|
|
|
13
13
|
self.message = message
|
|
14
14
|
self.response = response
|
|
15
15
|
self.status_code = response.status_code if response else None
|
|
16
|
-
self.detail = None
|
|
16
|
+
self.detail: Any = None
|
|
17
|
+
self._body: Optional[dict] = None
|
|
17
18
|
|
|
18
|
-
# Try to extract error details from the response
|
|
19
19
|
if response is not None:
|
|
20
20
|
try:
|
|
21
21
|
error_data = response.json()
|
|
22
22
|
if isinstance(error_data, dict):
|
|
23
|
+
self._body = error_data
|
|
23
24
|
self.detail = error_data.get("detail", error_data.get("message"))
|
|
24
25
|
except ValueError:
|
|
25
26
|
self.detail = response.text
|
|
26
27
|
|
|
27
28
|
super().__init__(self.message)
|
|
28
29
|
|
|
30
|
+
@property
|
|
31
|
+
def reason(self) -> Optional[str]:
|
|
32
|
+
"""Clé stable contrat §6.8 si le corps est ``{\"error\": {\"reason\": ...}}``."""
|
|
33
|
+
if not self._body:
|
|
34
|
+
return None
|
|
35
|
+
err = self._body.get("error")
|
|
36
|
+
if isinstance(err, dict):
|
|
37
|
+
r = err.get("reason")
|
|
38
|
+
return str(r) if r is not None else None
|
|
39
|
+
return None
|
|
40
|
+
|
|
29
41
|
def __str__(self):
|
|
30
42
|
if self.detail:
|
|
31
43
|
return f"{self.message}: {self.detail}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: subspacecomputing
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: Python SDK for Subspace Computing Engine API (by Beausoft)
|
|
5
5
|
Home-page: https://www.subspacecomputing.com/developer
|
|
6
6
|
Author: Beausoft
|
|
@@ -49,6 +49,17 @@ bsce = BSCE(api_key='your-api-key-here')
|
|
|
49
49
|
# bsce = BSCE(api_key='your-api-key-here', base_url='http://localhost:8000')
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### Teams (`X-Team-Id`)
|
|
53
|
+
|
|
54
|
+
Keys can carry a `default_team_id` from the portal. If the user is in **several** teams, some endpoints require an explicit team: pass `team_id=...` or call `set_team_id` so the SDK sends `X-Team-Id`.
|
|
55
|
+
|
|
56
|
+
If you omit it when required, the API returns **400** with `error.reason` **`team_context_required`**. Use `ValidationError` and read `exc.reason`.
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
bsce = BSCE(api_key="...", team_id="00000000-0000-0000-0000-000000000000")
|
|
60
|
+
bsce.set_team_id(None) # clear override for following requests
|
|
61
|
+
```
|
|
62
|
+
|
|
52
63
|
### Simple Projection (1 scenario)
|
|
53
64
|
|
|
54
65
|
```python
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing/utils/pandas_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
{subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{subspacecomputing-0.1.1 → subspacecomputing-0.1.2}/subspacecomputing.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|