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.
Files changed (48) hide show
  1. idemkit/__init__.py +101 -0
  2. idemkit/_version.py +1 -0
  3. idemkit/adapters/__init__.py +10 -0
  4. idemkit/adapters/ai.py +723 -0
  5. idemkit/adapters/asgi.py +533 -0
  6. idemkit/adapters/queue.py +413 -0
  7. idemkit/adapters/route.py +273 -0
  8. idemkit/adapters/wsgi.py +393 -0
  9. idemkit/backends/__init__.py +30 -0
  10. idemkit/backends/base.py +116 -0
  11. idemkit/backends/dynamodb.py +489 -0
  12. idemkit/backends/memory.py +325 -0
  13. idemkit/backends/mongo.py +395 -0
  14. idemkit/backends/postgres.py +682 -0
  15. idemkit/backends/redis.py +547 -0
  16. idemkit/cli.py +165 -0
  17. idemkit/conformance/__init__.py +25 -0
  18. idemkit/conformance/backend.py +257 -0
  19. idemkit/conformance/report.py +54 -0
  20. idemkit/contrib/__init__.py +30 -0
  21. idemkit/contrib/drf.py +181 -0
  22. idemkit/contrib/fastapi.py +141 -0
  23. idemkit/contrib/kafka.py +96 -0
  24. idemkit/contrib/logging.py +61 -0
  25. idemkit/contrib/mcp.py +113 -0
  26. idemkit/contrib/prometheus.py +79 -0
  27. idemkit/contrib/pubsub.py +98 -0
  28. idemkit/contrib/rabbitmq.py +138 -0
  29. idemkit/contrib/reconciliation.py +86 -0
  30. idemkit/contrib/sqs.py +117 -0
  31. idemkit/core/__init__.py +36 -0
  32. idemkit/core/codecs.py +229 -0
  33. idemkit/core/config.py +255 -0
  34. idemkit/core/engine.py +331 -0
  35. idemkit/core/events.py +63 -0
  36. idemkit/core/exception_cache.py +88 -0
  37. idemkit/core/exceptions.py +79 -0
  38. idemkit/core/fingerprint.py +153 -0
  39. idemkit/core/policy.py +143 -0
  40. idemkit/core/runner.py +664 -0
  41. idemkit/core/state.py +95 -0
  42. idemkit/core/sync_bridge.py +115 -0
  43. idemkit/problem_details.py +119 -0
  44. idemkit/py.typed +0 -0
  45. idemkit-0.1.0.dist-info/METADATA +446 -0
  46. idemkit-0.1.0.dist-info/RECORD +48 -0
  47. idemkit-0.1.0.dist-info/WHEEL +4 -0
  48. 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"]