contractlane-operator-sdk 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.
- contractlane_operator_sdk-0.1.0/.gitignore +9 -0
- contractlane_operator_sdk-0.1.0/PKG-INFO +96 -0
- contractlane_operator_sdk-0.1.0/README.md +80 -0
- contractlane_operator_sdk-0.1.0/pyproject.toml +34 -0
- contractlane_operator_sdk-0.1.0/src/contractlane_operator_sdk/__init__.py +22 -0
- contractlane_operator_sdk-0.1.0/src/contractlane_operator_sdk/client.py +428 -0
- contractlane_operator_sdk-0.1.0/src/contractlane_operator_sdk/errors.py +20 -0
- contractlane_operator_sdk-0.1.0/src/contractlane_operator_sdk/models.py +260 -0
- contractlane_operator_sdk-0.1.0/src/contractlane_operator_sdk/runtime.py +293 -0
- contractlane_operator_sdk-0.1.0/tests/integration/test_operator_integration.py +381 -0
- contractlane_operator_sdk-0.1.0/tests/test_client.py +301 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: contractlane-operator-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for Contract Lane Operator API
|
|
5
|
+
Author: Contract Lane
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: httpx>=0.27.2
|
|
9
|
+
Requires-Dist: pydantic>=2.10.3
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: mypy>=1.14.0; extra == 'dev'
|
|
12
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
13
|
+
Requires-Dist: pytest>=8.3.4; extra == 'dev'
|
|
14
|
+
Requires-Dist: ruff>=0.8.2; extra == 'dev'
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# contractlane-operator-sdk
|
|
18
|
+
|
|
19
|
+
Python SDK for the Contract Lane Operator API.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
```bash
|
|
23
|
+
pip install contractlane-operator-sdk
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quickstart
|
|
27
|
+
```python
|
|
28
|
+
from contractlane_operator_sdk import ClientOptions, OperatorClient
|
|
29
|
+
|
|
30
|
+
client = OperatorClient(
|
|
31
|
+
ClientOptions(
|
|
32
|
+
base_url="https://localhost",
|
|
33
|
+
session_token=lambda: "session-token",
|
|
34
|
+
operator_token=lambda: "operator-token",
|
|
35
|
+
challenge_headers=lambda _: {
|
|
36
|
+
"X-Signup-Challenge": "signup-challenge-token",
|
|
37
|
+
"X-Operator-Challenge": "proof-challenge",
|
|
38
|
+
"X-Operator-Challenge-Token": "challenge-provider-token",
|
|
39
|
+
},
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 1) Human signup/auth
|
|
45
|
+
```python
|
|
46
|
+
start = client.public.signup.start({"email": "owner@example.com", "org_name": "Acme"})
|
|
47
|
+
session_id = start.data["signup_session"]["session_id"]
|
|
48
|
+
|
|
49
|
+
client.public.signup.verify({"session_id": session_id, "verification_code": "123456"})
|
|
50
|
+
client.public.signup.complete({"session_id": session_id, "project_name": "Default", "agent_name": "Primary"})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 2) Admin actor + credential issue
|
|
54
|
+
```python
|
|
55
|
+
org = client.operator.admin.create_org({"name": "Acme", "admin_email": "owner@example.com"})
|
|
56
|
+
org_id = org.data["org"]["org_id"]
|
|
57
|
+
project = client.operator.admin.create_project(org_id, {"name": "Project A"})
|
|
58
|
+
project_id = project.data["project"]["project_id"]
|
|
59
|
+
actor = client.operator.admin.create_actor(project_id, {"name": "Bot", "scopes": ["cel.contracts:write"]})
|
|
60
|
+
actor_id = actor.data["actor"]["actor_id"]
|
|
61
|
+
client.operator.admin.issue_credential({"actor_id": actor_id, "upstream_token": "upstream-token"})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 3) Agent-first enrollment
|
|
65
|
+
```python
|
|
66
|
+
challenge = client.public.agent_enrollment.challenge(
|
|
67
|
+
{"public_key_jwk": {"kty": "OKP", "crv": "Ed25519", "x": "..."}}
|
|
68
|
+
)
|
|
69
|
+
challenge_id = challenge.data["challenge"]["challenge_id"]
|
|
70
|
+
client.public.agent_enrollment.start(
|
|
71
|
+
{
|
|
72
|
+
"challenge_id": challenge_id,
|
|
73
|
+
"signature": "base64url-signature",
|
|
74
|
+
"sponsor_email": "owner@example.com",
|
|
75
|
+
"requested_scopes": ["cel.contracts:write"],
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 4) Gateway contract action
|
|
81
|
+
```python
|
|
82
|
+
client.gateway.cel.create_contract({"template_id": "tpl_123", "payload": {}})
|
|
83
|
+
client.gateway.cel.contract_action("ctr_123", "send", {"note": "go"})
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Notes
|
|
87
|
+
- Mutating operator/public endpoints auto-inject `Idempotency-Key`.
|
|
88
|
+
- `request_id` is available via `response.meta.request_id`.
|
|
89
|
+
- Challenge hooks can provide `X-Signup-Challenge`, `X-Operator-Challenge`, and `X-Operator-Challenge-Token`; per-request headers can override hook values.
|
|
90
|
+
- Failures raise `APIError` with `status`, `code`, `message`, `request_id`, `meta`, `raw_body`.
|
|
91
|
+
|
|
92
|
+
## Integration Tests
|
|
93
|
+
Run against a live operator stack:
|
|
94
|
+
```bash
|
|
95
|
+
python -m pytest tests/integration -m integration
|
|
96
|
+
```
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# contractlane-operator-sdk
|
|
2
|
+
|
|
3
|
+
Python SDK for the Contract Lane Operator API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
```bash
|
|
7
|
+
pip install contractlane-operator-sdk
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Quickstart
|
|
11
|
+
```python
|
|
12
|
+
from contractlane_operator_sdk import ClientOptions, OperatorClient
|
|
13
|
+
|
|
14
|
+
client = OperatorClient(
|
|
15
|
+
ClientOptions(
|
|
16
|
+
base_url="https://localhost",
|
|
17
|
+
session_token=lambda: "session-token",
|
|
18
|
+
operator_token=lambda: "operator-token",
|
|
19
|
+
challenge_headers=lambda _: {
|
|
20
|
+
"X-Signup-Challenge": "signup-challenge-token",
|
|
21
|
+
"X-Operator-Challenge": "proof-challenge",
|
|
22
|
+
"X-Operator-Challenge-Token": "challenge-provider-token",
|
|
23
|
+
},
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 1) Human signup/auth
|
|
29
|
+
```python
|
|
30
|
+
start = client.public.signup.start({"email": "owner@example.com", "org_name": "Acme"})
|
|
31
|
+
session_id = start.data["signup_session"]["session_id"]
|
|
32
|
+
|
|
33
|
+
client.public.signup.verify({"session_id": session_id, "verification_code": "123456"})
|
|
34
|
+
client.public.signup.complete({"session_id": session_id, "project_name": "Default", "agent_name": "Primary"})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### 2) Admin actor + credential issue
|
|
38
|
+
```python
|
|
39
|
+
org = client.operator.admin.create_org({"name": "Acme", "admin_email": "owner@example.com"})
|
|
40
|
+
org_id = org.data["org"]["org_id"]
|
|
41
|
+
project = client.operator.admin.create_project(org_id, {"name": "Project A"})
|
|
42
|
+
project_id = project.data["project"]["project_id"]
|
|
43
|
+
actor = client.operator.admin.create_actor(project_id, {"name": "Bot", "scopes": ["cel.contracts:write"]})
|
|
44
|
+
actor_id = actor.data["actor"]["actor_id"]
|
|
45
|
+
client.operator.admin.issue_credential({"actor_id": actor_id, "upstream_token": "upstream-token"})
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3) Agent-first enrollment
|
|
49
|
+
```python
|
|
50
|
+
challenge = client.public.agent_enrollment.challenge(
|
|
51
|
+
{"public_key_jwk": {"kty": "OKP", "crv": "Ed25519", "x": "..."}}
|
|
52
|
+
)
|
|
53
|
+
challenge_id = challenge.data["challenge"]["challenge_id"]
|
|
54
|
+
client.public.agent_enrollment.start(
|
|
55
|
+
{
|
|
56
|
+
"challenge_id": challenge_id,
|
|
57
|
+
"signature": "base64url-signature",
|
|
58
|
+
"sponsor_email": "owner@example.com",
|
|
59
|
+
"requested_scopes": ["cel.contracts:write"],
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 4) Gateway contract action
|
|
65
|
+
```python
|
|
66
|
+
client.gateway.cel.create_contract({"template_id": "tpl_123", "payload": {}})
|
|
67
|
+
client.gateway.cel.contract_action("ctr_123", "send", {"note": "go"})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Notes
|
|
71
|
+
- Mutating operator/public endpoints auto-inject `Idempotency-Key`.
|
|
72
|
+
- `request_id` is available via `response.meta.request_id`.
|
|
73
|
+
- Challenge hooks can provide `X-Signup-Challenge`, `X-Operator-Challenge`, and `X-Operator-Challenge-Token`; per-request headers can override hook values.
|
|
74
|
+
- Failures raise `APIError` with `status`, `code`, `message`, `request_id`, `meta`, `raw_body`.
|
|
75
|
+
|
|
76
|
+
## Integration Tests
|
|
77
|
+
Run against a live operator stack:
|
|
78
|
+
```bash
|
|
79
|
+
python -m pytest tests/integration -m integration
|
|
80
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.26.0"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "contractlane-operator-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python SDK for Contract Lane Operator API"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Contract Lane" }]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"httpx>=0.27.2",
|
|
15
|
+
"pydantic>=2.10.3"
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
dev = [
|
|
20
|
+
"pytest>=8.3.4",
|
|
21
|
+
"pytest-asyncio>=0.24.0",
|
|
22
|
+
"ruff>=0.8.2",
|
|
23
|
+
"mypy>=1.14.0"
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[tool.hatch.build.targets.wheel]
|
|
27
|
+
packages = ["src/contractlane_operator_sdk"]
|
|
28
|
+
|
|
29
|
+
[tool.pytest.ini_options]
|
|
30
|
+
pythonpath = ["src"]
|
|
31
|
+
asyncio_mode = "auto"
|
|
32
|
+
markers = [
|
|
33
|
+
"integration: live integration tests against a running operator stack"
|
|
34
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .client import AsyncOperatorClient, OperatorClient
|
|
2
|
+
from .errors import APIError
|
|
3
|
+
from .models import (
|
|
4
|
+
APIResponse,
|
|
5
|
+
AuthMode,
|
|
6
|
+
ClientOptions,
|
|
7
|
+
RequestOptions,
|
|
8
|
+
ResponseMeta,
|
|
9
|
+
RetryOptions,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"APIError",
|
|
14
|
+
"APIResponse",
|
|
15
|
+
"AuthMode",
|
|
16
|
+
"ClientOptions",
|
|
17
|
+
"RequestOptions",
|
|
18
|
+
"ResponseMeta",
|
|
19
|
+
"RetryOptions",
|
|
20
|
+
"OperatorClient",
|
|
21
|
+
"AsyncOperatorClient",
|
|
22
|
+
]
|