agledger 2.0.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.
Files changed (36) hide show
  1. agledger-2.0.0/LICENSE +34 -0
  2. agledger-2.0.0/PKG-INFO +44 -0
  3. agledger-2.0.0/README.md +18 -0
  4. agledger-2.0.0/pyproject.toml +45 -0
  5. agledger-2.0.0/src/agledger/__init__.py +85 -0
  6. agledger-2.0.0/src/agledger/_client.py +163 -0
  7. agledger-2.0.0/src/agledger/_errors.py +132 -0
  8. agledger-2.0.0/src/agledger/_http.py +331 -0
  9. agledger-2.0.0/src/agledger/py.typed +0 -0
  10. agledger-2.0.0/src/agledger/resources/__init__.py +37 -0
  11. agledger-2.0.0/src/agledger/resources/a2a.py +30 -0
  12. agledger-2.0.0/src/agledger/resources/admin.py +41 -0
  13. agledger-2.0.0/src/agledger/resources/capabilities.py +29 -0
  14. agledger-2.0.0/src/agledger/resources/compliance.py +35 -0
  15. agledger-2.0.0/src/agledger/resources/dashboard.py +30 -0
  16. agledger-2.0.0/src/agledger/resources/disputes.py +54 -0
  17. agledger-2.0.0/src/agledger/resources/enterprises.py +46 -0
  18. agledger-2.0.0/src/agledger/resources/events.py +48 -0
  19. agledger-2.0.0/src/agledger/resources/health.py +21 -0
  20. agledger-2.0.0/src/agledger/resources/mandates.py +263 -0
  21. agledger-2.0.0/src/agledger/resources/notarize.py +57 -0
  22. agledger-2.0.0/src/agledger/resources/receipts.py +69 -0
  23. agledger-2.0.0/src/agledger/resources/registration.py +34 -0
  24. agledger-2.0.0/src/agledger/resources/reputation.py +24 -0
  25. agledger-2.0.0/src/agledger/resources/schemas.py +29 -0
  26. agledger-2.0.0/src/agledger/resources/verification.py +30 -0
  27. agledger-2.0.0/src/agledger/resources/webhooks.py +44 -0
  28. agledger-2.0.0/src/agledger/types.py +403 -0
  29. agledger-2.0.0/src/agledger/webhooks/__init__.py +7 -0
  30. agledger-2.0.0/src/agledger/webhooks/verify.py +95 -0
  31. agledger-2.0.0/tests/__init__.py +0 -0
  32. agledger-2.0.0/tests/test_client.py +244 -0
  33. agledger-2.0.0/tests/test_errors.py +115 -0
  34. agledger-2.0.0/tests/test_pagination.py +51 -0
  35. agledger-2.0.0/tests/test_retry.py +115 -0
  36. agledger-2.0.0/tests/test_webhooks.py +58 -0
