financial-data-protocol 0.3.0a3__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.
Files changed (52) hide show
  1. financial_data_protocol/__init__.py +187 -0
  2. financial_data_protocol/__main__.py +3 -0
  3. financial_data_protocol/cli/__init__.py +186 -0
  4. financial_data_protocol/cli/__main__.py +3 -0
  5. financial_data_protocol/client/__init__.py +25 -0
  6. financial_data_protocol/client/client.py +349 -0
  7. financial_data_protocol/client/httpclient.py +478 -0
  8. financial_data_protocol/client/interfaces.py +149 -0
  9. financial_data_protocol/client/protocol_client.py +320 -0
  10. financial_data_protocol/client/test_client.py +201 -0
  11. financial_data_protocol/constants.py +5 -0
  12. financial_data_protocol/models.py +352 -0
  13. financial_data_protocol/protocol.py +64 -0
  14. financial_data_protocol/py.typed +1 -0
  15. financial_data_protocol/server/__init__.py +12 -0
  16. financial_data_protocol/server/api.py +707 -0
  17. financial_data_protocol/server/app.py +85 -0
  18. financial_data_protocol/server/authority.py +322 -0
  19. financial_data_protocol/server/config.py +162 -0
  20. financial_data_protocol/server/db/__init__.py +1 -0
  21. financial_data_protocol/server/db/mongo/__init__.py +5 -0
  22. financial_data_protocol/server/db/mongo/schema.py +384 -0
  23. financial_data_protocol/server/db/postgres/__init__.py +1 -0
  24. financial_data_protocol/server/db/postgres/migrations/001_initial.sql +164 -0
  25. financial_data_protocol/server/db/postgres/migrations/002_lineage_receipts.sql +9 -0
  26. financial_data_protocol/server/db/postgres/migrations/003_material_handoffs.sql +43 -0
  27. financial_data_protocol/server/db/postgres/migrations/004_disclosures.sql +9 -0
  28. financial_data_protocol/server/db/postgres/migrations/005_domain_authority.sql +9 -0
  29. financial_data_protocol/server/db/postgres/migrations/006_content_blobs.sql +16 -0
  30. financial_data_protocol/server/db/postgres/migrations/__init__.py +1 -0
  31. financial_data_protocol/server/errors.py +51 -0
  32. financial_data_protocol/server/http.py +857 -0
  33. financial_data_protocol/server/logging.py +61 -0
  34. financial_data_protocol/server/object_storage/__init__.py +16 -0
  35. financial_data_protocol/server/object_storage/content_store.py +258 -0
  36. financial_data_protocol/server/object_storage/in_memory_content.py +44 -0
  37. financial_data_protocol/server/object_storage/interfaces.py +28 -0
  38. financial_data_protocol/server/registries/__init__.py +39 -0
  39. financial_data_protocol/server/registries/in_memory_registry.py +768 -0
  40. financial_data_protocol/server/registries/interfaces.py +295 -0
  41. financial_data_protocol/server/registries/mongo_registry.py +1642 -0
  42. financial_data_protocol/server/registries/postgres_registry.py +1875 -0
  43. financial_data_protocol/server/schema.py +73 -0
  44. financial_data_protocol/server/services/__init__.py +37 -0
  45. financial_data_protocol/server/services/artifact_service.py +105 -0
  46. financial_data_protocol/server/services/central_service.py +751 -0
  47. financial_data_protocol/server/services/content_service.py +549 -0
  48. financial_data_protocol-0.3.0a3.dist-info/METADATA +203 -0
  49. financial_data_protocol-0.3.0a3.dist-info/RECORD +52 -0
  50. financial_data_protocol-0.3.0a3.dist-info/WHEEL +5 -0
  51. financial_data_protocol-0.3.0a3.dist-info/entry_points.txt +2 -0
  52. financial_data_protocol-0.3.0a3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,187 @@
