trustos 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.
trustos-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Trust OS / Trustfolio Inc.
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.
trustos-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: trustos
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the Trust OS Decision Verification API
5
+ Author-email: "Trustfolio Inc." <admin@trust-os.io>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://trust-os.io
8
+ Project-URL: Documentation, https://trust-os.io/docs
9
+ Project-URL: Source, https://github.com/trustos-trustfolio/trustos-python-sdk
10
+ Project-URL: Issues, https://github.com/trustos-trustfolio/trustos-python-sdk/issues
11
+ Project-URL: OpenAPI, https://trust-os.io/openapi.json
12
+ Keywords: trust-os,decision-verification,ai-agents,fintech,api-client
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Internet :: WWW/HTTP
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: requests>=2.31.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
28
+ Requires-Dist: responses>=0.25.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # Trust OS Python SDK
32
+
33
+ Python SDK for the [Trust OS Decision Verification API](https://trust-os.io/docs/api).
34
+
35
+ Verify high-impact decisions before execution — payments, treasury operations, AI agent actions, and compliance workflows — with a single function call.
36
+
37
+ ## Links
38
+
39
+ | Resource | URL |
40
+ |---|---|
41
+ | Website | https://trust-os.io |
42
+ | Developer Docs | https://trust-os.io/docs |
43
+ | API Reference | https://trust-os.io/docs/api |
44
+ | Playground | https://demo.trust-os.io |
45
+ | Operations Demo | https://ops.trust-os.io |
46
+ | GitHub Organization | https://github.com/trustos-trustfolio |
47
+ | OpenAPI Spec | https://trust-os.io/openapi.json |
48
+
49
+ ---
50
+
51
+ ## Installation
52
+
53
+ > **PyPI release coming soon.** For now, install directly from GitHub once the repository is published:
54
+
55
+ ```bash
56
+ pip install git+https://github.com/trustos-trustfolio/trustos-python-sdk.git
57
+ ```
58
+
59
+ Once published to PyPI:
60
+
61
+ ```bash
62
+ pip install trustos
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Quick Start
68
+
69
+ ```python
70
+ from trustos import TrustOSClient
71
+
72
+ client = TrustOSClient(api_key="YOUR_API_KEY")
73
+
74
+ result = client.verify_decision({
75
+ "action": "stablecoin_transfer",
76
+ "amount": 50000,
77
+ "currency": "USDC",
78
+ "destination": "wallet_abc",
79
+ })
80
+
81
+ print(result["recommendation"]) # APPROVE | REVIEW | DENY
82
+ print(result["proof_hash"]) # SHA-256: 0x4a3f...9c2b
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Environment Variables
88
+
89
+ Store your API key as an environment variable instead of hardcoding it:
90
+
91
+ ```bash
92
+ # .env (never commit this file)
93
+ TRUSTOS_API_KEY=your_api_key_here
94
+ ```
95
+
96
+ The client reads `TRUSTOS_API_KEY` automatically when no `api_key=` argument is provided:
97
+
98
+ ```python
99
+ from trustos import TrustOSClient
100
+
101
+ client = TrustOSClient() # reads TRUSTOS_API_KEY from environment
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Examples
107
+
108
+ ### Stablecoin Payment
109
+
110
+ ```python
111
+ from trustos import TrustOSClient
112
+
113
+ client = TrustOSClient()
114
+
115
+ result = client.verify_decision({
116
+ "action": "stablecoin_transfer",
117
+ "amount": 250000,
118
+ "currency": "USDC",
119
+ "destination": "wallet_0x4f3b9c2a8d1e6f5a",
120
+ "source": "Payment API",
121
+ "priority": "High",
122
+ "metadata": {"region": "SG", "workflow": "merchant_settlement"},
123
+ })
124
+
125
+ if result["recommendation"] == "APPROVE":
126
+ # safe to execute the transfer
127
+ print("Approved:", result["decision_id"])
128
+ elif result["recommendation"] == "REVIEW":
129
+ # queue for human review
130
+ queue_for_review(result["decision_id"])
131
+ else:
132
+ # block the transfer
133
+ raise ValueError("Payment denied by Trust OS policy")
134
+ ```
135
+
136
+ ### Treasury Disbursement
137
+
138
+ ```python
139
+ result = client.verify_decision({
140
+ "action": "treasury_disbursement",
141
+ "amount": 1_000_000,
142
+ "currency": "USDC",
143
+ "destination": "dao_multisig_0x91a3b7c2",
144
+ "source": "governance-system",
145
+ "priority": "High",
146
+ })
147
+ ```
148
+
149
+ ### AI Agent Action
150
+
151
+ ```python
152
+ result = client.verify_decision({
153
+ "action": "execute_tool",
154
+ "destination": "database_write",
155
+ "source": "agent-framework",
156
+ "priority": "High",
157
+ "metadata": {"tool": "write_record", "agent_id": "agent_alpha_001"},
158
+ })
159
+ ```
160
+
161
+ More complete examples are in the [`examples/`](./examples/) directory.
162
+
163
+ ---
164
+
165
+ ## API Reference
166
+
167
+ ### `TrustOSClient(api_key=None, base_url=None, timeout=10.0)`
168
+
169
+ | Parameter | Type | Default | Description |
170
+ |---|---|---|---|
171
+ | `api_key` | `str \| None` | `None` | API key. Falls back to `TRUSTOS_API_KEY` env var. |
172
+ | `base_url` | `str \| None` | Production gateway | Override the API base URL. |
173
+ | `timeout` | `float` | `10.0` | Request timeout in seconds. |
174
+
175
+ Raises `ValueError` if no API key is found.
176
+
177
+ ### `client.verify_decision(payload: dict) -> dict`
178
+
179
+ Submit a decision for verification. Returns the parsed JSON response.
180
+
181
+ **Request fields:**
182
+
183
+ | Field | Type | Required | Description |
184
+ |---|---|---|---|
185
+ | `action` | string | **Yes** | Decision action type |
186
+ | `amount` | number | No | Transaction amount |
187
+ | `currency` | string | No | Currency or asset symbol |
188
+ | `destination` | string | No | Target wallet or account |
189
+ | `source` | string | No | Originating system |
190
+ | `priority` | string | No | `"High"`, `"Medium"`, or `"Low"` |
191
+ | `metadata` | object | No | Additional context fields |
192
+
193
+ **Response fields:**
194
+
195
+ | Field | Type | Description |
196
+ |---|---|---|
197
+ | `decision_id` | string | Unique identifier — store for audit trail |
198
+ | `recommendation` | string | `APPROVE`, `REVIEW`, or `DENY` |
199
+ | `risk_score` | number | 0.0 (no risk) to 1.0 (maximum) |
200
+ | `risk_level` | string | `LOW`, `MEDIUM`, or `HIGH` |
201
+ | `policy` | string | Policy name and version applied |
202
+ | `proof_hash` | string | SHA-256 cryptographic proof |
203
+ | `verified` | boolean | True when cryptographically verified |
204
+ | `latency_ms` | number | Evaluation latency in milliseconds |
205
+
206
+ ### `client.verify(payload: dict) -> dict`
207
+
208
+ Alias for `verify_decision()`.
209
+
210
+ ---
211
+
212
+ ## Error Handling
213
+
214
+ ```python
215
+ from trustos import TrustOSClient, TrustOSError
216
+
217
+ client = TrustOSClient()
218
+
219
+ try:
220
+ result = client.verify_decision({"action": "stablecoin_transfer"})
221
+ except TrustOSError as e:
222
+ print(f"Status code: {e.status_code}")
223
+ print(f"Response body: {e.response_body}")
224
+ print(f"Message: {e}")
225
+ ```
226
+
227
+ `TrustOSError` is raised on:
228
+
229
+ - Non-2xx HTTP responses (401 unauthorized, 429 rate limit, 500 server error, etc.)
230
+ - Network errors or timeouts
231
+ - Invalid JSON in the response body
232
+
233
+ ---
234
+
235
+ ## Security
236
+
237
+ - **Never commit your API key.** Use environment variables or a secrets manager.
238
+ - **Never hardcode keys in example scripts.** All examples use `TrustOSClient()` with no inline key.
239
+ - See [SECURITY.md](./SECURITY.md) for the vulnerability disclosure policy.
240
+
241
+ ---
242
+
243
+ ## Contributing
244
+
245
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
246
+
247
+ ---
248
+
249
+ ## Changelog
250
+
251
+ See [CHANGELOG.md](./CHANGELOG.md) for version history.
252
+
253
+ ---
254
+
255
+ ## License
256
+
257
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,227 @@
1
+ # Trust OS Python SDK
2
+
3
+ Python SDK for the [Trust OS Decision Verification API](https://trust-os.io/docs/api).
4
+
5
+ Verify high-impact decisions before execution — payments, treasury operations, AI agent actions, and compliance workflows — with a single function call.
6
+
7
+ ## Links
8
+
9
+ | Resource | URL |
10
+ |---|---|
11
+ | Website | https://trust-os.io |
12
+ | Developer Docs | https://trust-os.io/docs |
13
+ | API Reference | https://trust-os.io/docs/api |
14
+ | Playground | https://demo.trust-os.io |
15
+ | Operations Demo | https://ops.trust-os.io |
16
+ | GitHub Organization | https://github.com/trustos-trustfolio |
17
+ | OpenAPI Spec | https://trust-os.io/openapi.json |
18
+
19
+ ---
20
+
21
+ ## Installation
22
+
23
+ > **PyPI release coming soon.** For now, install directly from GitHub once the repository is published:
24
+
25
+ ```bash
26
+ pip install git+https://github.com/trustos-trustfolio/trustos-python-sdk.git
27
+ ```
28
+
29
+ Once published to PyPI:
30
+
31
+ ```bash
32
+ pip install trustos
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Quick Start
38
+
39
+ ```python
40
+ from trustos import TrustOSClient
41
+
42
+ client = TrustOSClient(api_key="YOUR_API_KEY")
43
+
44
+ result = client.verify_decision({
45
+ "action": "stablecoin_transfer",
46
+ "amount": 50000,
47
+ "currency": "USDC",
48
+ "destination": "wallet_abc",
49
+ })
50
+
51
+ print(result["recommendation"]) # APPROVE | REVIEW | DENY
52
+ print(result["proof_hash"]) # SHA-256: 0x4a3f...9c2b
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Environment Variables
58
+
59
+ Store your API key as an environment variable instead of hardcoding it:
60
+
61
+ ```bash
62
+ # .env (never commit this file)
63
+ TRUSTOS_API_KEY=your_api_key_here
64
+ ```
65
+
66
+ The client reads `TRUSTOS_API_KEY` automatically when no `api_key=` argument is provided:
67
+
68
+ ```python
69
+ from trustos import TrustOSClient
70
+
71
+ client = TrustOSClient() # reads TRUSTOS_API_KEY from environment
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Examples
77
+
78
+ ### Stablecoin Payment
79
+
80
+ ```python
81
+ from trustos import TrustOSClient
82
+
83
+ client = TrustOSClient()
84
+
85
+ result = client.verify_decision({
86
+ "action": "stablecoin_transfer",
87
+ "amount": 250000,
88
+ "currency": "USDC",
89
+ "destination": "wallet_0x4f3b9c2a8d1e6f5a",
90
+ "source": "Payment API",
91
+ "priority": "High",
92
+ "metadata": {"region": "SG", "workflow": "merchant_settlement"},
93
+ })
94
+
95
+ if result["recommendation"] == "APPROVE":
96
+ # safe to execute the transfer
97
+ print("Approved:", result["decision_id"])
98
+ elif result["recommendation"] == "REVIEW":
99
+ # queue for human review
100
+ queue_for_review(result["decision_id"])
101
+ else:
102
+ # block the transfer
103
+ raise ValueError("Payment denied by Trust OS policy")
104
+ ```
105
+
106
+ ### Treasury Disbursement
107
+
108
+ ```python
109
+ result = client.verify_decision({
110
+ "action": "treasury_disbursement",
111
+ "amount": 1_000_000,
112
+ "currency": "USDC",
113
+ "destination": "dao_multisig_0x91a3b7c2",
114
+ "source": "governance-system",
115
+ "priority": "High",
116
+ })
117
+ ```
118
+
119
+ ### AI Agent Action
120
+
121
+ ```python
122
+ result = client.verify_decision({
123
+ "action": "execute_tool",
124
+ "destination": "database_write",
125
+ "source": "agent-framework",
126
+ "priority": "High",
127
+ "metadata": {"tool": "write_record", "agent_id": "agent_alpha_001"},
128
+ })
129
+ ```
130
+
131
+ More complete examples are in the [`examples/`](./examples/) directory.
132
+
133
+ ---
134
+
135
+ ## API Reference
136
+
137
+ ### `TrustOSClient(api_key=None, base_url=None, timeout=10.0)`
138
+
139
+ | Parameter | Type | Default | Description |
140
+ |---|---|---|---|
141
+ | `api_key` | `str \| None` | `None` | API key. Falls back to `TRUSTOS_API_KEY` env var. |
142
+ | `base_url` | `str \| None` | Production gateway | Override the API base URL. |
143
+ | `timeout` | `float` | `10.0` | Request timeout in seconds. |
144
+
145
+ Raises `ValueError` if no API key is found.
146
+
147
+ ### `client.verify_decision(payload: dict) -> dict`
148
+
149
+ Submit a decision for verification. Returns the parsed JSON response.
150
+
151
+ **Request fields:**
152
+
153
+ | Field | Type | Required | Description |
154
+ |---|---|---|---|
155
+ | `action` | string | **Yes** | Decision action type |
156
+ | `amount` | number | No | Transaction amount |
157
+ | `currency` | string | No | Currency or asset symbol |
158
+ | `destination` | string | No | Target wallet or account |
159
+ | `source` | string | No | Originating system |
160
+ | `priority` | string | No | `"High"`, `"Medium"`, or `"Low"` |
161
+ | `metadata` | object | No | Additional context fields |
162
+
163
+ **Response fields:**
164
+
165
+ | Field | Type | Description |
166
+ |---|---|---|
167
+ | `decision_id` | string | Unique identifier — store for audit trail |
168
+ | `recommendation` | string | `APPROVE`, `REVIEW`, or `DENY` |
169
+ | `risk_score` | number | 0.0 (no risk) to 1.0 (maximum) |
170
+ | `risk_level` | string | `LOW`, `MEDIUM`, or `HIGH` |
171
+ | `policy` | string | Policy name and version applied |
172
+ | `proof_hash` | string | SHA-256 cryptographic proof |
173
+ | `verified` | boolean | True when cryptographically verified |
174
+ | `latency_ms` | number | Evaluation latency in milliseconds |
175
+
176
+ ### `client.verify(payload: dict) -> dict`
177
+
178
+ Alias for `verify_decision()`.
179
+
180
+ ---
181
+
182
+ ## Error Handling
183
+
184
+ ```python
185
+ from trustos import TrustOSClient, TrustOSError
186
+
187
+ client = TrustOSClient()
188
+
189
+ try:
190
+ result = client.verify_decision({"action": "stablecoin_transfer"})
191
+ except TrustOSError as e:
192
+ print(f"Status code: {e.status_code}")
193
+ print(f"Response body: {e.response_body}")
194
+ print(f"Message: {e}")
195
+ ```
196
+
197
+ `TrustOSError` is raised on:
198
+
199
+ - Non-2xx HTTP responses (401 unauthorized, 429 rate limit, 500 server error, etc.)
200
+ - Network errors or timeouts
201
+ - Invalid JSON in the response body
202
+
203
+ ---
204
+
205
+ ## Security
206
+
207
+ - **Never commit your API key.** Use environment variables or a secrets manager.
208
+ - **Never hardcode keys in example scripts.** All examples use `TrustOSClient()` with no inline key.
209
+ - See [SECURITY.md](./SECURITY.md) for the vulnerability disclosure policy.
210
+
211
+ ---
212
+
213
+ ## Contributing
214
+
215
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
216
+
217
+ ---
218
+
219
+ ## Changelog
220
+
221
+ See [CHANGELOG.md](./CHANGELOG.md) for version history.
222
+
223
+ ---
224
+
225
+ ## License
226
+
227
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["setuptools>=70", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "trustos"
7
+ version = "0.1.0"
8
+ description = "Python SDK for the Trust OS Decision Verification API"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [{ name = "Trustfolio Inc.", email = "admin@trust-os.io" }]
13
+ requires-python = ">=3.9"
14
+ dependencies = ["requests>=2.31.0"]
15
+ keywords = ["trust-os", "decision-verification", "ai-agents", "fintech", "api-client"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Software Development :: Libraries :: Python Modules",
25
+ "Topic :: Internet :: WWW/HTTP",
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://trust-os.io"
30
+ Documentation = "https://trust-os.io/docs"
31
+ Source = "https://github.com/trustos-trustfolio/trustos-python-sdk"
32
+ Issues = "https://github.com/trustos-trustfolio/trustos-python-sdk/issues"
33
+ OpenAPI = "https://trust-os.io/openapi.json"
34
+
35
+ [project.optional-dependencies]
36
+ dev = ["pytest>=8.0.0", "responses>=0.25.0"]
37
+
38
+ [tool.setuptools.packages.find]
39
+ include = ["trustos*"]
40
+
41
+ [tool.pytest.ini_options]
42
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,165 @@
1
+ """Tests for TrustOSClient."""
2
+
3
+ import os
4
+ import json
5
+
6
+ import pytest
7
+ import responses as resp_mock
8
+
9
+ from trustos import TrustOSClient, TrustOSError
10
+
11
+ _API_KEY = "test_api_key_abc123"
12
+ _BASE_URL = "https://trustos-core-gateway-v2-7jm9owrs.an.gateway.dev"
13
+ _VERIFY_URL = f"{_BASE_URL}/v1/decision/verify"
14
+
15
+ _MOCK_RESPONSE = {
16
+ "decision_id": "dec_example_001",
17
+ "recommendation": "APPROVE",
18
+ "risk_score": 0.18,
19
+ "risk_level": "LOW",
20
+ "policy": "Stablecoin Settlement Policy v1.0",
21
+ "proof_hash": "SHA-256: 0x4a3f...9c2b",
22
+ "verified": True,
23
+ "latency_ms": 142,
24
+ }
25
+
26
+ _PAYLOAD = {"action": "stablecoin_transfer", "amount": 50000, "currency": "USDC"}
27
+
28
+
29
+ # ── constructor ───────────────────────────────────────────────────────────────
30
+
31
+
32
+ def test_raises_without_api_key(monkeypatch):
33
+ """Client must raise ValueError when no key is available."""
34
+ monkeypatch.delenv("TRUSTOS_API_KEY", raising=False)
35
+ with pytest.raises(ValueError, match="No API key provided"):
36
+ TrustOSClient()
37
+
38
+
39
+ def test_reads_api_key_from_env(monkeypatch):
40
+ """Client reads API key from TRUSTOS_API_KEY env var."""
41
+ monkeypatch.setenv("TRUSTOS_API_KEY", _API_KEY)
42
+ client = TrustOSClient()
43
+ assert client._api_key == _API_KEY
44
+
45
+
46
+ def test_explicit_api_key_takes_precedence(monkeypatch):
47
+ """Explicit api_key= overrides the environment variable."""
48
+ monkeypatch.setenv("TRUSTOS_API_KEY", "env_key")
49
+ client = TrustOSClient(api_key="explicit_key")
50
+ assert client._api_key == "explicit_key"
51
+
52
+
53
+ def test_trailing_slash_removed():
54
+ """Trailing slashes are stripped from base_url."""
55
+ client = TrustOSClient(api_key=_API_KEY, base_url="https://example.com///")
56
+ assert client._base_url == "https://example.com"
57
+
58
+
59
+ def test_default_base_url():
60
+ """Default base URL points to the production gateway."""
61
+ client = TrustOSClient(api_key=_API_KEY)
62
+ assert "trustos-core-gateway" in client._base_url
63
+
64
+
65
+ # ── verify_decision ───────────────────────────────────────────────────────────
66
+
67
+
68
+ @resp_mock.activate
69
+ def test_verify_decision_posts_to_correct_url():
70
+ """verify_decision sends a POST to /v1/decision/verify."""
71
+ resp_mock.add(
72
+ resp_mock.POST,
73
+ _VERIFY_URL,
74
+ json=_MOCK_RESPONSE,
75
+ status=200,
76
+ )
77
+ client = TrustOSClient(api_key=_API_KEY)
78
+ result = client.verify_decision(_PAYLOAD)
79
+ assert result["decision_id"] == "dec_example_001"
80
+ assert len(resp_mock.calls) == 1
81
+ assert resp_mock.calls[0].request.method == "POST"
82
+ assert "/v1/decision/verify" in resp_mock.calls[0].request.url
83
+
84
+
85
+ @resp_mock.activate
86
+ def test_x_api_key_header_is_set():
87
+ """The x-api-key header is present on every request."""
88
+ resp_mock.add(resp_mock.POST, _VERIFY_URL, json=_MOCK_RESPONSE, status=200)
89
+ client = TrustOSClient(api_key=_API_KEY)
90
+ client.verify_decision(_PAYLOAD)
91
+ assert resp_mock.calls[0].request.headers.get("x-api-key") == _API_KEY
92
+
93
+
94
+ @resp_mock.activate
95
+ def test_verify_alias_calls_verify_decision():
96
+ """verify() is a transparent alias for verify_decision()."""
97
+ resp_mock.add(resp_mock.POST, _VERIFY_URL, json=_MOCK_RESPONSE, status=200)
98
+ client = TrustOSClient(api_key=_API_KEY)
99
+ result = client.verify(_PAYLOAD)
100
+ assert result["recommendation"] == "APPROVE"
101
+ assert len(resp_mock.calls) == 1
102
+
103
+
104
+ @resp_mock.activate
105
+ def test_non_2xx_raises_trustos_error():
106
+ """Non-2xx responses raise TrustOSError with the status code."""
107
+ resp_mock.add(
108
+ resp_mock.POST,
109
+ _VERIFY_URL,
110
+ json={"error": "unauthorized", "message": "Invalid API key"},
111
+ status=401,
112
+ )
113
+ client = TrustOSClient(api_key="bad_key")
114
+ with pytest.raises(TrustOSError) as exc_info:
115
+ client.verify_decision(_PAYLOAD)
116
+ assert exc_info.value.status_code == 401
117
+ assert "401" in str(exc_info.value)
118
+
119
+
120
+ @resp_mock.activate
121
+ def test_rate_limit_raises_trustos_error():
122
+ """429 responses raise TrustOSError."""
123
+ resp_mock.add(
124
+ resp_mock.POST,
125
+ _VERIFY_URL,
126
+ json={"error": "rate_limit_exceeded", "message": "Too many requests"},
127
+ status=429,
128
+ )
129
+ client = TrustOSClient(api_key=_API_KEY)
130
+ with pytest.raises(TrustOSError) as exc_info:
131
+ client.verify_decision(_PAYLOAD)
132
+ assert exc_info.value.status_code == 429
133
+
134
+
135
+ @resp_mock.activate
136
+ def test_invalid_json_raises_trustos_error():
137
+ """A non-JSON response body raises TrustOSError."""
138
+ resp_mock.add(
139
+ resp_mock.POST,
140
+ _VERIFY_URL,
141
+ body="not json at all",
142
+ status=200,
143
+ content_type="text/plain",
144
+ )
145
+ client = TrustOSClient(api_key=_API_KEY)
146
+ with pytest.raises(TrustOSError, match="Invalid JSON"):
147
+ client.verify_decision(_PAYLOAD)
148
+
149
+
150
+ @resp_mock.activate
151
+ def test_response_body_attached_on_error():
152
+ """TrustOSError.response_body contains the raw error text."""
153
+ error_body = json.dumps({"error": "internal_error", "message": "Internal server error"})
154
+ resp_mock.add(
155
+ resp_mock.POST,
156
+ _VERIFY_URL,
157
+ body=error_body,
158
+ status=500,
159
+ content_type="application/json",
160
+ )
161
+ client = TrustOSClient(api_key=_API_KEY)
162
+ with pytest.raises(TrustOSError) as exc_info:
163
+ client.verify_decision(_PAYLOAD)
164
+ assert exc_info.value.response_body is not None
165
+ assert "internal_error" in exc_info.value.response_body
@@ -0,0 +1,6 @@
1
+ """Trust OS Python SDK."""
2
+
3
+ from trustos.client import TrustOSClient, TrustOSError
4
+
5
+ __all__ = ["TrustOSClient", "TrustOSError"]
6
+ __version__ = "0.1.0"
@@ -0,0 +1,130 @@
1
+ """Trust OS Python SDK — Decision Verification API client."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any
7
+
8
+ import requests
9
+
10
+
11
+ DEFAULT_BASE_URL = "https://trustos-core-gateway-v2-7jm9owrs.an.gateway.dev"
12
+ _VERIFY_PATH = "/v1/decision/verify"
13
+
14
+
15
+ class TrustOSError(Exception):
16
+ """Raised when the Trust OS API returns a non-2xx response or an
17
+ unexpected payload.
18
+
19
+ Attributes:
20
+ status_code: HTTP status code, or None for network/parse errors.
21
+ response_body: Raw response text, or None when unavailable.
22
+ """
23
+
24
+ def __init__(
25
+ self,
26
+ message: str,
27
+ *,
28
+ status_code: int | None = None,
29
+ response_body: str | None = None,
30
+ ) -> None:
31
+ super().__init__(message)
32
+ self.status_code = status_code
33
+ self.response_body = response_body
34
+
35
+ def __repr__(self) -> str:
36
+ return (
37
+ f"TrustOSError(status_code={self.status_code!r}, "
38
+ f"message={str(self)!r})"
39
+ )
40
+
41
+
42
+ class TrustOSClient:
43
+ """Client for the Trust OS Decision Verification API.
44
+
45
+ Args:
46
+ api_key: API key for authentication. If *None*, the value of the
47
+ ``TRUSTOS_API_KEY`` environment variable is used instead.
48
+ base_url: Override the API base URL. Trailing slashes are removed
49
+ automatically. Defaults to the production gateway.
50
+ timeout: Request timeout in seconds. Defaults to 10.0.
51
+
52
+ Raises:
53
+ ValueError: If no API key is provided and ``TRUSTOS_API_KEY`` is
54
+ not set in the environment.
55
+
56
+ Example::
57
+
58
+ from trustos import TrustOSClient
59
+
60
+ client = TrustOSClient(api_key="YOUR_API_KEY")
61
+ result = client.verify_decision({"action": "stablecoin_transfer"})
62
+ """
63
+
64
+ def __init__(
65
+ self,
66
+ api_key: str | None = None,
67
+ base_url: str | None = None,
68
+ timeout: float = 10.0,
69
+ ) -> None:
70
+ resolved_key = api_key or os.environ.get("TRUSTOS_API_KEY")
71
+ if not resolved_key:
72
+ raise ValueError(
73
+ "No API key provided. Pass api_key= to TrustOSClient() "
74
+ "or set the TRUSTOS_API_KEY environment variable."
75
+ )
76
+ self._api_key = resolved_key
77
+ self._base_url = (base_url or DEFAULT_BASE_URL).rstrip("/")
78
+ self._timeout = timeout
79
+ self._session = requests.Session()
80
+ self._session.headers.update({
81
+ "Content-Type": "application/json",
82
+ "x-api-key": self._api_key,
83
+ "User-Agent": "trustos-python-sdk/0.1.0",
84
+ })
85
+
86
+ def verify_decision(self, payload: dict[str, Any]) -> dict[str, Any]:
87
+ """Submit a decision payload for verification.
88
+
89
+ Args:
90
+ payload: Decision fields. ``action`` is the only required key.
91
+ Optional keys: ``amount``, ``currency``, ``destination``,
92
+ ``source``, ``priority``, ``metadata``.
93
+
94
+ Returns:
95
+ Parsed JSON response containing ``decision_id``,
96
+ ``recommendation``, ``risk_score``, ``risk_level``, ``policy``,
97
+ ``proof_hash``, ``verified``, and ``latency_ms``.
98
+
99
+ Raises:
100
+ TrustOSError: On non-2xx HTTP status or unparseable response.
101
+ """
102
+ url = f"{self._base_url}{_VERIFY_PATH}"
103
+ try:
104
+ response = self._session.post(url, json=payload, timeout=self._timeout)
105
+ except requests.RequestException as exc:
106
+ raise TrustOSError(f"Request failed: {exc}") from exc
107
+
108
+ if not response.ok:
109
+ try:
110
+ body = response.text
111
+ except Exception:
112
+ body = None
113
+ raise TrustOSError(
114
+ f"API error {response.status_code}: {response.reason}",
115
+ status_code=response.status_code,
116
+ response_body=body,
117
+ )
118
+
119
+ try:
120
+ return response.json()
121
+ except ValueError as exc:
122
+ raise TrustOSError(
123
+ "Invalid JSON in API response",
124
+ status_code=response.status_code,
125
+ response_body=response.text,
126
+ ) from exc
127
+
128
+ def verify(self, payload: dict[str, Any]) -> dict[str, Any]:
129
+ """Alias for :meth:`verify_decision`."""
130
+ return self.verify_decision(payload)
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: trustos
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the Trust OS Decision Verification API
5
+ Author-email: "Trustfolio Inc." <admin@trust-os.io>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://trust-os.io
8
+ Project-URL: Documentation, https://trust-os.io/docs
9
+ Project-URL: Source, https://github.com/trustos-trustfolio/trustos-python-sdk
10
+ Project-URL: Issues, https://github.com/trustos-trustfolio/trustos-python-sdk/issues
11
+ Project-URL: OpenAPI, https://trust-os.io/openapi.json
12
+ Keywords: trust-os,decision-verification,ai-agents,fintech,api-client
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Internet :: WWW/HTTP
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: requests>=2.31.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
28
+ Requires-Dist: responses>=0.25.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # Trust OS Python SDK
32
+
33
+ Python SDK for the [Trust OS Decision Verification API](https://trust-os.io/docs/api).
34
+
35
+ Verify high-impact decisions before execution — payments, treasury operations, AI agent actions, and compliance workflows — with a single function call.
36
+
37
+ ## Links
38
+
39
+ | Resource | URL |
40
+ |---|---|
41
+ | Website | https://trust-os.io |
42
+ | Developer Docs | https://trust-os.io/docs |
43
+ | API Reference | https://trust-os.io/docs/api |
44
+ | Playground | https://demo.trust-os.io |
45
+ | Operations Demo | https://ops.trust-os.io |
46
+ | GitHub Organization | https://github.com/trustos-trustfolio |
47
+ | OpenAPI Spec | https://trust-os.io/openapi.json |
48
+
49
+ ---
50
+
51
+ ## Installation
52
+
53
+ > **PyPI release coming soon.** For now, install directly from GitHub once the repository is published:
54
+
55
+ ```bash
56
+ pip install git+https://github.com/trustos-trustfolio/trustos-python-sdk.git
57
+ ```
58
+
59
+ Once published to PyPI:
60
+
61
+ ```bash
62
+ pip install trustos
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Quick Start
68
+
69
+ ```python
70
+ from trustos import TrustOSClient
71
+
72
+ client = TrustOSClient(api_key="YOUR_API_KEY")
73
+
74
+ result = client.verify_decision({
75
+ "action": "stablecoin_transfer",
76
+ "amount": 50000,
77
+ "currency": "USDC",
78
+ "destination": "wallet_abc",
79
+ })
80
+
81
+ print(result["recommendation"]) # APPROVE | REVIEW | DENY
82
+ print(result["proof_hash"]) # SHA-256: 0x4a3f...9c2b
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Environment Variables
88
+
89
+ Store your API key as an environment variable instead of hardcoding it:
90
+
91
+ ```bash
92
+ # .env (never commit this file)
93
+ TRUSTOS_API_KEY=your_api_key_here
94
+ ```
95
+
96
+ The client reads `TRUSTOS_API_KEY` automatically when no `api_key=` argument is provided:
97
+
98
+ ```python
99
+ from trustos import TrustOSClient
100
+
101
+ client = TrustOSClient() # reads TRUSTOS_API_KEY from environment
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Examples
107
+
108
+ ### Stablecoin Payment
109
+
110
+ ```python
111
+ from trustos import TrustOSClient
112
+
113
+ client = TrustOSClient()
114
+
115
+ result = client.verify_decision({
116
+ "action": "stablecoin_transfer",
117
+ "amount": 250000,
118
+ "currency": "USDC",
119
+ "destination": "wallet_0x4f3b9c2a8d1e6f5a",
120
+ "source": "Payment API",
121
+ "priority": "High",
122
+ "metadata": {"region": "SG", "workflow": "merchant_settlement"},
123
+ })
124
+
125
+ if result["recommendation"] == "APPROVE":
126
+ # safe to execute the transfer
127
+ print("Approved:", result["decision_id"])
128
+ elif result["recommendation"] == "REVIEW":
129
+ # queue for human review
130
+ queue_for_review(result["decision_id"])
131
+ else:
132
+ # block the transfer
133
+ raise ValueError("Payment denied by Trust OS policy")
134
+ ```
135
+
136
+ ### Treasury Disbursement
137
+
138
+ ```python
139
+ result = client.verify_decision({
140
+ "action": "treasury_disbursement",
141
+ "amount": 1_000_000,
142
+ "currency": "USDC",
143
+ "destination": "dao_multisig_0x91a3b7c2",
144
+ "source": "governance-system",
145
+ "priority": "High",
146
+ })
147
+ ```
148
+
149
+ ### AI Agent Action
150
+
151
+ ```python
152
+ result = client.verify_decision({
153
+ "action": "execute_tool",
154
+ "destination": "database_write",
155
+ "source": "agent-framework",
156
+ "priority": "High",
157
+ "metadata": {"tool": "write_record", "agent_id": "agent_alpha_001"},
158
+ })
159
+ ```
160
+
161
+ More complete examples are in the [`examples/`](./examples/) directory.
162
+
163
+ ---
164
+
165
+ ## API Reference
166
+
167
+ ### `TrustOSClient(api_key=None, base_url=None, timeout=10.0)`
168
+
169
+ | Parameter | Type | Default | Description |
170
+ |---|---|---|---|
171
+ | `api_key` | `str \| None` | `None` | API key. Falls back to `TRUSTOS_API_KEY` env var. |
172
+ | `base_url` | `str \| None` | Production gateway | Override the API base URL. |
173
+ | `timeout` | `float` | `10.0` | Request timeout in seconds. |
174
+
175
+ Raises `ValueError` if no API key is found.
176
+
177
+ ### `client.verify_decision(payload: dict) -> dict`
178
+
179
+ Submit a decision for verification. Returns the parsed JSON response.
180
+
181
+ **Request fields:**
182
+
183
+ | Field | Type | Required | Description |
184
+ |---|---|---|---|
185
+ | `action` | string | **Yes** | Decision action type |
186
+ | `amount` | number | No | Transaction amount |
187
+ | `currency` | string | No | Currency or asset symbol |
188
+ | `destination` | string | No | Target wallet or account |
189
+ | `source` | string | No | Originating system |
190
+ | `priority` | string | No | `"High"`, `"Medium"`, or `"Low"` |
191
+ | `metadata` | object | No | Additional context fields |
192
+
193
+ **Response fields:**
194
+
195
+ | Field | Type | Description |
196
+ |---|---|---|
197
+ | `decision_id` | string | Unique identifier — store for audit trail |
198
+ | `recommendation` | string | `APPROVE`, `REVIEW`, or `DENY` |
199
+ | `risk_score` | number | 0.0 (no risk) to 1.0 (maximum) |
200
+ | `risk_level` | string | `LOW`, `MEDIUM`, or `HIGH` |
201
+ | `policy` | string | Policy name and version applied |
202
+ | `proof_hash` | string | SHA-256 cryptographic proof |
203
+ | `verified` | boolean | True when cryptographically verified |
204
+ | `latency_ms` | number | Evaluation latency in milliseconds |
205
+
206
+ ### `client.verify(payload: dict) -> dict`
207
+
208
+ Alias for `verify_decision()`.
209
+
210
+ ---
211
+
212
+ ## Error Handling
213
+
214
+ ```python
215
+ from trustos import TrustOSClient, TrustOSError
216
+
217
+ client = TrustOSClient()
218
+
219
+ try:
220
+ result = client.verify_decision({"action": "stablecoin_transfer"})
221
+ except TrustOSError as e:
222
+ print(f"Status code: {e.status_code}")
223
+ print(f"Response body: {e.response_body}")
224
+ print(f"Message: {e}")
225
+ ```
226
+
227
+ `TrustOSError` is raised on:
228
+
229
+ - Non-2xx HTTP responses (401 unauthorized, 429 rate limit, 500 server error, etc.)
230
+ - Network errors or timeouts
231
+ - Invalid JSON in the response body
232
+
233
+ ---
234
+
235
+ ## Security
236
+
237
+ - **Never commit your API key.** Use environment variables or a secrets manager.
238
+ - **Never hardcode keys in example scripts.** All examples use `TrustOSClient()` with no inline key.
239
+ - See [SECURITY.md](./SECURITY.md) for the vulnerability disclosure policy.
240
+
241
+ ---
242
+
243
+ ## Contributing
244
+
245
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
246
+
247
+ ---
248
+
249
+ ## Changelog
250
+
251
+ See [CHANGELOG.md](./CHANGELOG.md) for version history.
252
+
253
+ ---
254
+
255
+ ## License
256
+
257
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ tests/test_client.py
5
+ trustos/__init__.py
6
+ trustos/client.py
7
+ trustos.egg-info/PKG-INFO
8
+ trustos.egg-info/SOURCES.txt
9
+ trustos.egg-info/dependency_links.txt
10
+ trustos.egg-info/requires.txt
11
+ trustos.egg-info/top_level.txt
@@ -0,0 +1,5 @@
1
+ requests>=2.31.0
2
+
3
+ [dev]
4
+ pytest>=8.0.0
5
+ responses>=0.25.0
@@ -0,0 +1 @@
1
+ trustos