agledger-2.0.0/LICENSE ADDED
@@ -0,0 +1,34 @@
1
+ Copyright (c) 2026 AGLedger LLC. All rights reserved.
2
+
3
+ PROPRIETARY SOFTWARE LICENSE
4
+
5
+ This software and associated documentation files (the "Software") are the
6
+ proprietary property of AGLedger LLC. The Software is provided for use
7
+ exclusively with the AGLedger API (https://api.agledger.ai).
8
+
9
+ Permission is hereby granted to use the Software solely for the purpose of
10
+ integrating with AGLedger services via the AGLedger API, subject to the
11
+ following conditions:
12
+
13
+ 1. You may not copy, modify, merge, publish, distribute, sublicense, or sell
14
+ copies of the Software, except as required to use it with the AGLedger API.
15
+
16
+ 2. You may not use the Software to create a competing product or service.
17
+
18
+ 3. You may not reverse engineer, decompile, or disassemble the Software,
19
+ except to the extent permitted by applicable law.
20
+
21
+ Use of this SDK is subject to the AGLedger Terms of Service at
22
+ https://agledger.ai/terms.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27
+ AGLEDGER LLC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
28
+ AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
+
31
+ ---
32
+
33
+ AGLedger™ and the Agentic Contract Specification™ are trademarks of
34
+ AGLedger LLC. Patent pending.
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.4
2
+ Name: agledger
3
+ Version: 2.0.0
4
+ Summary: AGLedger SDK — Accountability and audit infrastructure for agentic systems.
5
+ Author-email: AGLedger LLC <support@agledger.ai>
6
+ License-Expression: LicenseRef-Proprietary
7
+ License-File: LICENSE
8
+ Keywords: accountability,agents,agledger,audit,mandates
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.9
19
+ Requires-Dist: httpx<1,>=0.25.0
20
+ Requires-Dist: pydantic<3,>=2.0.0
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
23
+ Requires-Dist: pytest>=8.0; extra == 'dev'
24
+ Requires-Dist: respx>=0.22; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # AGLedger Python SDK
28
+
29
+ Accountability and audit infrastructure for agentic systems.
30
+
31
+ ```python
32
+ from agledger import AgledgerClient
33
+
34
+ client = AgledgerClient(api_key="ach_ent_...")
35
+ mandate = client.mandates.create(
36
+ enterpriseId="ent_123",
37
+ contractType="ACH-PROC-v1",
38
+ contractVersion="1",
39
+ platform="internal",
40
+ criteria={"item": "widgets", "maxQuantity": 100},
41
+ )
42
+ ```
43
+
44
+ See [agledger.ai](https://agledger.ai) for documentation.
@@ -0,0 +1,18 @@
1
+ # AGLedger Python SDK
2
+
3
+ Accountability and audit infrastructure for agentic systems.
4
+
5
+ ```python
6
+ from agledger import AgledgerClient
7
+
8
+ client = AgledgerClient(api_key="ach_ent_...")
9
+ mandate = client.mandates.create(
10
+ enterpriseId="ent_123",
11
+ contractType="ACH-PROC-v1",
12
+ contractVersion="1",
13
+ platform="internal",
14
+ criteria={"item": "widgets", "maxQuantity": 100},
15
+ )
16
+ ```
17
+
18
+ See [agledger.ai](https://agledger.ai) for documentation.
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "agledger"
7
+ version = "2.0.0"
8
+ description = "AGLedger SDK — Accountability and audit infrastructure for agentic systems."
9
+ readme = "README.md"
10
+ license = "LicenseRef-Proprietary"
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "AGLedger LLC", email = "support@agledger.ai" }]
13
+ keywords = ["agledger", "mandates", "accountability", "agents", "audit"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.9",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Typing :: Typed",
24
+ ]
25
+ dependencies = [
26
+ "httpx>=0.25.0,<1",
27
+ "pydantic>=2.0.0,<3",
28
+ ]
29
+
30
+ [project.optional-dependencies]
31
+ dev = [
32
+ "pytest>=8.0",
33
+ "pytest-asyncio>=0.24",
34
+ "respx>=0.22",
35
+ ]
36
+
37
+ [tool.hatch.build.targets.wheel]
38
+ packages = ["src/agledger"]
39
+
40
+ [tool.pytest.ini_options]
41
+ asyncio_mode = "auto"
42
+ testpaths = ["tests"]
43
+
44
+ [tool.pyright]
45
+ typeCheckingMode = "strict"
@@ -0,0 +1,85 @@
1
+ """
2
+ AGLedger SDK — Accountability and audit infrastructure for agentic systems.
3
+
4
+ Patent Pending. Copyright 2026 AGLedger LLC. All rights reserved.
5
+ """
6
+
7
+ from agledger._client import AgledgerClient, AsyncAgledgerClient
8
+ from agledger._errors import (
9
+ AgledgerError,
10
+ APIConnectionError,
11
+ APIError,
12
+ APITimeoutError,
13
+ AuthenticationError,
14
+ BadRequestError,
15
+ NotFoundError,
16
+ PermissionDeniedError,
17
+ RateLimitError,
18
+ UnprocessableError,
19
+ )
20
+ from agledger.types import (
21
+ AccountProfile,
22
+ AuditChain,
23
+ ContractType,
24
+ DashboardSummary,
25
+ Dispute,
26
+ DisputeStatus,
27
+ EnterpriseAgentRecord,
28
+ Event,
29
+ HealthResponse,
30
+ Mandate,
31
+ MandateStatus,
32
+ MandateTransitionAction,
33
+ OperatingMode,
34
+ Page,
35
+ Receipt,
36
+ ReceiptStatus,
37
+ RegisterResult,
38
+ ReputationScore,
39
+ VerificationMode,
40
+ VerificationOutcome,
41
+ VerificationResult,
42
+ Webhook,
43
+ WebhookEventType,
44
+ )
45
+
46
+ __version__ = "2.0.0"
47
+ __all__ = [
48
+ "AgledgerClient",
49
+ "AsyncAgledgerClient",
50
+ # Errors
51
+ "AgledgerError",
52
+ "APIError",
53
+ "AuthenticationError",
54
+ "PermissionDeniedError",
55
+ "NotFoundError",
56
+ "BadRequestError",
57
+ "UnprocessableError",
58
+ "RateLimitError",
59
+ "APIConnectionError",
60
+ "APITimeoutError",
61
+ # Types
62
+ "Mandate",
63
+ "MandateStatus",
64
+ "MandateTransitionAction",
65
+ "Receipt",
66
+ "ReceiptStatus",
67
+ "ContractType",
68
+ "OperatingMode",
69
+ "VerificationMode",
70
+ "VerificationOutcome",
71
+ "VerificationResult",
72
+ "Dispute",
73
+ "DisputeStatus",
74
+ "Webhook",
75
+ "WebhookEventType",
76
+ "ReputationScore",
77
+ "Event",
78
+ "AuditChain",
79
+ "DashboardSummary",
80
+ "AccountProfile",
81
+ "RegisterResult",
82
+ "EnterpriseAgentRecord",
83
+ "HealthResponse",
84
+ "Page",
85
+ ]
@@ -0,0 +1,163 @@
1
+ """
2
+ AGLedger SDK — Client with 18 resource sub-clients.
3
+ Supports context manager protocol for proper connection cleanup.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from types import TracebackType
9
+ from typing import Optional
10
+
11
+ import httpx
12
+
13
+ from agledger._http import (
14
+ AsyncHttpClient,
15
+ HttpClient,
16
+ DEFAULT_BASE_URL,
17
+ DEFAULT_MAX_RETRIES,
18
+ DEFAULT_TIMEOUT,
19
+ _resolve_api_key,
20
+ )
21
+ from agledger.resources.a2a import A2AResource, AsyncA2AResource
22
+ from agledger.resources.admin import AdminResource, AsyncAdminResource
23
+ from agledger.resources.capabilities import AsyncCapabilitiesResource, CapabilitiesResource
24
+ from agledger.resources.compliance import AsyncComplianceResource, ComplianceResource
25
+ from agledger.resources.dashboard import AsyncDashboardResource, DashboardResource
26
+ from agledger.resources.disputes import AsyncDisputesResource, DisputesResource
27
+ from agledger.resources.enterprises import AsyncEnterprisesResource, EnterprisesResource
28
+ from agledger.resources.events import AsyncEventsResource, EventsResource
29
+ from agledger.resources.health import AsyncHealthResource, HealthResource
30
+ from agledger.resources.mandates import AsyncMandatesResource, MandatesResource
31
+ from agledger.resources.notarize import AsyncNotarizeResource, NotarizeResource
32
+ from agledger.resources.receipts import AsyncReceiptsResource, ReceiptsResource
33
+ from agledger.resources.registration import AsyncRegistrationResource, RegistrationResource
34
+ from agledger.resources.reputation import AsyncReputationResource, ReputationResource
35
+ from agledger.resources.schemas import AsyncSchemasResource, SchemasResource
36
+ from agledger.resources.verification import AsyncVerificationResource, VerificationResource
37
+ from agledger.resources.webhooks import AsyncWebhooksResource, WebhooksResource
38
+
39
+
40
+ class AgledgerClient:
41
+ """
42
+ Synchronous AGLedger API client with 18 resource sub-clients.
43
+
44
+ Supports context manager for automatic connection cleanup::
45
+
46
+ with AgledgerClient(api_key="ach_ent_...") as client:
47
+ mandate = client.mandates.create(
48
+ enterprise_id="ent_123",
49
+ contract_type="ACH-PROC-v1",
50
+ contract_version="1",
51
+ platform="internal",
52
+ criteria={"item": "widgets"},
53
+ )
54
+
55
+ Or pass ``AGLEDGER_API_KEY`` env var::
56
+
57
+ client = AgledgerClient() # reads from env
58
+ """
59
+
60
+ def __init__(
61
+ self,
62
+ api_key: str | None = None,
63
+ *,
64
+ base_url: str = DEFAULT_BASE_URL,
65
+ max_retries: int = DEFAULT_MAX_RETRIES,
66
+ timeout: float = DEFAULT_TIMEOUT,
67
+ idempotency_key_prefix: str = "",
68
+ http_client: httpx.Client | None = None,
69
+ ) -> None:
70
+ resolved_key = _resolve_api_key(api_key)
71
+ self._http = HttpClient(
72
+ api_key=resolved_key,
73
+ base_url=base_url,
74
+ max_retries=max_retries,
75
+ timeout=timeout,
76
+ idempotency_key_prefix=idempotency_key_prefix,
77
+ http_client=http_client,
78
+ )
79
+ self.mandates = MandatesResource(self._http)
80
+ self.receipts = ReceiptsResource(self._http)
81
+ self.verification = VerificationResource(self._http)
82
+ self.disputes = DisputesResource(self._http)
83
+ self.webhooks = WebhooksResource(self._http)
84
+ self.reputation = ReputationResource(self._http)
85
+ self.events = EventsResource(self._http)
86
+ self.schemas = SchemasResource(self._http)
87
+ self.dashboard = DashboardResource(self._http)
88
+ self.compliance = ComplianceResource(self._http)
89
+ self.registration = RegistrationResource(self._http)
90
+ self.health = HealthResource(self._http)
91
+ self.admin = AdminResource(self._http)
92
+ self.a2a = A2AResource(self._http)
93
+ self.capabilities = CapabilitiesResource(self._http)
94
+ self.notarize = NotarizeResource(self._http)
95
+ self.enterprises = EnterprisesResource(self._http)
96
+
97
+ def close(self) -> None:
98
+ """Close the underlying HTTP connection pool."""
99
+ self._http.close()
100
+
101
+ def __enter__(self) -> AgledgerClient:
102
+ return self
103
+
104
+ def __exit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None) -> None:
105
+ self.close()
106
+
107
+
108
+ class AsyncAgledgerClient:
109
+ """
110
+ Async AGLedger API client with 18 resource sub-clients.
111
+
112
+ Supports async context manager::
113
+
114
+ async with AsyncAgledgerClient(api_key="ach_ent_...") as client:
115
+ mandate = await client.mandates.get("mnd-123")
116
+ """
117
+
118
+ def __init__(
119
+ self,
120
+ api_key: str | None = None,
121
+ *,
122
+ base_url: str = DEFAULT_BASE_URL,
123
+ max_retries: int = DEFAULT_MAX_RETRIES,
124
+ timeout: float = DEFAULT_TIMEOUT,
125
+ idempotency_key_prefix: str = "",
126
+ http_client: httpx.AsyncClient | None = None,
127
+ ) -> None:
128
+ resolved_key = _resolve_api_key(api_key)
129
+ self._http = AsyncHttpClient(
130
+ api_key=resolved_key,
131
+ base_url=base_url,
132
+ max_retries=max_retries,
133
+ timeout=timeout,
134
+ idempotency_key_prefix=idempotency_key_prefix,
135
+ http_client=http_client,
136
+ )
137
+ self.mandates = AsyncMandatesResource(self._http)
138
+ self.receipts = AsyncReceiptsResource(self._http)
139
+ self.verification = AsyncVerificationResource(self._http)
140
+ self.disputes = AsyncDisputesResource(self._http)
141
+ self.webhooks = AsyncWebhooksResource(self._http)
142
+ self.reputation = AsyncReputationResource(self._http)
143
+ self.events = AsyncEventsResource(self._http)
144
+ self.schemas = AsyncSchemasResource(self._http)
145
+ self.dashboard = AsyncDashboardResource(self._http)
146
+ self.compliance = AsyncComplianceResource(self._http)
147
+ self.registration = AsyncRegistrationResource(self._http)
148
+ self.health = AsyncHealthResource(self._http)
149
+ self.admin = AsyncAdminResource(self._http)
150
+ self.a2a = AsyncA2AResource(self._http)
151
+ self.capabilities = AsyncCapabilitiesResource(self._http)
152
+ self.notarize = AsyncNotarizeResource(self._http)
153
+ self.enterprises = AsyncEnterprisesResource(self._http)
154
+
155
+ async def close(self) -> None:
156
+ """Close the underlying HTTP connection pool."""
157
+ await self._http.close()
158
+
159
+ async def __aenter__(self) -> AsyncAgledgerClient:
160
+ return self
161
+
162
+ async def __aexit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None) -> None:
163
+ await self.close()
@@ -0,0 +1,132 @@
1
+ """
2
+ AGLedger SDK — Error classes.
3
+ Follows Anthropic/OpenAI naming conventions. Never shadows Python builtins.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, Optional
9
+
10
+
11
+ class AgledgerError(Exception):
12
+ """Base error for all SDK errors."""
13
+
14
+ pass
15
+
16
+
17
+ class APIError(AgledgerError):
18
+ """API returned an error response."""
19
+
20
+ status: int
21
+ code: str
22
+ request_id: Optional[str]
23
+ details: Optional[Any]
24
+ retryable: bool
25
+ doc_url: str
26
+
27
+ __slots__ = ("status", "code", "request_id", "details", "retryable", "doc_url")
28
+
29
+ def __init__(
30
+ self,
31
+ status: int,
32
+ *,
33
+ message: str = "",
34
+ code: str = "unknown",
35
+ request_id: Optional[str] = None,
36
+ details: Optional[Any] = None,
37
+ retryable: Optional[bool] = None,
38
+ ) -> None:
39
+ self.status = status
40
+ self.code = code
41
+ self.request_id = request_id
42
+ self.details = details
43
+ self.retryable = retryable if retryable is not None else (status == 429 or status >= 500)
44
+ self.doc_url = f"https://docs.agledger.ai/errors/{self.code}"
45
+ super().__init__(message or f"API error {status}")
46
+
47
+ def __repr__(self) -> str:
48
+ return f"{self.__class__.__name__}(status={self.status}, code={self.code!r}, message={str(self)!r})"
49
+
50
+ def is_retryable(self) -> bool:
51
+ """Whether this error can be retried (429, 5xx, network errors)."""
52
+ return self.retryable
53
+
54
+ def is_input_error(self) -> bool:
55
+ """Whether this is a 400 validation error — fix the request and retry."""
56
+ return self.status == 400
57
+
58
+ def is_state_error(self) -> bool:
59
+ """Whether this is a 422 state error — resource is in the wrong state."""
60
+ return self.status == 422
61
+
62
+ def is_auth_error(self) -> bool:
63
+ """Whether this is an auth error (401/403)."""
64
+ return self.status in (401, 403)
65
+
66
+
67
+ class AuthenticationError(APIError):
68
+ """401 — invalid or missing API key."""
69
+
70
+ def __init__(self, **kwargs: Any) -> None:
71
+ super().__init__(401, **kwargs)
72
+
73
+
74
+ class PermissionDeniedError(APIError):
75
+ """403 — insufficient scopes or permissions."""
76
+
77
+ missing_scopes: list[str]
78
+ key_scopes: Optional[list[str]]
79
+
80
+ def __init__(
81
+ self,
82
+ *,
83
+ missing_scopes: Optional[list[str]] = None,
84
+ key_scopes: Optional[list[str]] = None,
85
+ **kwargs: Any,
86
+ ) -> None:
87
+ self.missing_scopes = missing_scopes or []
88
+ self.key_scopes = key_scopes
89
+ super().__init__(403, **kwargs)
90
+
91
+
92
+ class NotFoundError(APIError):
93
+ """404 — resource not found."""
94
+
95
+ def __init__(self, **kwargs: Any) -> None:
96
+ super().__init__(404, **kwargs)
97
+
98
+
99
+ class BadRequestError(APIError):
100
+ """400 — request validation failed."""
101
+
102
+ def __init__(self, **kwargs: Any) -> None:
103
+ super().__init__(400, **kwargs)
104
+
105
+
106
+ class UnprocessableError(APIError):
107
+ """422 — resource in wrong state for the requested operation."""
108
+
109
+ def __init__(self, **kwargs: Any) -> None:
110
+ super().__init__(422, **kwargs)
111
+
112
+
113
+ class RateLimitError(APIError):
114
+ """429 — rate limit exceeded."""
115
+
116
+ retry_after: Optional[float]
117
+
118
+ def __init__(self, *, retry_after: Optional[float] = None, **kwargs: Any) -> None:
119
+ self.retry_after = retry_after
120
+ super().__init__(429, **kwargs)
121
+
122
+
123
+ class APIConnectionError(AgledgerError):
124
+ """Network connectivity error."""
125
+
126
+ pass
127
+
128
+
129
+ class APITimeoutError(APIConnectionError):
130
+ """Request timed out."""
131
+
132
+ pass