tigrbl-typing 0.1.12.dev1__tar.gz → 0.1.13.dev1__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 (23) hide show
  1. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/PKG-INFO +4 -1
  2. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/pyproject.toml +8 -2
  3. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/phases.py +67 -15
  4. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/status/utils.py +12 -0
  5. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/README.md +0 -0
  6. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/__init__.py +0 -0
  7. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/channel.py +0 -0
  8. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/gw/__init__.py +0 -0
  9. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/gw/raw.py +0 -0
  10. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/protocols.py +0 -0
  11. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/request.py +0 -0
  12. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/status/__init__.py +0 -0
  13. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/status/converters.py +0 -0
  14. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/status/exceptions.py +0 -0
  15. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/status/mappings.py +0 -0
  16. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/types/__init__.py +0 -0
  17. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/types/authn_abc.py +0 -0
  18. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/types/channel.py +0 -0
  19. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/types/op.py +0 -0
  20. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/types/uuid.py +0 -0
  21. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/vendor/__init__.py +0 -0
  22. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/vendor/pydantic.py +0 -0
  23. {tigrbl_typing-0.1.12.dev1 → tigrbl_typing-0.1.13.dev1}/tigrbl_typing/vendor/sqlalchemy.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tigrbl-typing
3
- Version: 0.1.12.dev1
3
+ Version: 0.1.13.dev1
4
4
  Summary: Typing protocols and shared type helpers for the Tigrbl framework.
5
5
  License-Expression: Apache-2.0
6
6
  Keywords: tigrbl,sdk,standards,framework
@@ -16,6 +16,9 @@ Classifier: Programming Language :: Python
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Programming Language :: Python :: 3 :: Only
18
18
  Requires-Dist: pydantic (>=2.10,<3)
19
+ Project-URL: Homepage, https://github.com/swarmauri/tigrbl
20
+ Project-URL: Issues, https://github.com/swarmauri/tigrbl/issues
21
+ Project-URL: Repository, https://github.com/swarmauri/tigrbl/tree/main/pkgs/core/tigrbl_typing
19
22
  Description-Content-Type: text/markdown
20
23
 
21
24
  # tigrbl_typing
@@ -1,10 +1,9 @@
1
1
  [project]
2
2
  name = "tigrbl-typing"
3
- version = "0.1.12.dev1"
3
+ version = "0.1.13.dev1"
4
4
  description = "Typing protocols and shared type helpers for the Tigrbl framework."
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
7
- repository = "http://github.com/swarmauri/swarmauri-sdk"
8
7
  requires-python = ">=3.10,<3.14"
