idemkit 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.
- idemkit/__init__.py +101 -0
- idemkit/_version.py +1 -0
- idemkit/adapters/__init__.py +10 -0
- idemkit/adapters/ai.py +723 -0
- idemkit/adapters/asgi.py +533 -0
- idemkit/adapters/queue.py +413 -0
- idemkit/adapters/route.py +273 -0
- idemkit/adapters/wsgi.py +393 -0
- idemkit/backends/__init__.py +30 -0
- idemkit/backends/base.py +116 -0
- idemkit/backends/dynamodb.py +489 -0
- idemkit/backends/memory.py +325 -0
- idemkit/backends/mongo.py +395 -0
- idemkit/backends/postgres.py +682 -0
- idemkit/backends/redis.py +547 -0
- idemkit/cli.py +165 -0
- idemkit/conformance/__init__.py +25 -0
- idemkit/conformance/backend.py +257 -0
- idemkit/conformance/report.py +54 -0
- idemkit/contrib/__init__.py +30 -0
- idemkit/contrib/drf.py +181 -0
- idemkit/contrib/fastapi.py +141 -0
- idemkit/contrib/kafka.py +96 -0
- idemkit/contrib/logging.py +61 -0
- idemkit/contrib/mcp.py +113 -0
- idemkit/contrib/prometheus.py +79 -0
- idemkit/contrib/pubsub.py +98 -0
- idemkit/contrib/rabbitmq.py +138 -0
- idemkit/contrib/reconciliation.py +86 -0
- idemkit/contrib/sqs.py +117 -0
- idemkit/core/__init__.py +36 -0
- idemkit/core/codecs.py +229 -0
- idemkit/core/config.py +255 -0
- idemkit/core/engine.py +331 -0
- idemkit/core/events.py +63 -0
- idemkit/core/exception_cache.py +88 -0
- idemkit/core/exceptions.py +79 -0
- idemkit/core/fingerprint.py +153 -0
- idemkit/core/policy.py +143 -0
- idemkit/core/runner.py +664 -0
- idemkit/core/state.py +95 -0
- idemkit/core/sync_bridge.py +115 -0
- idemkit/problem_details.py +119 -0
- idemkit/py.typed +0 -0
- idemkit-0.1.0.dist-info/METADATA +446 -0
- idemkit-0.1.0.dist-info/RECORD +48 -0
- idemkit-0.1.0.dist-info/WHEEL +4 -0
- idemkit-0.1.0.dist-info/entry_points.txt +2 -0
idemkit/__init__.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""idemkit — correct, framework-agnostic idempotency for HTTP, queues, and function calls.
|
|
2
|
+
|
|
3
|
+
The behavioral contract is documented in ``spec/README.md`` at the project root.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from idemkit._version import __version__
|
|
7
|
+
from idemkit.adapters.asgi import IdempotencyMiddleware
|
|
8
|
+
from idemkit.backends.base import IdempotencyBackend
|
|
9
|
+
from idemkit.backends.memory import InMemoryBackend, ManualClock
|
|
10
|
+
from idemkit.core.events import EventHandler, IdempotencyEvent
|
|
11
|
+
from idemkit.core.exceptions import (
|
|
12
|
+
ConfigurationError,
|
|
13
|
+
IdempotencyConflict,
|
|
14
|
+
IdempotencyError,
|
|
15
|
+
IdempotencyKeyMissing,
|
|
16
|
+
PayloadMismatch,
|
|
17
|
+
ReplayedError,
|
|
18
|
+
StorageError,
|
|
19
|
+
StorageUnavailable,
|
|
20
|
+
)
|
|
21
|
+
from idemkit.core.policy import HttpConfig, MethodConfig, QueueConfig
|
|
22
|
+
from idemkit.core.state import Decision
|
|
23
|
+
|
|
24
|
+
# Each surface is configured with one config object passed as `config=`:
|
|
25
|
+
# HttpConfig / QueueConfig / MethodConfig. The datastore is configured on the
|
|
26
|
+
# backend (table / namespace), not here.
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"ConfigurationError",
|
|
30
|
+
"ConsumerAction",
|
|
31
|
+
"ConsumerResult",
|
|
32
|
+
"Decision",
|
|
33
|
+
"DynamoBackend",
|
|
34
|
+
"EventHandler",
|
|
35
|
+
"HttpConfig",
|
|
36
|
+
"Idempotency",
|
|
37
|
+
"IdempotencyBackend",
|
|
38
|
+
"IdempotencyConflict",
|
|
39
|
+
"IdempotencyError",
|
|
40
|
+
"IdempotencyEvent",
|
|
41
|
+
"IdempotencyKeyMissing",
|
|
42
|
+
"IdempotencyMiddleware",
|
|
43
|
+
"IdempotentConsumer",
|
|
44
|
+
"InMemoryBackend",
|
|
45
|
+
"ManualClock",
|
|
46
|
+
"MethodConfig",
|
|
47
|
+
"MongoBackend",
|
|
48
|
+
"PayloadMismatch",
|
|
49
|
+
"PostgresBackend",
|
|
50
|
+
"QueueConfig",
|
|
51
|
+
"RedisBackend",
|
|
52
|
+
"ReplayedError",
|
|
53
|
+
"StorageError",
|
|
54
|
+
"StorageUnavailable",
|
|
55
|
+
"WSGIIdempotencyMiddleware",
|
|
56
|
+
"__version__",
|
|
57
|
+
"idempotency_problem_handler",
|
|
58
|
+
"idempotent",
|
|
59
|
+
"idempotent_sync",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def __getattr__(name: str): # type: ignore[no-untyped-def]
|
|
64
|
+
"""Lazy imports for components with optional deps."""
|
|
65
|
+
if name == "RedisBackend":
|
|
66
|
+
from idemkit.backends.redis import RedisBackend
|
|
67
|
+
|
|
68
|
+
return RedisBackend
|
|
69
|
+
if name == "PostgresBackend":
|
|
70
|
+
from idemkit.backends.postgres import PostgresBackend
|
|
71
|
+
|
|
72
|
+
return PostgresBackend
|
|
73
|
+
if name == "MongoBackend":
|
|
74
|
+
from idemkit.backends.mongo import MongoBackend
|
|
75
|
+
|
|
76
|
+
return MongoBackend
|
|
77
|
+
if name == "DynamoBackend":
|
|
78
|
+
from idemkit.backends.dynamodb import DynamoBackend
|
|
79
|
+
|
|
80
|
+
return DynamoBackend
|
|
81
|
+
if name == "Idempotency":
|
|
82
|
+
from idemkit.adapters.route import Idempotency
|
|
83
|
+
|
|
84
|
+
return Idempotency
|
|
85
|
+
if name == "idempotency_problem_handler":
|
|
86
|
+
from idemkit.adapters.route import idempotency_problem_handler
|
|
87
|
+
|
|
88
|
+
return idempotency_problem_handler
|
|
89
|
+
if name == "WSGIIdempotencyMiddleware":
|
|
90
|
+
from idemkit.adapters.wsgi import WSGIIdempotencyMiddleware
|
|
91
|
+
|
|
92
|
+
return WSGIIdempotencyMiddleware
|
|
93
|
+
if name in ("IdempotentConsumer", "ConsumerAction", "ConsumerResult"):
|
|
94
|
+
from idemkit.adapters import queue
|
|
95
|
+
|
|
96
|
+
return getattr(queue, name)
|
|
97
|
+
if name in ("idempotent", "idempotent_sync"):
|
|
98
|
+
from idemkit.adapters import ai
|
|
99
|
+
|
|
100
|
+
return getattr(ai, name)
|
|
101
|
+
raise AttributeError(f"module 'idemkit' has no attribute {name!r}")
|
idemkit/_version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""HTTP framework adapters for idemkit.
|
|
2
|
+
|
|
3
|
+
Ships ASGI middleware (FastAPI / Starlette / any ASGI 3 app) and WSGI middleware
|
|
4
|
+
(Flask / Django sync / any WSGI app).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from idemkit.adapters.asgi import IdempotencyMiddleware
|
|
8
|
+
from idemkit.adapters.wsgi import WSGIIdempotencyMiddleware
|
|
9
|
+
|
|
10
|
+
__all__ = ["IdempotencyMiddleware", "WSGIIdempotencyMiddleware"]
|