arche-sdk 0.1.0__py3-none-any.whl

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.
arche_sdk/__init__.py ADDED
@@ -0,0 +1,49 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Arche Python SDK public exports."""
4
+
5
+ from arche_sdk._version import __version__
6
+ from arche_sdk.client import ArcheClient
7
+ from arche_sdk.errors import (
8
+ APIError,
9
+ ArcheSDKError,
10
+ AuthenticationError,
11
+ BulkLicenseNotAcceptedError,
12
+ ChecksumMismatchError,
13
+ ConflictError,
14
+ ConnectionError,
15
+ NotFoundError,
16
+ PermissionDeniedError,
17
+ RateLimitError,
18
+ ResponseDecodeError,
19
+ ServerError,
20
+ TimeoutError,
21
+ TransportError,
22
+ ValidationError,
23
+ )
24
+ from arche_sdk.models.bulk import SyncProgress, SyncResult
25
+ from arche_sdk.pagination import Page
26
+ from arche_sdk.request_options import RequestOptions
27
+
28
+ __all__ = [
29
+ "APIError",
30
+ "ArcheClient",
31
+ "ArcheSDKError",
32
+ "AuthenticationError",
33
+ "BulkLicenseNotAcceptedError",
34
+ "ChecksumMismatchError",
35
+ "ConflictError",
36
+ "ConnectionError",
37
+ "NotFoundError",
38
+ "Page",
39
+ "PermissionDeniedError",
40
+ "RateLimitError",
41
+ "RequestOptions",
42
+ "ResponseDecodeError",
43
+ "ServerError",
44
+ "SyncProgress",
45
+ "SyncResult",
46
+ "TimeoutError",
47
+ "TransportError",
48
+ "ValidationError",
49
+ ]
arche_sdk/_version.py ADDED
@@ -0,0 +1,5 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """The SDK's release version, read by the build and the publish workflow."""
4
+
5
+ __version__ = "0.1.0"
arche_sdk/auth.py ADDED
@@ -0,0 +1,26 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Authentication header utilities for Arche SDK."""
4
+
5
+ from __future__ import annotations
6
+
7
+ from arche_sdk.config import SDKConfig
8
+
9
+
10
+ class AuthHeaderProvider:
11
+ """Build auth headers for outgoing requests."""
12
+
13
+ def __init__(self, config: SDKConfig) -> None:
14
+ self._config = config
15
+
16
+ def headers(self) -> dict[str, str]:
17
+ """Return authentication headers.
18
+
19
+ Returns:
20
+ A dictionary containing either `X-Api-Key`, `Authorization`, or empty.
21
+ """
22
+ if self._config.api_key:
23
+ return {"X-Api-Key": self._config.api_key}
24
+ if self._config.bearer_token:
25
+ return {"Authorization": f"Bearer {self._config.bearer_token}"}
26
+ return {}
arche_sdk/client.py ADDED
@@ -0,0 +1,63 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Root client for Arche Python SDK."""
4
+
5
+ from __future__ import annotations
6
+
7
+ import httpx
8
+
9
+ from arche_sdk.config import SDKConfig
10
+ from arche_sdk.resources.bulk import BulkClient
11
+ from arche_sdk.resources.companies import CompaniesClient
12
+ from arche_sdk.resources.filings import FilingsClient
13
+ from arche_sdk.resources.narratives import NarrativesClient
14
+ from arche_sdk.resources.statements import StatementsClient
15
+ from arche_sdk.transport import HTTPTransport
16
+
17
+
18
+ class ArcheClient:
19
+ """Synchronous Arche API client.
20
+
21
+ Args:
22
+ api_key: Optional API key for `X-Api-Key` authentication.
23
+ bearer_token: Optional bearer token for `Authorization` authentication.
24
+ base_url: Base API URL.
25
+ timeout_seconds: Default request timeout in seconds.
26
+ user_agent: Optional custom user-agent header.
27
+ http_client: Optional preconfigured `httpx.Client`.
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ *,
33
+ api_key: str | None = None,
34
+ bearer_token: str | None = None,
35
+ base_url: str = "https://api.arche.fi",
36
+ timeout_seconds: float = 30.0,
37
+ user_agent: str | None = None,
38
+ http_client: httpx.Client | None = None,
39
+ ) -> None:
40
+ self._config = SDKConfig(
41
+ api_key=api_key,
42
+ bearer_token=bearer_token,
43
+ base_url=base_url,
44
+ timeout_seconds=timeout_seconds,
45
+ user_agent=user_agent,
46
+ )
47
+ self._transport = HTTPTransport(self._config, http_client=http_client)
48
+
49
+ self.companies = CompaniesClient(self._transport)
50
+ self.filings = FilingsClient(self._transport)
51
+ self.statements = StatementsClient(self._transport)
52
+ self.narratives = NarrativesClient(self._transport)
53
+ self.bulk = BulkClient(self._transport)
54
+
55
+ def close(self) -> None:
56
+ """Close underlying HTTP transport resources."""
57
+ self._transport.close()
58
+
59
+ def __enter__(self) -> ArcheClient:
60
+ return self
61
+
62
+ def __exit__(self, exc_type: object, exc: object, tb: object) -> None:
63
+ self.close()
arche_sdk/config.py ADDED
@@ -0,0 +1,37 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """SDK configuration objects for Arche Python SDK."""
4
+
5
+ from __future__ import annotations
6
+
7
+ from dataclasses import dataclass
8
+
9
+ DEFAULT_BASE_URL = "https://api.arche.fi"
10
+ DEFAULT_TIMEOUT_SECONDS = 30.0
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class SDKConfig:
15
+ """Immutable SDK configuration.
16
+
17
+ Args:
18
+ api_key: API key for `X-Api-Key` authentication.
19
+ bearer_token: Bearer token for `Authorization` authentication.
20
+ base_url: API base URL.
21
+ timeout_seconds: Default request timeout in seconds.
22
+ user_agent: Optional user-agent string override.
23
+ """
24
+
25
+ api_key: str | None = None
26
+ bearer_token: str | None = None
27
+ base_url: str = DEFAULT_BASE_URL
28
+ timeout_seconds: float = DEFAULT_TIMEOUT_SECONDS
29
+ user_agent: str | None = None
30
+
31
+ def __post_init__(self) -> None:
32
+ if self.api_key and self.bearer_token:
33
+ raise ValueError("Provide either api_key or bearer_token, not both.")
34
+ if self.timeout_seconds <= 0:
35
+ raise ValueError("timeout_seconds must be > 0")
36
+ if not self.base_url:
37
+ raise ValueError("base_url must be non-empty")
arche_sdk/envelopes.py ADDED
@@ -0,0 +1,50 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Public envelope models used by Arche API."""
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Generic, TypeVar
8
+
9
+ from pydantic import BaseModel, ConfigDict
10
+
11
+ T = TypeVar("T")
12
+
13
+
14
+ class ErrorObject(BaseModel):
15
+ """Canonical API error object."""
16
+
17
+ model_config = ConfigDict(extra="allow")
18
+
19
+ code: str
20
+ http_status: int
21
+ message: str
22
+ details: dict[str, object] | None = None
23
+ trace_id: str | None = None
24
+
25
+
26
+ class ErrorEnvelope(BaseModel):
27
+ """Canonical API error envelope."""
28
+
29
+ model_config = ConfigDict(extra="allow")
30
+
31
+ error: ErrorObject
32
+
33
+
34
+ class SuccessEnvelope(BaseModel, Generic[T]):
35
+ """Canonical success envelope."""
36
+
37
+ model_config = ConfigDict(extra="allow")
38
+
39
+ data: T
40
+
41
+
42
+ class PaginatedEnvelope(BaseModel, Generic[T]):
43
+ """Canonical paginated envelope."""
44
+
45
+ model_config = ConfigDict(extra="allow")
46
+
47
+ page: int
48
+ page_size: int
49
+ total: int
50
+ items: list[T]
arche_sdk/errors.py ADDED
@@ -0,0 +1,148 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Arche SDK exception hierarchy and API error types."""
4
+
5
+ from __future__ import annotations
6
+
7
+
8
+ class ArcheSDKError(Exception):
9
+ """Base exception for all SDK errors."""
10
+
11
+
12
+ class TransportError(ArcheSDKError):
13
+ """Transport-level error while making a request."""
14
+
15
+
16
+ class TimeoutError(TransportError):
17
+ """Request timed out."""
18
+
19
+
20
+ class ConnectionError(TransportError):
21
+ """Failed to connect to API."""
22
+
23
+
24
+ class ResponseDecodeError(ArcheSDKError):
25
+ """Response body could not be decoded."""
26
+
27
+
28
+ class ChecksumMismatchError(ArcheSDKError):
29
+ """A downloaded file's SHA-256 differs from the checksum the manifest records.
30
+
31
+ The file is removed rather than left in place: a partially written or
32
+ corrupted Parquet file that looks complete is worse than an absent one,
33
+ because the next sync would skip it.
34
+ """
35
+
36
+ def __init__(self, *, path: str, expected: str, actual: str) -> None:
37
+ self.path = path
38
+ self.expected = expected
39
+ self.actual = actual
40
+ super().__init__(f"{path}: expected sha256 {expected}, downloaded {actual}")
41
+
42
+
43
+ class APIError(ArcheSDKError):
44
+ """Base API error returned by server."""
45
+
46
+ def __init__(
47
+ self,
48
+ *,
49
+ status_code: int,
50
+ code: str,
51
+ message: str,
52
+ details: dict[str, object] | None,
53
+ trace_id: str | None,
54
+ request_id: str | None,
55
+ ) -> None:
56
+ self.status_code = status_code
57
+ self.code = code
58
+ self.message = message
59
+ self.details = details or {}
60
+ self.trace_id = trace_id
61
+ self.request_id = request_id
62
+ super().__init__(f"{status_code} {code}: {message}")
63
+
64
+
65
+ class ValidationError(APIError):
66
+ """Input validation error."""
67
+
68
+
69
+ class AuthenticationError(APIError):
70
+ """Authentication failed."""
71
+
72
+
73
+ class PermissionDeniedError(APIError):
74
+ """Permission denied."""
75
+
76
+
77
+ class BulkLicenseNotAcceptedError(PermissionDeniedError):
78
+ """The organization has not accepted the current bulk-data license.
79
+
80
+ Download URLs are issued only once it has. Read the license with
81
+ ``client.bulk.license()`` and accept it with
82
+ ``client.bulk.accept_license(name=..., email=...)``.
83
+ """
84
+
85
+ def __init__(
86
+ self,
87
+ *,
88
+ status_code: int,
89
+ code: str,
90
+ message: str,
91
+ details: dict[str, object] | None,
92
+ trace_id: str | None,
93
+ request_id: str | None,
94
+ ) -> None:
95
+ super().__init__(
96
+ status_code=status_code,
97
+ code=code,
98
+ message=(
99
+ f"{message} With this SDK, read it with client.bulk.license() and "
100
+ "accept it with client.bulk.accept_license(name=..., email=...)."
101
+ ),
102
+ details=details,
103
+ trace_id=trace_id,
104
+ request_id=request_id,
105
+ )
106
+
107
+
108
+ class NotFoundError(APIError):
109
+ """Resource not found."""
110
+
111
+
112
+ class ConflictError(APIError):
113
+ """Conflict error."""
114
+
115
+
116
+ class RateLimitError(APIError):
117
+ """Rate limit exceeded."""
118
+
119
+ def __init__(
120
+ self,
121
+ *,
122
+ status_code: int,
123
+ code: str,
124
+ message: str,
125
+ details: dict[str, object] | None,
126
+ trace_id: str | None,
127
+ request_id: str | None,
128
+ retry_after: str | None,
129
+ rate_limit_limit: str | None,
130
+ rate_limit_remaining: str | None,
131
+ rate_limit_reset: str | None,
132
+ ) -> None:
133
+ super().__init__(
134
+ status_code=status_code,
135
+ code=code,
136
+ message=message,
137
+ details=details,
138
+ trace_id=trace_id,
139
+ request_id=request_id,
140
+ )
141
+ self.retry_after = retry_after
142
+ self.rate_limit_limit = rate_limit_limit
143
+ self.rate_limit_remaining = rate_limit_remaining
144
+ self.rate_limit_reset = rate_limit_reset
145
+
146
+
147
+ class ServerError(APIError):
148
+ """Server-side error (5xx)."""
@@ -0,0 +1,109 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Public model exports for Arche SDK."""
4
+
5
+ from arche_sdk.models.ai import Narrative, NarrativeCitation
6
+ from arche_sdk.models.bulk import (
7
+ BulkColumn,
8
+ BulkDataset,
9
+ BulkDatasetTotals,
10
+ BulkDownloadUrl,
11
+ BulkFile,
12
+ BulkLicense,
13
+ BulkLicenseAcceptance,
14
+ BulkLicenseAcceptanceRecord,
15
+ BulkSnapshot,
16
+ BulkSnapshotManifest,
17
+ SyncProgress,
18
+ SyncResult,
19
+ )
20
+ from arche_sdk.models.companies import (
21
+ EdgarCompanyCompleteness,
22
+ EdgarCompanyProfile,
23
+ EdgarCompanyProfileSource,
24
+ EdgarCompanyResolve,
25
+ )
26
+ from arche_sdk.models.edgar import (
27
+ EdgarDerivedMetricsCatalog,
28
+ EdgarDerivedMetricSpec,
29
+ EdgarDerivedMetricsPoint,
30
+ EdgarDerivedMetricsTimeSeries,
31
+ EdgarFiling,
32
+ EdgarStatementVersion,
33
+ EdgarStatementList,
34
+ MetricOverrideAudit,
35
+ NormalizedFact,
36
+ StatementUsd,
37
+ UsdValue,
38
+ NormalizedStatement,
39
+ RestatementDelta,
40
+ RestatementDeltaVersion,
41
+ RestatementLedger,
42
+ RestatementLedgerEntry,
43
+ RestatementMetricDelta,
44
+ RestatementMetricTimeline,
45
+ RestatementSummary,
46
+ StatementMetricAuditChain,
47
+ StatementQuality,
48
+ )
49
+ from arche_sdk.models.reconciliation import ReconciliationResult, ReconciliationSummaryBucket
50
+ from arche_sdk.models.statements import (
51
+ DQAnomaly,
52
+ EdgarFinancialsAsOf,
53
+ EdgarFinancialsAsOfPage,
54
+ FactQuality,
55
+ OverrideRuleApplication,
56
+ StatementDQOverlay,
57
+ StatementOverrideTrace,
58
+ )
59
+
60
+ __all__ = [
61
+ "BulkColumn",
62
+ "BulkDataset",
63
+ "BulkDatasetTotals",
64
+ "BulkDownloadUrl",
65
+ "BulkFile",
66
+ "BulkLicense",
67
+ "BulkLicenseAcceptance",
68
+ "BulkLicenseAcceptanceRecord",
69
+ "BulkSnapshot",
70
+ "BulkSnapshotManifest",
71
+ "DQAnomaly",
72
+ "EdgarCompanyCompleteness",
73
+ "EdgarCompanyProfile",
74
+ "EdgarCompanyProfileSource",
75
+ "EdgarCompanyResolve",
76
+ "EdgarDerivedMetricSpec",
77
+ "EdgarDerivedMetricsCatalog",
78
+ "EdgarDerivedMetricsPoint",
79
+ "EdgarDerivedMetricsTimeSeries",
80
+ "EdgarFinancialsAsOf",
81
+ "EdgarFinancialsAsOfPage",
82
+ "EdgarFiling",
83
+ "EdgarStatementVersion",
84
+ "EdgarStatementList",
85
+ "FactQuality",
86
+ "MetricOverrideAudit",
87
+ "Narrative",
88
+ "NarrativeCitation",
89
+ "NormalizedFact",
90
+ "StatementUsd",
91
+ "UsdValue",
92
+ "NormalizedStatement",
93
+ "OverrideRuleApplication",
94
+ "ReconciliationResult",
95
+ "ReconciliationSummaryBucket",
96
+ "RestatementDelta",
97
+ "RestatementDeltaVersion",
98
+ "RestatementLedger",
99
+ "RestatementLedgerEntry",
100
+ "RestatementMetricDelta",
101
+ "RestatementMetricTimeline",
102
+ "RestatementSummary",
103
+ "StatementDQOverlay",
104
+ "StatementMetricAuditChain",
105
+ "StatementOverrideTrace",
106
+ "StatementQuality",
107
+ "SyncProgress",
108
+ "SyncResult",
109
+ ]
arche_sdk/models/ai.py ADDED
@@ -0,0 +1,32 @@
1
+ # Copyright (c) 2026 Protos Systems LLC.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Typed AI models for narratives endpoints."""
4
+
5
+ from __future__ import annotations
6
+
7
+ from datetime import datetime
8
+
9
+ from pydantic import BaseModel, ConfigDict
10
+
11
+
12
+ class NarrativeCitation(BaseModel):
13
+ model_config = ConfigDict(extra="allow")
14
+
15
+ metric_code: str
16
+ period: str
17
+ value: str
18
+ comparison: str | None = None
19
+
20
+
21
+ class Narrative(BaseModel):
22
+ model_config = ConfigDict(extra="allow")
23
+
24
+ company_id: str
25
+ cik: str
26
+ as_of_timestamp: datetime
27
+ narrative_type: str
28
+ window_label: str
29
+ input_hash: str
30
+ narrative_text: str
31
+ citations: list[NarrativeCitation]
32
+ created_at: datetime