9
8
  classifiers = [
10
9
  "Development Status :: 1 - Planning",
@@ -17,11 +16,18 @@ classifiers = [
17
16
  "Programming Language :: Python :: 3 :: Only",
18
17
  ]
19
18
  authors = [{ name = "Jacob Stewart", email = "jacob@swarmauri.com" }]
19
+
20
20
  dependencies = [
21
21
  "pydantic>=2.10,<3",
22
22
  ]
23
23
  keywords = ["tigrbl", "sdk", "standards", "framework"]
24
24
 
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/swarmauri/tigrbl"
28
+ Repository = "https://github.com/swarmauri/tigrbl/tree/main/pkgs/core/tigrbl_typing"
29
+ Issues = "https://github.com/swarmauri/tigrbl/issues"
30
+
25
31
  [build-system]
26
32
  requires = ["poetry-core>=1.0.0"]
27
33
  build-backend = "poetry.core.masonry.api"
@@ -3,6 +3,18 @@ from __future__ import annotations
3
3
  from enum import Enum
4
4
  from typing import Literal, Tuple
5
5
 
6
+ PHASE_ALIASES: dict[str, str] = {
7
+ "END_TX": "TX_COMMIT",
8
+ "ON_END_TX_ERROR": "ON_TX_COMMIT_ERROR",
9
+ "ON_ROLLBACK": "TX_ROLLBACK",
10
+ }
11
+
12
+
13
+ def normalize_phase(name: str | None) -> str | None:
14
+ if name is None:
15
+ return None
16
+ return PHASE_ALIASES.get(str(name), str(name))
17
+
6
18
  HookPhase = Literal[
7
19
  "PRE_TX_BEGIN",
8
20
  "START_TX",
@@ -10,7 +22,7 @@ HookPhase = Literal[
10
22
  "HANDLER",
11
23
  "POST_HANDLER",
12
24
  "PRE_COMMIT",
13
- "END_TX",
25
+ "TX_COMMIT",
14
26
  "POST_COMMIT",
15
27
  "POST_RESPONSE",
16
28
  "ON_ERROR",
@@ -20,26 +32,28 @@ HookPhase = Literal[
20
32
  "ON_HANDLER_ERROR",
21
33
  "ON_POST_HANDLER_ERROR",
22
34
  "ON_PRE_COMMIT_ERROR",
23
- "ON_END_TX_ERROR",
35
+ "ON_TX_COMMIT_ERROR",
24
36
  "ON_POST_COMMIT_ERROR",
25
37
  "ON_POST_RESPONSE_ERROR",
26
- "ON_ROLLBACK",
38
+ "TX_ROLLBACK",
27
39
  ]
28
40
 
29
41
  Phase = Literal[
30
42
  "INGRESS_BEGIN",
31
43
  "INGRESS_PARSE",
32
- "INGRESS_ROUTE",
44
+ "INGRESS_DISPATCH",
33
45
  "PRE_TX_BEGIN",
34
46
  "START_TX",
35
47
  "PRE_HANDLER",
36
48
  "HANDLER",
37
49
  "POST_HANDLER",
38
50
  "PRE_COMMIT",
39
- "END_TX",
51
+ "TX_COMMIT",
40
52
  "POST_COMMIT",
41
53
  "EGRESS_SHAPE",
42
54
  "EGRESS_FINALIZE",
55
+ "EMIT",
56
+ "POST_EMIT",
43
57
  "POST_RESPONSE",
44
58
  "ON_ERROR",
45
59
  "ON_PRE_TX_BEGIN_ERROR",
@@ -48,10 +62,10 @@ Phase = Literal[
48
62
  "ON_HANDLER_ERROR",
49
63
  "ON_POST_HANDLER_ERROR",
50
64
  "ON_PRE_COMMIT_ERROR",
51
- "ON_END_TX_ERROR",
65
+ "ON_TX_COMMIT_ERROR",
52
66
  "ON_POST_COMMIT_ERROR",
53
67
  "ON_POST_RESPONSE_ERROR",
54
- "ON_ROLLBACK",
68
+ "TX_ROLLBACK",
55
69
  ]
56
70
 
57
71
 
@@ -62,7 +76,7 @@ class PHASE(str, Enum):
62
76
  HANDLER = "HANDLER"
63
77
  POST_HANDLER = "POST_HANDLER"
64
78
  PRE_COMMIT = "PRE_COMMIT"
65
- END_TX = "END_TX"
79
+ TX_COMMIT = "TX_COMMIT"
66
80
  POST_COMMIT = "POST_COMMIT"
67
81
  POST_RESPONSE = "POST_RESPONSE"
68
82
  ON_ERROR = "ON_ERROR"
@@ -72,27 +86,36 @@ class PHASE(str, Enum):
72
86
  ON_HANDLER_ERROR = "ON_HANDLER_ERROR"
73
87
  ON_POST_HANDLER_ERROR = "ON_POST_HANDLER_ERROR"
74
88
  ON_PRE_COMMIT_ERROR = "ON_PRE_COMMIT_ERROR"
75
- ON_END_TX_ERROR = "ON_END_TX_ERROR"
89
+ ON_TX_COMMIT_ERROR = "ON_TX_COMMIT_ERROR"
76
90
  ON_POST_COMMIT_ERROR = "ON_POST_COMMIT_ERROR"
77
91
  ON_POST_RESPONSE_ERROR = "ON_POST_RESPONSE_ERROR"
78
- ON_ROLLBACK = "ON_ROLLBACK"
92
+ TX_ROLLBACK = "TX_ROLLBACK"
93
+
94
+ @classmethod
95
+ def _missing_(cls, value: object):
96
+ normalized = normalize_phase(str(value)) if value is not None else None
97
+ if normalized != value:
98
+ return cls(normalized)
99
+ return None
79
100
 
80
101
 
81
102
  HOOK_PHASES: Tuple[HookPhase, ...] = tuple(p.value for p in PHASE)
82
103
  PHASES: Tuple[Phase, ...] = (
83
104
  "INGRESS_BEGIN",
84
105
  "INGRESS_PARSE",
85
- "INGRESS_ROUTE",
106
+ "INGRESS_DISPATCH",
86
107
  "PRE_TX_BEGIN",
87
108
  "START_TX",
88
109
  "PRE_HANDLER",
89
110
  "HANDLER",
90
111
  "POST_HANDLER",
91
112
  "PRE_COMMIT",
92
- "END_TX",
113
+ "TX_COMMIT",
93
114
  "POST_COMMIT",
94
115
  "EGRESS_SHAPE",
95
116
  "EGRESS_FINALIZE",
117
+ "EMIT",
118
+ "POST_EMIT",
96
119
  "POST_RESPONSE",
97
120
  "ON_ERROR",
98
121
  "ON_PRE_TX_BEGIN_ERROR",
@@ -101,10 +124,39 @@ PHASES: Tuple[Phase, ...] = (
101
124
  "ON_HANDLER_ERROR",
102
125
  "ON_POST_HANDLER_ERROR",
103
126
  "ON_PRE_COMMIT_ERROR",
104
- "ON_END_TX_ERROR",
127
+ "ON_TX_COMMIT_ERROR",
105
128
  "ON_POST_COMMIT_ERROR",
106
129
  "ON_POST_RESPONSE_ERROR",
107
- "ON_ROLLBACK",
130
+ "TX_ROLLBACK",
108
131
  )
109
132
 
110
- __all__ = ["PHASE", "PHASES", "HOOK_PHASES", "Phase", "HookPhase"]
133
+
134
+ def compile_protocol_phase_projection(proto: str) -> dict[str, object]:
135
+ stream_like = proto in {"http.stream", "https.stream", "http.sse", "https.sse"}
136
+ phase_order = (
137
+ "INGRESS_PARSE",
138
+ "INGRESS_DISPATCH",
139
+ "PRE_HANDLER",
140
+ "HANDLER",
141
+ "POST_HANDLER",
142
+ "EMIT",
143
+ "POST_EMIT",
144
+ )
145
+ if not stream_like:
146
+ phase_order = phase_order[:5] + ("EGRESS_SHAPE", "EGRESS_FINALIZE") + phase_order[5:]
147
+ return {
148
+ "proto": proto,
149
+ "phase_order": phase_order,
150
+ "phases": tuple({"phase": phase} for phase in phase_order),
151
+ }
152
+
153
+ __all__ = [
154
+ "PHASE",
155
+ "PHASES",
156
+ "HOOK_PHASES",
157
+ "Phase",
158
+ "HookPhase",
159
+ "PHASE_ALIASES",
160
+ "compile_protocol_phase_projection",
161
+ "normalize_phase",
162
+ ]
@@ -44,6 +44,17 @@ def _is_asyncpg_constraint_error(exc: BaseException) -> bool:
44
44
  )
45
45
 
46
46
 
47
+ def is_persistence_exception(exc: BaseException) -> bool:
48
+ if _is_asyncpg_constraint_error(exc):
49
+ return True
50
+ candidates = tuple(
51
+ typ
52
+ for typ in (DBAPIError, IntegrityError, OperationalError)
53
+ if isinstance(typ, type)
54
+ )
55
+ return bool(candidates) and isinstance(exc, candidates)
56
+
57
+
47
58
  def _limit(s: str, n: int = 4000) -> str:
48
59
  return s if len(s) <= n else s[: n - 3] + "..."
49
60
 
@@ -105,6 +116,7 @@ __all__ = [
105
116
  "OperationalError",
106
117
  "NoResultFound",
107
118
  "_is_asyncpg_constraint_error",
119
+ "is_persistence_exception",
108
120
  "_limit",
109
121
  "_stringify_exc",
110
122
  "_format_validation",