1
+ """Financial Data Protocol public package."""
2
+
3
+ from .client import FdpClient, FdpConfig
4
+ from .client.protocol_client import CentralClient, CentralClientError
5
+ from .constants import API_SCHEMA_VERSION, CENTRAL_SCHEMA_REVISION, CENTRAL_SCHEMA_VERSION
6
+ from .models import (
7
+ Artifact,
8
+ Content,
9
+ DeclarationProvenance,
10
+ DisclosurePackageRevision,
11
+ DisclosureReceipt,
12
+ DisclosureRevocation,
13
+ EvidenceReference,
14
+ LineageDeclaration,
15
+ LineageRelationType,
16
+ MaterialTransfer,
17
+ Package,
18
+ PackageMember,
19
+ PackageRevision,
20
+ RegistrySpace,
21
+ SpaceAccess,
22
+ UsageReceipt,
23
+ WriteConflict,
24
+ WriteCreated,
25
+ WriteIdempotent,
26
+ WriteResult,
27
+ )
28
+ from .server.api import (
29
+ ApiFailure,
30
+ ApiRequest,
31
+ ApiResponse,
32
+ ApiSuccess,
33
+ CentralTransport,
34
+ InProcessCentralTransport,
35
+ StaticMachineTokenAuthenticator,
36
+ StaticMachineTokenBinding,
37
+ )
38
+ from .server.authority import (
39
+ AuthorityCutoverRecord,
40
+ AuthorityRollbackPointRecord,
41
+ AuthorityRollbackRecord,
42
+ DomainAuthorityGate,
43
+ DomainAuthorityReadback,
44
+ DomainAuthorityState,
45
+ ShadowComparison,
46
+ )
47
+ from .server.config import CentralSettings
48
+ from .server.db.mongo.schema import CENTRAL_MONGO_SCHEMA_REVISION
49
+ from .server.errors import (
50
+ AuthorizationError,
51
+ ContentIntegrityError,
52
+ NotFoundError,
53
+ OperationStateError,
54
+ ServiceError,
55
+ )
56
+ from .server.http import CentralHttpApp, HttpCentralTransport, create_app
57
+ from .server.object_storage import (
58
+ AlibabaCloudOssObjectStore,
59
+ InMemoryObjectStore,
60
+ ObjectStore,
61
+ S3ObjectStore,
62
+ StreamingObjectStore,
63
+ )
64
+ from .server.registries import (
65
+ CentralOperationState,
66
+ CleanupUploadRequest,
67
+ FinalizedUpload,
68
+ FinalizeUploadRequest,
69
+ IdempotencyRecord,
70
+ InMemoryRegistryCustody,
71
+ RegistryCustody,
72
+ StagedUpload,
73
+ StageUploadRequest,
74
+ )
75
+ from .server.registries.mongo_registry import CentralMongoRegistry
76
+ from .server.registries.postgres_registry import (
77
+ CENTRAL_POSTGRES_SCHEMA_REVISION,
78
+ CentralPostgresRegistry,
79
+ )
80
+ from .server.schema import export_all_json_schemas, export_json_schema, schema_names
81
+ from .server.services import (
82
+ ArtifactService,
83
+ BackupRestoreReadiness,
84
+ CentralAccessContext,
85
+ CentralService,
86
+ ContextSpaceAuthorizer,
87
+ RecoveryContentCheck,
88
+ RecoveryRecordCheck,
89
+ RecoveryRecordState,
90
+ RecoveryReport,
91
+ SpaceAuthorizer,
92
+ )
93
+ from .server.services.content_service import (
94
+ ContentVerificationState,
95
+ FinalizedContentInspection,
96
+ OrphanedObject,
97
+ )
98
+
99
+ __all__ = [
100
+ "API_SCHEMA_VERSION",
101
+ "CENTRAL_MONGO_SCHEMA_REVISION",
102
+ "CENTRAL_POSTGRES_SCHEMA_REVISION",
103
+ "CENTRAL_SCHEMA_REVISION",
104
+ "CENTRAL_SCHEMA_VERSION",
105
+ "AlibabaCloudOssObjectStore",
106
+ "ApiFailure",
107
+ "ApiRequest",
108
+ "ApiResponse",
109
+ "ApiSuccess",
110
+ "Artifact",
111
+ "ArtifactService",
112
+ "AuthorityCutoverRecord",
113
+ "AuthorityRollbackPointRecord",
114
+ "AuthorityRollbackRecord",
115
+ "AuthorizationError",
116
+ "BackupRestoreReadiness",
117
+ "CentralAccessContext",
118
+ "CentralClient",
119
+ "CentralClientError",
120
+ "CentralHttpApp",
121
+ "CentralMongoRegistry",
122
+ "CentralOperationState",
123
+ "CentralPostgresRegistry",
124
+ "CentralService",
125
+ "CentralSettings",
126
+ "CentralTransport",
127
+ "CleanupUploadRequest",
128
+ "Content",
129
+ "ContentIntegrityError",
130
+ "ContentVerificationState",
131
+ "ContextSpaceAuthorizer",
132
+ "DeclarationProvenance",
133
+ "DisclosurePackageRevision",
134
+ "DisclosureReceipt",
135
+ "DisclosureRevocation",
136
+ "DomainAuthorityGate",
137
+ "DomainAuthorityReadback",
138
+ "DomainAuthorityState",
139
+ "EvidenceReference",
140
+ "FdpClient",
141
+ "FdpConfig",
142
+ "FinalizeUploadRequest",
143
+ "FinalizedContentInspection",
144
+ "FinalizedUpload",
145
+ "HttpCentralTransport",
146
+ "IdempotencyRecord",
147
+ "InMemoryObjectStore",
148
+ "InMemoryRegistryCustody",
149
+ "InProcessCentralTransport",
150
+ "LineageDeclaration",
151
+ "LineageRelationType",
152
+ "MaterialTransfer",
153
+ "NotFoundError",
154
+ "ObjectStore",
155
+ "OperationStateError",
156
+ "OrphanedObject",
157
+ "Package",
158
+ "PackageMember",
159
+ "PackageRevision",
160
+ "RecoveryContentCheck",
161
+ "RecoveryRecordCheck",
162
+ "RecoveryRecordState",
163
+ "RecoveryReport",
164
+ "RegistryCustody",
165
+ "RegistrySpace",
166
+ "S3ObjectStore",
167
+ "ServiceError",
168
+ "ShadowComparison",
169
+ "SpaceAccess",
170
+ "SpaceAuthorizer",
171
+ "StageUploadRequest",
172
+ "StagedUpload",
173
+ "StaticMachineTokenAuthenticator",
174
+ "StaticMachineTokenBinding",
175
+ "StreamingObjectStore",
176
+ "UsageReceipt",
177
+ "WriteConflict",
178
+ "WriteCreated",
179
+ "WriteIdempotent",
180
+ "WriteResult",
181
+ "create_app",
182
+ "export_all_json_schemas",
183
+ "export_json_schema",
184
+ "schema_names",
185
+ ]
186
+
187
+ __version__ = "0.3.0a2"
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,186 @@
1
+ """Explicit, configuration-authenticated Central custody reconciliation CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+ from collections.abc import Sequence
9
+ from typing import Any, Never
10
+ from urllib.error import HTTPError, URLError
11
+ from urllib.parse import urlencode
12
+ from urllib.request import Request, urlopen
13
+
14
+ from ..server.app import load_server_settings
15
+ from ..server.config import OperatorSettings
16
+ from ..server.errors import FDPError
17
+ from ..server.http import HttpCentralTransport
18
+ from ..server.registries.mongo_registry import CentralMongoRegistry
19
+
20
+ EXIT_OK = 0
21
+ EXIT_USAGE = 2
22
+ EXIT_OPERATIONAL_ERROR = 4
23
+
24
+
25
+ def _emit(payload: Any, *, stream: Any = sys.stdout) -> None:
26
+ print(json.dumps(payload, ensure_ascii=False, sort_keys=True), file=stream)
27
+
28
+
29
+ class _Parser(argparse.ArgumentParser):
30
+ def error(self, message: str) -> Never:
31
+ _emit({"ok": False, "error": "invalid_arguments", "message": message}, stream=sys.stderr)
32
+ raise SystemExit(EXIT_USAGE)
33
+
34
+
35
+ def _parser() -> _Parser:
36
+ parser = _Parser(prog="fdp-central", description="FDP Central operator commands")
37
+ commands = parser.add_subparsers(dest="command", required=True)
38
+ sweep = commands.add_parser(
39
+ "blob-sweep",
40
+ help="reconcile final Blob objects for a month, for example --month 2026-08",
41
+ )
42
+ sweep.add_argument("--registry-space-id", required=True)
43
+ sweep.add_argument("--caller-id", required=True)
44
+ sweep.add_argument(
45
+ "--month",
46
+ required=True,
47
+ help="UTC Blob creation month in YYYY-MM format, for example 2026-08",
48
+ )
49
+ sweep.add_argument("--max-keys", type=int, default=1000)
50
+ sweep.add_argument("--apply", action="store_true")
51
+ commands.add_parser(
52
+ "init-db", help="initialize the configured Central MongoDB registry (empty database only)"
53
+ )
54
+ commands.add_parser("serve", help="run the configured Central HTTP service")
55
+ return parser
56
+
57
+
58
+ def _transport(caller_id: str) -> HttpCentralTransport:
59
+ """Read operator transport settings from the shared YAML configuration."""
60
+ configured = OperatorSettings.from_file()
61
+ if caller_id != configured.caller_id:
62
+ raise ValueError("Caller ID does not match the configured operator identity")
63
+ return HttpCentralTransport(configured.http_url, configured.machine_token, caller_id)
64
+
65
+
66
+ def _send(
67
+ transport: HttpCentralTransport,
68
+ *,
69
+ caller_id: str,
70
+ space: str,
71
+ operation: str,
72
+ payload: dict[str, Any],
73
+ key: str | None = None,
74
+ ) -> dict[str, Any]:
75
+ if operation == "list_orphaned_objects":
76
+ url = transport.base_url + "/v1/content/orphaned-objects?" + urlencode(payload)
77
+ method, body = "GET", None
78
+ elif operation == "remove_orphaned_object":
79
+ url = transport.base_url + "/v1/content/orphaned-objects:remove"
80
+ method, body = "POST", json.dumps(payload).encode()
81
+ elif operation == "cleanup_upload":
82
+ operation_id = str(payload["operation_id"])
83
+ url = transport.base_url + f"/v1/content/stages/{operation_id}:cleanup"
84
+ method, body = "POST", b""
85
+ else: # pragma: no cover - closed command surface
86
+ raise ValueError("unsupported custody-sweep operation")
87
+ headers = {
88
+ "Authorization": "Bearer " + transport.machine_token,
89
+ "FDP-Caller-Id": caller_id,
90
+ "FDP-Registry-Space-Id": space,
91
+ }
92
+ if body is not None:
93
+ headers["Content-Type"] = "application/json"
94
+ if key is not None:
95
+ headers["Idempotency-Key"] = key
96
+ try:
97
+ with urlopen(
98
+ Request(url, data=body, headers=headers, method=method), timeout=transport.timeout
99
+ ) as raw:
100
+ response = json.loads(raw.read())
101
+ except HTTPError as exc:
102
+ response = json.loads(exc.read())
103
+ except URLError as exc:
104
+ raise RuntimeError("Central HTTP transport is unavailable") from exc
105
+ if response.get("result") != "success":
106
+ raise RuntimeError(str(response.get("code", "unknown_error")))
107
+ return dict(response["data"])
108
+
109
+
110
+ def main(argv: Sequence[str] | None = None) -> int:
111
+ args = _parser().parse_args(argv)
112
+ if args.command == "serve":
113
+ try:
114
+ from ..server.app import main as start_server
115
+
116
+ return start_server()
117
+ except (FDPError, OSError, RuntimeError, ValueError) as exc:
118
+ _emit(
119
+ {
120
+ "ok": False,
121
+ "error": getattr(exc, "code", "operational_error"),
122
+ "message": str(exc),
123
+ },
124
+ stream=sys.stderr,
125
+ )
126
+ return EXIT_OPERATIONAL_ERROR
127
+ if args.command == "init-db":
128
+ try:
129
+ settings = load_server_settings()
130
+ registry = CentralMongoRegistry(settings.database_url or "")
131
+ try:
132
+ _emit({"ok": True, "central_schema_revision": registry.migrate()})
133
+ finally:
134
+ registry.close()
135
+ return EXIT_OK
136
+ except (FDPError, OSError, RuntimeError, ValueError) as exc:
137
+ _emit(
138
+ {"ok": False, "error": "operational_error", "message": str(exc)},
139
+ stream=sys.stderr,
140
+ )
141
+ return EXIT_OPERATIONAL_ERROR
142
+ if not 1 <= args.max_keys <= 1000:
143
+ _emit(
144
+ {"ok": False, "error": "invalid_arguments", "message": "--max-keys is 1..1000"},
145
+ stream=sys.stderr,
146
+ )
147
+ return EXIT_USAGE
148
+ try:
149
+ transport = _transport(args.caller_id)
150
+ listed = _send(
151
+ transport,
152
+ caller_id=args.caller_id,
153
+ space=args.registry_space_id,
154
+ operation="list_orphaned_objects",
155
+ payload={"month": args.month, "max_keys": args.max_keys},
156
+ )
157
+ objects = [str(item["object_key"]) for item in listed["objects"]]
158
+ report: dict[str, Any] = {
159
+ "ok": True,
160
+ "mode": "apply" if args.apply else "dry_run",
161
+ "orphaned_objects": objects,
162
+ }
163
+ if args.apply:
164
+ removals: list[dict[str, Any]] = []
165
+ for index, object_key in enumerate(objects):
166
+ key = f"custody-sweep-remove-{index}-{object_key}"
167
+ result = _send(
168
+ transport,
169
+ caller_id=args.caller_id,
170
+ space=args.registry_space_id,
171
+ operation="remove_orphaned_object",
172
+ payload={"object_key": object_key},
173
+ key=key,
174
+ )
175
+ removals.append(
176
+ {
177
+ "object_key": object_key,
178
+ "removed": result["removed"],
179
+ }
180
+ )
181
+ report["removals"] = removals
182
+ _emit(report)
183
+ return EXIT_OK
184
+ except (OSError, RuntimeError, ValueError) as exc:
185
+ _emit({"ok": False, "error": "operational_error", "message": str(exc)}, stream=sys.stderr)
186
+ return EXIT_OPERATIONAL_ERROR
@@ -0,0 +1,3 @@
1
+ from . import main
2
+
3
+ raise SystemExit(main())
@@ -0,0 +1,25 @@
1
+ """Reusable clients for Financial Data Protocol."""
2
+
3
+ from .client import (
4
+ DEFAULT_FDP_CONFIG,
5
+ ArtifactUpload,
6
+ FdpClient,
7
+ PackageRevisionDraft,
8
+ PackageUploadResult,
9
+ )
10
+ from .httpclient import FdpConfig, HttpClient
11
+ from .interfaces import ArtifactPackageClient
12
+ from .protocol_client import CentralClient, CentralClientError
13
+
14
+ __all__ = [
15
+ "DEFAULT_FDP_CONFIG",
16
+ "ArtifactPackageClient",
17
+ "ArtifactUpload",
18
+ "CentralClient",
19
+ "CentralClientError",
20
+ "FdpClient",
21
+ "FdpConfig",
22
+ "HttpClient",
23
+ "PackageRevisionDraft",
24
+ "PackageUploadResult",
25
+ ]