driftstone 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.
- driftstone-0.1.0/.gitignore +10 -0
- driftstone-0.1.0/.python-version +1 -0
- driftstone-0.1.0/PKG-INFO +87 -0
- driftstone-0.1.0/README.md +68 -0
- driftstone-0.1.0/pyproject.toml +36 -0
- driftstone-0.1.0/src/driftstone/__init__.py +15 -0
- driftstone-0.1.0/src/driftstone/_internal/__init__.py +1 -0
- driftstone-0.1.0/src/driftstone/_internal/constants.py +7 -0
- driftstone-0.1.0/src/driftstone/_internal/transport.py +103 -0
- driftstone-0.1.0/src/driftstone/_internal/utils.py +21 -0
- driftstone-0.1.0/src/driftstone/client.py +67 -0
- driftstone-0.1.0/src/driftstone/exceptions.py +14 -0
- driftstone-0.1.0/src/driftstone/models/__init__.py +1 -0
- driftstone-0.1.0/src/driftstone/models/access_group.py +32 -0
- driftstone-0.1.0/src/driftstone/models/app.py +120 -0
- driftstone-0.1.0/src/driftstone/models/channel.py +123 -0
- driftstone-0.1.0/src/driftstone/models/instance.py +51 -0
- driftstone-0.1.0/src/driftstone/models/profile.py +61 -0
- driftstone-0.1.0/src/driftstone/models/response.py +12 -0
- driftstone-0.1.0/src/driftstone/models/session.py +33 -0
- driftstone-0.1.0/src/driftstone/models/version.py +39 -0
- driftstone-0.1.0/src/driftstone/py.typed +1 -0
- driftstone-0.1.0/src/driftstone/resources/__init__.py +1 -0
- driftstone-0.1.0/src/driftstone/resources/_base.py +18 -0
- driftstone-0.1.0/src/driftstone/resources/access_group.py +125 -0
- driftstone-0.1.0/src/driftstone/resources/app.py +124 -0
- driftstone-0.1.0/src/driftstone/resources/channel.py +220 -0
- driftstone-0.1.0/src/driftstone/resources/instance.py +43 -0
- driftstone-0.1.0/src/driftstone/resources/profile.py +59 -0
- driftstone-0.1.0/src/driftstone/resources/session.py +101 -0
- driftstone-0.1.0/src/driftstone/resources/state.py +163 -0
- driftstone-0.1.0/src/driftstone/resources/version.py +163 -0
- driftstone-0.1.0/src/driftstone/version.py +1 -0
- driftstone-0.1.0/tests/.claude/agent.json +14 -0
- driftstone-0.1.0/tests/.claude/environment.json +9 -0
- driftstone-0.1.0/tests/.claude/skills/slack-gif-creator/LICENSE.txt +202 -0
- driftstone-0.1.0/tests/.claude/skills/slack-gif-creator/SKILL.md +254 -0
- driftstone-0.1.0/tests/.claude/skills/slack-gif-creator/core/easing.py +234 -0
- driftstone-0.1.0/tests/.claude/skills/slack-gif-creator/core/frame_composer.py +176 -0
- driftstone-0.1.0/tests/.claude/skills/slack-gif-creator/core/gif_builder.py +269 -0
- driftstone-0.1.0/tests/.claude/skills/slack-gif-creator/core/validators.py +136 -0
- driftstone-0.1.0/tests/.claude/skills/slack-gif-creator/requirements.txt +4 -0
- driftstone-0.1.0/tests/.openclaw/openclaw.json +94 -0
- driftstone-0.1.0/tests/.openclaw/workspace/AGENTS.md +212 -0
- driftstone-0.1.0/tests/.openclaw/workspace/BOOTSTRAP.md +55 -0
- driftstone-0.1.0/tests/.openclaw/workspace/HEARTBEAT.md +5 -0
- driftstone-0.1.0/tests/.openclaw/workspace/IDENTITY.md +23 -0
- driftstone-0.1.0/tests/.openclaw/workspace/SOUL.md +36 -0
- driftstone-0.1.0/tests/.openclaw/workspace/TOOLS.md +40 -0
- driftstone-0.1.0/tests/.openclaw/workspace/USER.md +17 -0
- driftstone-0.1.0/tests/quick_start_claude.py +41 -0
- driftstone-0.1.0/tests/quick_start_openclaw.py +18 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: driftstone
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the Driftstone API.
|
|
5
|
+
Project-URL: Homepage, https://www.driftstone.ai/
|
|
6
|
+
Author: Driftstone
|
|
7
|
+
Keywords: api-client,driftstone,sdk
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: httpx<1.0,>=0.27
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
## Driftstone - Python
|
|
21
|
+
|
|
22
|
+
Python SDK for the Driftstone API.
|
|
23
|
+
|
|
24
|
+
### Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install driftstone
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Quick Start
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from driftstone import Driftstone
|
|
34
|
+
|
|
35
|
+
client = Driftstone(api_key="your-api-key")
|
|
36
|
+
|
|
37
|
+
app = client.app.init("typedef-app",
|
|
38
|
+
type="claude",
|
|
39
|
+
version_path=".openclaw"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
channel = app.channel.init("my-api",
|
|
43
|
+
type="api"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
stream = channel.run(
|
|
47
|
+
session_id="my-custom-session-id",
|
|
48
|
+
user_id="stephen@pickaxe.co",
|
|
49
|
+
input="hello world"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
for event in stream:
|
|
53
|
+
if event.done:
|
|
54
|
+
break
|
|
55
|
+
|
|
56
|
+
print(event)
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Using A Context Manager
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from driftstone import Driftstone
|
|
64
|
+
|
|
65
|
+
with Driftstone(api_key="your-api-key") as client:
|
|
66
|
+
app = client.app.init("typedef-app",
|
|
67
|
+
type="claude",
|
|
68
|
+
version_path=".openclaw"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
channel = app.channel.init("my-api",
|
|
72
|
+
type="api"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
stream = channel.run(
|
|
76
|
+
session_id="my-custom-session-id",
|
|
77
|
+
user_id="stephen@pickaxe.co",
|
|
78
|
+
input="hello world"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
for event in stream:
|
|
82
|
+
if event.done:
|
|
83
|
+
break
|
|
84
|
+
|
|
85
|
+
print(event)
|
|
86
|
+
|
|
87
|
+
```
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
## Driftstone - Python
|
|
2
|
+
|
|
3
|
+
Python SDK for the Driftstone API.
|
|
4
|
+
|
|
5
|
+
### Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install driftstone
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from driftstone import Driftstone
|
|
15
|
+
|
|
16
|
+
client = Driftstone(api_key="your-api-key")
|
|
17
|
+
|
|
18
|
+
app = client.app.init("typedef-app",
|
|
19
|
+
type="claude",
|
|
20
|
+
version_path=".openclaw"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
channel = app.channel.init("my-api",
|
|
24
|
+
type="api"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
stream = channel.run(
|
|
28
|
+
session_id="my-custom-session-id",
|
|
29
|
+
user_id="stephen@pickaxe.co",
|
|
30
|
+
input="hello world"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
for event in stream:
|
|
34
|
+
if event.done:
|
|
35
|
+
break
|
|
36
|
+
|
|
37
|
+
print(event)
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Using A Context Manager
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from driftstone import Driftstone
|
|
45
|
+
|
|
46
|
+
with Driftstone(api_key="your-api-key") as client:
|
|
47
|
+
app = client.app.init("typedef-app",
|
|
48
|
+
type="claude",
|
|
49
|
+
version_path=".openclaw"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
channel = app.channel.init("my-api",
|
|
53
|
+
type="api"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
stream = channel.run(
|
|
57
|
+
session_id="my-custom-session-id",
|
|
58
|
+
user_id="stephen@pickaxe.co",
|
|
59
|
+
input="hello world"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
for event in stream:
|
|
63
|
+
if event.done:
|
|
64
|
+
break
|
|
65
|
+
|
|
66
|
+
print(event)
|
|
67
|
+
|
|
68
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27.0"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "driftstone"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Python SDK for the Driftstone API."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"httpx>=0.27,<1.0",
|
|
13
|
+
]
|
|
14
|
+
authors = [
|
|
15
|
+
{ name = "Driftstone" },
|
|
16
|
+
]
|
|
17
|
+
keywords = ["driftstone", "sdk", "api-client"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 3 - Alpha",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://www.driftstone.ai/"
|
|
31
|
+
|
|
32
|
+
[tool.hatch.version]
|
|
33
|
+
path = "src/driftstone/version.py"
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.wheel]
|
|
36
|
+
packages = ["src/driftstone"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .client import Driftstone
|
|
2
|
+
from .exceptions import (
|
|
3
|
+
DriftstoneAPIError,
|
|
4
|
+
DriftstoneError,
|
|
5
|
+
DriftstoneHTTPError,
|
|
6
|
+
DriftstoneResponseError,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"Driftstone",
|
|
11
|
+
"DriftstoneError",
|
|
12
|
+
"DriftstoneHTTPError",
|
|
13
|
+
"DriftstoneResponseError",
|
|
14
|
+
"DriftstoneAPIError",
|
|
15
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Internal Driftstone SDK implementation details."""
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Literal, cast
|
|
4
|
+
import httpx
|
|
5
|
+
|
|
6
|
+
from .utils import logger
|
|
7
|
+
from ..exceptions import (
|
|
8
|
+
DriftstoneAPIError,
|
|
9
|
+
DriftstoneHTTPError,
|
|
10
|
+
DriftstoneResponseError
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
Method = Literal["GET", "POST", "PUT", "PATCH", "DELETE"]
|
|
14
|
+
|
|
15
|
+
class Transport:
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
*,
|
|
19
|
+
base_url: str,
|
|
20
|
+
api_key: str,
|
|
21
|
+
timeout: float,
|
|
22
|
+
user_agent: str,
|
|
23
|
+
http_client: httpx.Client | None = None,
|
|
24
|
+
) -> None:
|
|
25
|
+
self.timeout = timeout
|
|
26
|
+
self._headers = {
|
|
27
|
+
"Authorization": f"Bearer {api_key}",
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
"Accept": "application/json",
|
|
30
|
+
"User-Agent": user_agent,
|
|
31
|
+
}
|
|
32
|
+
self._owns_http_client = http_client is None
|
|
33
|
+
self._http = http_client or httpx.Client(
|
|
34
|
+
base_url=base_url,
|
|
35
|
+
timeout=timeout,
|
|
36
|
+
headers=self._headers,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def headers(self) -> dict[str, str]:
|
|
41
|
+
return self._headers.copy()
|
|
42
|
+
|
|
43
|
+
def close(self) -> None:
|
|
44
|
+
if self._owns_http_client:
|
|
45
|
+
self._http.close()
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def _parse_response(response: httpx.Response) -> dict[str, Any]:
|
|
49
|
+
try:
|
|
50
|
+
decoded = response.json()
|
|
51
|
+
except ValueError as exc:
|
|
52
|
+
raise DriftstoneResponseError(
|
|
53
|
+
f"Driftstone API returned non-JSON response (status={response.status_code})"
|
|
54
|
+
) from exc
|
|
55
|
+
|
|
56
|
+
if not isinstance(decoded, dict):
|
|
57
|
+
raise DriftstoneResponseError(
|
|
58
|
+
"Driftstone API returned an unexpected response payload"
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
return cast(dict[str, Any], decoded)
|
|
62
|
+
|
|
63
|
+
def request(
|
|
64
|
+
self,
|
|
65
|
+
method: Method,
|
|
66
|
+
path: str,
|
|
67
|
+
payload: dict[str, Any] | None = None,
|
|
68
|
+
) -> dict[str, Any]:
|
|
69
|
+
payload = payload or {}
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
kwargs: dict[str, Any] = {
|
|
73
|
+
"method": method,
|
|
74
|
+
"url": path,
|
|
75
|
+
"headers": self._headers,
|
|
76
|
+
}
|
|
77
|
+
if method == "GET":
|
|
78
|
+
kwargs["params"] = payload
|
|
79
|
+
else:
|
|
80
|
+
kwargs["json"] = payload
|
|
81
|
+
|
|
82
|
+
response = self._http.request(**kwargs)
|
|
83
|
+
except httpx.HTTPError as exc:
|
|
84
|
+
raise DriftstoneHTTPError(f"HTTP request failed: {exc}") from exc
|
|
85
|
+
|
|
86
|
+
data = self._parse_response(response)
|
|
87
|
+
|
|
88
|
+
logger.debug(
|
|
89
|
+
"Received response from Driftstone API (status=%d, data=%s)",
|
|
90
|
+
response.status_code,
|
|
91
|
+
data,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if response.status_code >= 400:
|
|
95
|
+
raise DriftstoneAPIError(
|
|
96
|
+
f"Driftstone API returned error status {response.status_code}: {data}"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
if data.get("success") is False:
|
|
100
|
+
message = str(data.get("error") or data.get("message") or "Request failed")
|
|
101
|
+
raise DriftstoneAPIError(f"Driftstone API error: {message}")
|
|
102
|
+
|
|
103
|
+
return data
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
logger = logging.getLogger("driftstone")
|
|
5
|
+
logger.setLevel(logging.WARNING)
|
|
6
|
+
logger.addHandler(logging.NullHandler())
|
|
7
|
+
|
|
8
|
+
logging.basicConfig(
|
|
9
|
+
format="[%(funcName)s][%(asctime)s]: %(levelname)s %(message)s",
|
|
10
|
+
datefmt="%m/%d/%Y %H:%M:%S",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
def set_debug(enabled: bool) -> None:
|
|
14
|
+
logger.setLevel(logging.INFO if enabled else logging.WARNING)
|
|
15
|
+
|
|
16
|
+
def safe_parse_json(raw: str):
|
|
17
|
+
try:
|
|
18
|
+
return json.loads(raw)
|
|
19
|
+
except Exception as e:
|
|
20
|
+
logger.error("Failed to parse JSON: %s", e)
|
|
21
|
+
return None
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Literal
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from ._internal.constants import DEFAULT_API_BASE_URL
|
|
8
|
+
from ._internal.utils import logger, set_debug
|
|
9
|
+
from ._internal.transport import Method, Transport
|
|
10
|
+
from .resources.app import DriftstoneApp
|
|
11
|
+
from .version import __version__
|
|
12
|
+
|
|
13
|
+
class Driftstone:
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
api_key: str,
|
|
17
|
+
*,
|
|
18
|
+
version: Literal["v1"] = "v1",
|
|
19
|
+
timeout: float = 30.0,
|
|
20
|
+
debug: bool = False,
|
|
21
|
+
http_client: httpx.Client | None = None,
|
|
22
|
+
) -> None:
|
|
23
|
+
self.debug = debug
|
|
24
|
+
set_debug(self.debug)
|
|
25
|
+
|
|
26
|
+
logger.info("Initializing Driftstone client with provided API key")
|
|
27
|
+
|
|
28
|
+
trimmed_key = api_key.strip()
|
|
29
|
+
if not trimmed_key:
|
|
30
|
+
raise ValueError("api_key must be provided")
|
|
31
|
+
if not trimmed_key.startswith("dk-"):
|
|
32
|
+
raise ValueError("Invalid Driftstone API key")
|
|
33
|
+
|
|
34
|
+
self.api_key = trimmed_key
|
|
35
|
+
self.version = version
|
|
36
|
+
self.timeout = timeout
|
|
37
|
+
self.base_url = f"{DEFAULT_API_BASE_URL}/{self.version}"
|
|
38
|
+
|
|
39
|
+
self._transport = Transport(
|
|
40
|
+
base_url=self.base_url,
|
|
41
|
+
api_key=self.api_key,
|
|
42
|
+
timeout=self.timeout,
|
|
43
|
+
user_agent=f"Driftstone-python/{__version__}",
|
|
44
|
+
http_client=http_client,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def close(self) -> None:
|
|
48
|
+
self._transport.close()
|
|
49
|
+
|
|
50
|
+
def __enter__(self) -> "Driftstone":
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def __exit__(self, *_: object) -> None:
|
|
54
|
+
self.close()
|
|
55
|
+
|
|
56
|
+
def _request(
|
|
57
|
+
self,
|
|
58
|
+
method: Method,
|
|
59
|
+
path: str,
|
|
60
|
+
payload: dict[str, Any] | None = None,
|
|
61
|
+
) -> dict[str, Any]:
|
|
62
|
+
return self._transport.request(method, path, payload)
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def app(self) -> DriftstoneApp:
|
|
66
|
+
return DriftstoneApp(self)
|
|
67
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class DriftstoneError(Exception):
|
|
2
|
+
"""Base exception for the Driftstone SDK."""
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DriftstoneHTTPError(DriftstoneError):
|
|
6
|
+
"""Raised when the underlying HTTP request fails."""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DriftstoneResponseError(DriftstoneError):
|
|
10
|
+
"""Raised when an API response cannot be parsed as expected."""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DriftstoneAPIError(DriftstoneError):
|
|
14
|
+
"""Raised when the Driftstone API returns an error."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Driftstone SDK models."""
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any, Literal, Mapping
|
|
6
|
+
|
|
7
|
+
AccessGroupLimitReset = Literal["daily", "monthly", "yearly"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass(frozen=True, slots=True)
|
|
11
|
+
class DriftstoneAccessGroupModel:
|
|
12
|
+
id: str
|
|
13
|
+
appId: str
|
|
14
|
+
name: str
|
|
15
|
+
limit: int
|
|
16
|
+
limitReset: AccessGroupLimitReset
|
|
17
|
+
limitMessage: str
|
|
18
|
+
createdAt: datetime
|
|
19
|
+
updatedAt: datetime
|
|
20
|
+
|
|
21
|
+
@classmethod
|
|
22
|
+
def _from_api(cls, payload: Mapping[str, Any]) -> "DriftstoneAccessGroupModel":
|
|
23
|
+
return cls(
|
|
24
|
+
id=payload["id"],
|
|
25
|
+
appId=payload["appId"],
|
|
26
|
+
name=payload["name"],
|
|
27
|
+
limit=payload["limit"],
|
|
28
|
+
limitReset=payload["limitReset"],
|
|
29
|
+
limitMessage=payload["limitMessage"],
|
|
30
|
+
createdAt=datetime.fromisoformat(payload["createdAt"]),
|
|
31
|
+
updatedAt=datetime.fromisoformat(payload["updatedAt"]),
|
|
32
|
+
)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import (
|
|
6
|
+
TYPE_CHECKING,
|
|
7
|
+
Any,
|
|
8
|
+
Literal,
|
|
9
|
+
Mapping,
|
|
10
|
+
Optional,
|
|
11
|
+
TypedDict,
|
|
12
|
+
Union,
|
|
13
|
+
Required,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from ..resources.access_group import DriftstoneAccessGroup
|
|
18
|
+
from ..resources.version import DriftstoneVersion
|
|
19
|
+
from ..resources.channel import DriftstoneChannel
|
|
20
|
+
from ..resources.session import DriftstoneSession
|
|
21
|
+
from ..resources.profile import DriftstoneProfile
|
|
22
|
+
from ..resources.instance import DriftstoneInstance
|
|
23
|
+
|
|
24
|
+
ApplicationType = Literal["claude", "openclaw"]
|
|
25
|
+
|
|
26
|
+
class AppInitLimit(TypedDict):
|
|
27
|
+
name: Optional[str]
|
|
28
|
+
amount: Required[int]
|
|
29
|
+
interval: Required[Literal["daily", "weekly", "monthly"]]
|
|
30
|
+
message: Optional[str]
|
|
31
|
+
|
|
32
|
+
class AppInitCredentialMCPOAuthNoneParam(TypedDict):
|
|
33
|
+
type: Required[Literal["none"]]
|
|
34
|
+
|
|
35
|
+
class AppInitCredentialMCPOAuthBasicParam(TypedDict):
|
|
36
|
+
type: Required[Literal["client_secret_basic"]]
|
|
37
|
+
client_secret: Required[str]
|
|
38
|
+
|
|
39
|
+
class AppInitCredentialMCPOAuthPostParam(TypedDict):
|
|
40
|
+
type: Required[Literal["client_secret_post"]]
|
|
41
|
+
client_secret: Required[str]
|
|
42
|
+
|
|
43
|
+
class AppInitCredentialMCPOAuthRefresh(TypedDict):
|
|
44
|
+
client_id: Required[str]
|
|
45
|
+
refresh_token: Required[str]
|
|
46
|
+
token_endpoint: Required[str]
|
|
47
|
+
token_endpoint_auth: Required[Union[
|
|
48
|
+
AppInitCredentialMCPOAuthNoneParam,
|
|
49
|
+
AppInitCredentialMCPOAuthBasicParam,
|
|
50
|
+
AppInitCredentialMCPOAuthPostParam,
|
|
51
|
+
]]
|
|
52
|
+
resource: Optional[str]
|
|
53
|
+
scope: Optional[str]
|
|
54
|
+
|
|
55
|
+
class AppInitCredentialMCPOAuth(TypedDict):
|
|
56
|
+
access_token: Required[str]
|
|
57
|
+
mcp_server_url: Required[str]
|
|
58
|
+
type: Required[Literal["mcp_oauth"]]
|
|
59
|
+
expires_at: Optional[datetime]
|
|
60
|
+
refresh: Optional[AppInitCredentialMCPOAuthRefresh]
|
|
61
|
+
|
|
62
|
+
class AppInitCredentialMCPStaticBearer(TypedDict):
|
|
63
|
+
token: Required[str]
|
|
64
|
+
mcp_server_url: Required[str]
|
|
65
|
+
type: Required[Literal["mcp_oauth"]]
|
|
66
|
+
|
|
67
|
+
AppInitCredential = Union[AppInitCredentialMCPOAuth, AppInitCredentialMCPStaticBearer]
|
|
68
|
+
|
|
69
|
+
@dataclass(frozen=True, slots=True)
|
|
70
|
+
class DriftstoneAppModel:
|
|
71
|
+
id: str
|
|
72
|
+
orgId: str
|
|
73
|
+
type: ApplicationType
|
|
74
|
+
name: str
|
|
75
|
+
slug: str
|
|
76
|
+
vaultId: str
|
|
77
|
+
defaultAccessGroupId: str
|
|
78
|
+
headVersionId: Optional[str]
|
|
79
|
+
metadata: Optional[dict[str, str]]
|
|
80
|
+
createdAt: datetime
|
|
81
|
+
updatedAt: datetime
|
|
82
|
+
|
|
83
|
+
version: DriftstoneVersion
|
|
84
|
+
channel: DriftstoneChannel
|
|
85
|
+
session: DriftstoneSession
|
|
86
|
+
access_group: DriftstoneAccessGroup
|
|
87
|
+
profile: DriftstoneProfile
|
|
88
|
+
instance: DriftstoneInstance
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def _from_api(
|
|
92
|
+
cls,
|
|
93
|
+
payload: Mapping[str, Any],
|
|
94
|
+
version: DriftstoneVersion,
|
|
95
|
+
channel: DriftstoneChannel,
|
|
96
|
+
session: DriftstoneSession,
|
|
97
|
+
access_group: DriftstoneAccessGroup,
|
|
98
|
+
profile: DriftstoneProfile,
|
|
99
|
+
instance: DriftstoneInstance,
|
|
100
|
+
) -> "DriftstoneAppModel":
|
|
101
|
+
return cls(
|
|
102
|
+
id=payload["id"],
|
|
103
|
+
orgId=payload["orgId"],
|
|
104
|
+
type=payload["type"],
|
|
105
|
+
name=payload["name"],
|
|
106
|
+
slug=payload["slug"],
|
|
107
|
+
vaultId=payload["vaultId"],
|
|
108
|
+
defaultAccessGroupId=payload["defaultAccessGroupId"],
|
|
109
|
+
headVersionId=payload.get("headVersionId"),
|
|
110
|
+
metadata=payload.get("metadata"),
|
|
111
|
+
createdAt=datetime.fromisoformat(payload["createdAt"]),
|
|
112
|
+
updatedAt=datetime.fromisoformat(payload["updatedAt"]),
|
|
113
|
+
|
|
114
|
+
version=version,
|
|
115
|
+
channel=channel,
|
|
116
|
+
session=session,
|
|
117
|
+
access_group=access_group,
|
|
118
|
+
profile=profile,
|
|
119
|
+
instance=instance,
|
|
120
|
+
)
|