tigrbl 0.0.1.dev1__py3-none-any.whl → 0.3.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 (269) hide show
  1. tigrbl/README.md +94 -0
  2. tigrbl/__init__.py +139 -14
  3. tigrbl/api/__init__.py +6 -0
  4. tigrbl/api/_api.py +97 -0
  5. tigrbl/api/api_spec.py +30 -0
  6. tigrbl/api/mro_collect.py +43 -0
  7. tigrbl/api/shortcuts.py +56 -0
  8. tigrbl/api/tigrbl_api.py +291 -0
  9. tigrbl/app/__init__.py +0 -0
  10. tigrbl/app/_app.py +86 -0
  11. tigrbl/app/_model_registry.py +41 -0
  12. tigrbl/app/app_spec.py +42 -0
  13. tigrbl/app/mro_collect.py +67 -0
  14. tigrbl/app/shortcuts.py +65 -0
  15. tigrbl/app/tigrbl_app.py +319 -0
  16. tigrbl/bindings/__init__.py +73 -0
  17. tigrbl/bindings/api/__init__.py +12 -0
  18. tigrbl/bindings/api/common.py +109 -0
  19. tigrbl/bindings/api/include.py +256 -0
  20. tigrbl/bindings/api/resource_proxy.py +149 -0
  21. tigrbl/bindings/api/rpc.py +111 -0
  22. tigrbl/bindings/columns.py +49 -0
  23. tigrbl/bindings/handlers/__init__.py +11 -0
  24. tigrbl/bindings/handlers/builder.py +119 -0
  25. tigrbl/bindings/handlers/ctx.py +74 -0
  26. tigrbl/bindings/handlers/identifiers.py +228 -0
  27. tigrbl/bindings/handlers/namespaces.py +51 -0
  28. tigrbl/bindings/handlers/steps.py +276 -0
  29. tigrbl/bindings/hooks.py +311 -0
  30. tigrbl/bindings/model.py +194 -0
  31. tigrbl/bindings/model_helpers.py +139 -0
  32. tigrbl/bindings/model_registry.py +77 -0
  33. tigrbl/bindings/rest/__init__.py +7 -0
  34. tigrbl/bindings/rest/attach.py +34 -0
  35. tigrbl/bindings/rest/collection.py +286 -0
  36. tigrbl/bindings/rest/common.py +120 -0
  37. tigrbl/bindings/rest/fastapi.py +76 -0
  38. tigrbl/bindings/rest/helpers.py +119 -0
  39. tigrbl/bindings/rest/io.py +317 -0
  40. tigrbl/bindings/rest/io_headers.py +49 -0
  41. tigrbl/bindings/rest/member.py +386 -0
  42. tigrbl/bindings/rest/router.py +296 -0
  43. tigrbl/bindings/rest/routing.py +153 -0
  44. tigrbl/bindings/rpc.py +364 -0
  45. tigrbl/bindings/schemas/__init__.py +11 -0
  46. tigrbl/bindings/schemas/builder.py +348 -0
  47. tigrbl/bindings/schemas/defaults.py +260 -0
  48. tigrbl/bindings/schemas/utils.py +193 -0
  49. tigrbl/column/README.md +62 -0
  50. tigrbl/column/__init__.py +72 -0
  51. tigrbl/column/_column.py +96 -0
  52. tigrbl/column/column_spec.py +40 -0
  53. tigrbl/column/field_spec.py +31 -0
  54. tigrbl/column/infer/__init__.py +25 -0
  55. tigrbl/column/infer/core.py +92 -0
  56. tigrbl/column/infer/jsonhints.py +44 -0
  57. tigrbl/column/infer/planning.py +133 -0
  58. tigrbl/column/infer/types.py +102 -0
  59. tigrbl/column/infer/utils.py +59 -0
  60. tigrbl/column/io_spec.py +136 -0
  61. tigrbl/column/mro_collect.py +59 -0
  62. tigrbl/column/shortcuts.py +89 -0
  63. tigrbl/column/storage_spec.py +65 -0
  64. tigrbl/config/__init__.py +19 -0
  65. tigrbl/config/constants.py +224 -0
  66. tigrbl/config/defaults.py +29 -0
  67. tigrbl/config/resolver.py +295 -0
  68. tigrbl/core/__init__.py +47 -0
  69. tigrbl/core/crud/__init__.py +36 -0
  70. tigrbl/core/crud/bulk.py +168 -0
  71. tigrbl/core/crud/helpers/__init__.py +76 -0
  72. tigrbl/core/crud/helpers/db.py +92 -0
  73. tigrbl/core/crud/helpers/enum.py +86 -0
  74. tigrbl/core/crud/helpers/filters.py +162 -0
  75. tigrbl/core/crud/helpers/model.py +123 -0
  76. tigrbl/core/crud/helpers/normalize.py +99 -0
  77. tigrbl/core/crud/ops.py +235 -0
  78. tigrbl/ddl/__init__.py +344 -0
  79. tigrbl/decorators.py +17 -0
  80. tigrbl/deps/__init__.py +20 -0
  81. tigrbl/deps/fastapi.py +45 -0
  82. tigrbl/deps/favicon.svg +4 -0
  83. tigrbl/deps/jinja.py +27 -0
  84. tigrbl/deps/pydantic.py +10 -0
  85. tigrbl/deps/sqlalchemy.py +94 -0
  86. tigrbl/deps/starlette.py +36 -0
  87. tigrbl/engine/__init__.py +45 -0
  88. tigrbl/engine/_engine.py +144 -0
  89. tigrbl/engine/bind.py +33 -0
  90. tigrbl/engine/builders.py +236 -0
  91. tigrbl/engine/capabilities.py +29 -0
  92. tigrbl/engine/collect.py +111 -0
  93. tigrbl/engine/decorators.py +110 -0
  94. tigrbl/engine/docs/PLUGINS.md +49 -0
  95. tigrbl/engine/engine_spec.py +355 -0
  96. tigrbl/engine/plugins.py +52 -0
  97. tigrbl/engine/registry.py +36 -0
  98. tigrbl/engine/resolver.py +224 -0
  99. tigrbl/engine/shortcuts.py +216 -0
  100. tigrbl/hook/__init__.py +21 -0
  101. tigrbl/hook/_hook.py +22 -0
  102. tigrbl/hook/decorators.py +28 -0
  103. tigrbl/hook/hook_spec.py +24 -0
  104. tigrbl/hook/mro_collect.py +98 -0
  105. tigrbl/hook/shortcuts.py +44 -0
  106. tigrbl/hook/types.py +76 -0
  107. tigrbl/op/__init__.py +50 -0
  108. tigrbl/op/_op.py +31 -0
  109. tigrbl/op/canonical.py +31 -0
  110. tigrbl/op/collect.py +11 -0
  111. tigrbl/op/decorators.py +238 -0
  112. tigrbl/op/model_registry.py +301 -0
  113. tigrbl/op/mro_collect.py +99 -0
  114. tigrbl/op/resolver.py +216 -0
  115. tigrbl/op/types.py +136 -0
  116. tigrbl/orm/__init__.py +1 -0
  117. tigrbl/orm/mixins/_RowBound.py +83 -0
  118. tigrbl/orm/mixins/__init__.py +95 -0
  119. tigrbl/orm/mixins/bootstrappable.py +113 -0
  120. tigrbl/orm/mixins/bound.py +47 -0
  121. tigrbl/orm/mixins/edges.py +40 -0
  122. tigrbl/orm/mixins/fields.py +165 -0
  123. tigrbl/orm/mixins/hierarchy.py +54 -0
  124. tigrbl/orm/mixins/key_digest.py +44 -0
  125. tigrbl/orm/mixins/lifecycle.py +115 -0
  126. tigrbl/orm/mixins/locks.py +51 -0
  127. tigrbl/orm/mixins/markers.py +16 -0
  128. tigrbl/orm/mixins/operations.py +57 -0
  129. tigrbl/orm/mixins/ownable.py +337 -0
  130. tigrbl/orm/mixins/principals.py +98 -0
  131. tigrbl/orm/mixins/tenant_bound.py +301 -0
  132. tigrbl/orm/mixins/upsertable.py +118 -0
  133. tigrbl/orm/mixins/utils.py +49 -0
  134. tigrbl/orm/tables/__init__.py +72 -0
  135. tigrbl/orm/tables/_base.py +8 -0
  136. tigrbl/orm/tables/audit.py +56 -0
  137. tigrbl/orm/tables/client.py +25 -0
  138. tigrbl/orm/tables/group.py +29 -0
  139. tigrbl/orm/tables/org.py +30 -0
  140. tigrbl/orm/tables/rbac.py +76 -0
  141. tigrbl/orm/tables/status.py +106 -0
  142. tigrbl/orm/tables/tenant.py +22 -0
  143. tigrbl/orm/tables/user.py +39 -0
  144. tigrbl/response/README.md +34 -0
  145. tigrbl/response/__init__.py +33 -0
  146. tigrbl/response/bind.py +12 -0
  147. tigrbl/response/decorators.py +37 -0
  148. tigrbl/response/resolver.py +83 -0
  149. tigrbl/response/shortcuts.py +171 -0
  150. tigrbl/response/types.py +49 -0
  151. tigrbl/rest/__init__.py +27 -0
  152. tigrbl/runtime/README.md +129 -0
  153. tigrbl/runtime/__init__.py +20 -0
  154. tigrbl/runtime/atoms/__init__.py +102 -0
  155. tigrbl/runtime/atoms/emit/__init__.py +42 -0
  156. tigrbl/runtime/atoms/emit/paired_post.py +158 -0
  157. tigrbl/runtime/atoms/emit/paired_pre.py +106 -0
  158. tigrbl/runtime/atoms/emit/readtime_alias.py +120 -0
  159. tigrbl/runtime/atoms/out/__init__.py +38 -0
  160. tigrbl/runtime/atoms/out/masking.py +135 -0
  161. tigrbl/runtime/atoms/refresh/__init__.py +38 -0
  162. tigrbl/runtime/atoms/refresh/demand.py +130 -0
  163. tigrbl/runtime/atoms/resolve/__init__.py +40 -0
  164. tigrbl/runtime/atoms/resolve/assemble.py +167 -0
  165. tigrbl/runtime/atoms/resolve/paired_gen.py +147 -0
  166. tigrbl/runtime/atoms/response/__init__.py +19 -0
  167. tigrbl/runtime/atoms/response/headers_from_payload.py +57 -0
  168. tigrbl/runtime/atoms/response/negotiate.py +30 -0
  169. tigrbl/runtime/atoms/response/negotiation.py +43 -0
  170. tigrbl/runtime/atoms/response/render.py +36 -0
  171. tigrbl/runtime/atoms/response/renderer.py +116 -0
  172. tigrbl/runtime/atoms/response/template.py +44 -0
  173. tigrbl/runtime/atoms/response/templates.py +88 -0
  174. tigrbl/runtime/atoms/schema/__init__.py +40 -0
  175. tigrbl/runtime/atoms/schema/collect_in.py +21 -0
  176. tigrbl/runtime/atoms/schema/collect_out.py +21 -0
  177. tigrbl/runtime/atoms/storage/__init__.py +38 -0
  178. tigrbl/runtime/atoms/storage/to_stored.py +167 -0
  179. tigrbl/runtime/atoms/wire/__init__.py +45 -0
  180. tigrbl/runtime/atoms/wire/build_in.py +166 -0
  181. tigrbl/runtime/atoms/wire/build_out.py +87 -0
  182. tigrbl/runtime/atoms/wire/dump.py +206 -0
  183. tigrbl/runtime/atoms/wire/validate_in.py +227 -0
  184. tigrbl/runtime/context.py +206 -0
  185. tigrbl/runtime/errors/__init__.py +61 -0
  186. tigrbl/runtime/errors/converters.py +214 -0
  187. tigrbl/runtime/errors/exceptions.py +124 -0
  188. tigrbl/runtime/errors/mappings.py +71 -0
  189. tigrbl/runtime/errors/utils.py +150 -0
  190. tigrbl/runtime/events.py +209 -0
  191. tigrbl/runtime/executor/__init__.py +6 -0
  192. tigrbl/runtime/executor/guards.py +132 -0
  193. tigrbl/runtime/executor/helpers.py +88 -0
  194. tigrbl/runtime/executor/invoke.py +150 -0
  195. tigrbl/runtime/executor/types.py +84 -0
  196. tigrbl/runtime/kernel.py +644 -0
  197. tigrbl/runtime/labels.py +353 -0
  198. tigrbl/runtime/opview.py +89 -0
  199. tigrbl/runtime/ordering.py +256 -0
  200. tigrbl/runtime/system.py +279 -0
  201. tigrbl/runtime/trace.py +330 -0
  202. tigrbl/schema/__init__.py +38 -0
  203. tigrbl/schema/_schema.py +27 -0
  204. tigrbl/schema/builder/__init__.py +17 -0
  205. tigrbl/schema/builder/build_schema.py +209 -0
  206. tigrbl/schema/builder/cache.py +24 -0
  207. tigrbl/schema/builder/compat.py +16 -0
  208. tigrbl/schema/builder/extras.py +85 -0
  209. tigrbl/schema/builder/helpers.py +51 -0
  210. tigrbl/schema/builder/list_params.py +117 -0
  211. tigrbl/schema/builder/strip_parent_fields.py +70 -0
  212. tigrbl/schema/collect.py +79 -0
  213. tigrbl/schema/decorators.py +68 -0
  214. tigrbl/schema/get_schema.py +86 -0
  215. tigrbl/schema/schema_spec.py +20 -0
  216. tigrbl/schema/shortcuts.py +42 -0
  217. tigrbl/schema/types.py +34 -0
  218. tigrbl/schema/utils.py +143 -0
  219. tigrbl/session/README.md +14 -0
  220. tigrbl/session/__init__.py +28 -0
  221. tigrbl/session/abc.py +76 -0
  222. tigrbl/session/base.py +151 -0
  223. tigrbl/session/decorators.py +43 -0
  224. tigrbl/session/default.py +118 -0
  225. tigrbl/session/shortcuts.py +50 -0
  226. tigrbl/session/spec.py +112 -0
  227. tigrbl/shortcuts.py +22 -0
  228. tigrbl/specs.py +44 -0
  229. tigrbl/system/__init__.py +13 -0
  230. tigrbl/system/diagnostics/__init__.py +24 -0
  231. tigrbl/system/diagnostics/compat.py +31 -0
  232. tigrbl/system/diagnostics/healthz.py +41 -0
  233. tigrbl/system/diagnostics/hookz.py +51 -0
  234. tigrbl/system/diagnostics/kernelz.py +20 -0
  235. tigrbl/system/diagnostics/methodz.py +43 -0
  236. tigrbl/system/diagnostics/router.py +73 -0
  237. tigrbl/system/diagnostics/utils.py +43 -0
  238. tigrbl/system/uvicorn.py +60 -0
  239. tigrbl/table/__init__.py +9 -0
  240. tigrbl/table/_base.py +260 -0
  241. tigrbl/table/_table.py +54 -0
  242. tigrbl/table/mro_collect.py +69 -0
  243. tigrbl/table/shortcuts.py +57 -0
  244. tigrbl/table/table_spec.py +28 -0
  245. tigrbl/transport/__init__.py +74 -0
  246. tigrbl/transport/jsonrpc/__init__.py +19 -0
  247. tigrbl/transport/jsonrpc/dispatcher.py +352 -0
  248. tigrbl/transport/jsonrpc/helpers.py +115 -0
  249. tigrbl/transport/jsonrpc/models.py +41 -0
  250. tigrbl/transport/rest/__init__.py +25 -0
  251. tigrbl/transport/rest/aggregator.py +132 -0
  252. tigrbl/types/__init__.py +170 -0
  253. tigrbl/types/allow_anon_provider.py +19 -0
  254. tigrbl/types/authn_abc.py +30 -0
  255. tigrbl/types/nested_path_provider.py +22 -0
  256. tigrbl/types/op.py +35 -0
  257. tigrbl/types/op_config_provider.py +17 -0
  258. tigrbl/types/op_verb_alias_provider.py +33 -0
  259. tigrbl/types/request_extras_provider.py +22 -0
  260. tigrbl/types/response_extras_provider.py +22 -0
  261. tigrbl/types/table_config_provider.py +13 -0
  262. tigrbl/types/uuid.py +55 -0
  263. tigrbl-0.3.0.dist-info/METADATA +516 -0
  264. tigrbl-0.3.0.dist-info/RECORD +266 -0
  265. {tigrbl-0.0.1.dev1.dist-info → tigrbl-0.3.0.dist-info}/WHEEL +1 -1
  266. tigrbl-0.3.0.dist-info/licenses/LICENSE +201 -0
  267. tigrbl/ExampleAgent.py +0 -1
  268. tigrbl-0.0.1.dev1.dist-info/METADATA +0 -18
  269. tigrbl-0.0.1.dev1.dist-info/RECORD +0 -5
@@ -0,0 +1,516 @@
1
+ Metadata-Version: 2.4
2
+ Name: tigrbl
3
+ Version: 0.3.0
4
+ Summary: Automatic API generation tools by Swarmauri.
5
+ License-Expression: Apache-2.0
6
+ License-File: LICENSE
7
+ Keywords: tigrbl,sdk,standards
8
+ Author: Swarmauri Team
9
+ Author-email: team@swarmauri.com
10
+ Requires-Python: >=3.10,<3.13
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Provides-Extra: postgres
20
+ Provides-Extra: templates
21
+ Provides-Extra: tests
22
+ Requires-Dist: aiosqlite (>=0.19.0)
23
+ Requires-Dist: asyncpg (>=0.30.0) ; extra == "postgres"
24
+ Requires-Dist: fastapi (>=0.100.0)
25
+ Requires-Dist: greenlet (>=3.2.3)
26
+ Requires-Dist: httpx (>=0.27.0)
27
+ Requires-Dist: jinja2 (>=3.1.4) ; extra == "templates"
28
+ Requires-Dist: psycopg2-binary (>=2.9.9) ; extra == "postgres"
29
+ Requires-Dist: pydantic (>=2.0.0)
30
+ Requires-Dist: sqlalchemy (>=2.0)
31
+ Requires-Dist: swarmauri_base
32
+ Requires-Dist: swarmauri_core
33
+ Requires-Dist: swarmauri_standard
34
+ Requires-Dist: tigrbl-tests ; extra == "tests"
35
+ Requires-Dist: uvicorn
36
+ Description-Content-Type: text/markdown
37
+
38
+ ![Tigrbl Logo](https://github.com/swarmauri/swarmauri-sdk/blob/a170683ecda8ca1c4f912c966d4499649ffb8224/assets/tigrbl.brand.theme.svg)
39
+
40
+ <p align="center">
41
+ <a href="https://pypi.org/project/tigrbl/">
42
+ <img src="https://img.shields.io/pypi/dm/tigrbl" alt="PyPI - Downloads"/></a>
43
+ <a href="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/tigrbl/">
44
+ <img alt="Hits" src="https://hits.sh/github.com/swarmauri/swarmauri-sdk/tree/master/pkgs/standards/tigrbl.svg"/></a>
45
+ <a href="https://pypi.org/project/tigrbl/">
46
+ <img src="https://img.shields.io/pypi/pyversions/tigrbl" alt="PyPI - Python Version"/></a>
47
+ <a href="https://pypi.org/project/tigrbl/">
48
+ <img src="https://img.shields.io/pypi/l/tigrbl" alt="PyPI - License"/></a>
49
+ <a href="https://pypi.org/project/tigrbl/">
50
+ <img src="https://img.shields.io/pypi/v/tigrbl?label=tigrbl&color=green" alt="PyPI - tigrbl"/></a>
51
+ </p>
52
+
53
+ ---
54
+
55
+ # Tigrbl 🐅🐂
56
+ A high-leverage meta-framework that turns plain SQLAlchemy models into a fully-featured REST+RPC surface with near-zero boilerplate. 🚀
57
+
58
+ ## Features ✨
59
+
60
+ - ⚡ Zero-boilerplate CRUD for SQLAlchemy models
61
+ - 🔌 Unified REST and RPC endpoints from a single definition
62
+ - 🪝 Hookable phase system for deep customization
63
+ - 🧩 Pluggable engine and provider abstractions
64
+ - 🚀 Built on FastAPI and Pydantic for modern Python web apps
65
+
66
+ ## Terminology 📚
67
+
68
+ - **Tenant** 🏢 – a namespace used to group related resources.
69
+ - **Principal** 👤 – an owner of resources, such as an individual user or an organization.
70
+ - **Resource** 📦 – a logical collection of data or functionality exposed by the API.
71
+ - **Engine** ⚙️ – the database connection and transaction manager backing a resource.
72
+ - **Model / Table** 🧱 – the ORM or database representation of a resource's records.
73
+ - **Column** 📏 – a field on a model that maps to a table column.
74
+ - **Operation** 🛠️ – a verb-driven action executed against a resource.
75
+ - **Hook** 🪝 – a callback that runs during a phase to customize behavior.
76
+ - **Phase** ⏱️ – a step in the request lifecycle where hooks may run.
77
+ - **Verb** 🔤 – the canonical name of an operation such as create or read.
78
+ - **Runtime** 🧠 – orchestrates phases and hooks while processing a request.
79
+ - **Kernel** 🧩 – the core dispatcher invoked by the runtime to handle operations.
80
+ - **Schema** 🧬 – the structured shape of request or response data.
81
+ - **Request** 📥 – inbound data and context provided to an operation.
82
+ - **Response** 📤 – outbound result returned after an operation completes.
83
+
84
+ ## Built-in Verbs 🧰
85
+
86
+ Tigrbl exposes a canonical set of operations that surface as both REST
87
+ and RPC endpoints. The table below summarizes the default REST routes,
88
+ RPC methods, arity, and the expected input and output shapes for each
89
+ verb. `{resource}` stands for the collection path and `{id}` is the
90
+ primary key placeholder.
91
+
92
+ | Verb | REST route | RPC method | Arity | Input type | Output type |
93
+ |------|------------|------------|-------|------------|-------------|
94
+ | `create` ➕ | `POST /{resource}` | `Model.create` | collection | dict | dict |
95
+ | `read` 🔍 | `GET /{resource}/{id}` | `Model.read` | member | – | dict |
96
+ | `update` ✏️ | `PATCH /{resource}/{id}` | `Model.update` | member | dict | dict |
97
+ | `replace` ♻️ | `PUT /{resource}/{id}` | `Model.replace` | member | dict | dict |
98
+ | `merge` 🧬 | `PATCH /{resource}/{id}` | `Model.merge` | member | dict | dict |
99
+ | `delete` 🗑️ | `DELETE /{resource}/{id}` | `Model.delete` | member | – | dict |
100
+ | `list` 📃 | `GET /{resource}` | `Model.list` | collection | dict | array |
101
+ | `clear` 🧹 | `DELETE /{resource}` | `Model.clear` | collection | dict | dict |
102
+ | `bulk_create` 📦➕ | `POST /{resource}` | `Model.bulk_create` | collection | array | array |
103
+ | `bulk_update` 📦✏️ | `PATCH /{resource}` | `Model.bulk_update` | collection | array | array |
104
+ | `bulk_replace` 📦♻️ | `PUT /{resource}` | `Model.bulk_replace` | collection | array | array |
105
+ | `bulk_merge` 📦🧬 | `PATCH /{resource}` | `Model.bulk_merge` | collection | array | array |
106
+ | `bulk_delete` 📦🗑️ | `DELETE /{resource}` | `Model.bulk_delete` | collection | dict | dict |
107
+ | `bulk_read` – | – | – | – | – | – |
108
+
109
+ ### Update, Merge, and Replace 🔄
110
+
111
+ `update` applies a shallow PATCH: only the supplied fields change and
112
+ missing fields are left untouched. `merge` performs a deep merge with
113
+ upsert semantics—if the target row is absent it is created, and nested
114
+ mapping fields are merged rather than replaced. `replace` follows PUT
115
+ semantics, overwriting the entire record and nulling any omitted
116
+ attributes.
117
+
118
+ ### Verb Overrides 🧭
119
+
120
+ Because `create` and `bulk_create` share the same collection `POST`
121
+ route, enabling `bulk_create` removes the REST `create` endpoint; the
122
+ `Model.create` RPC method remains available. Likewise, `bulk_delete`
123
+ supersedes `clear` by claiming the collection `DELETE` route. Only one
124
+ of each conflicting pair can be exposed at a time. Other verbs coexist
125
+ without conflict because they operate on distinct paths or HTTP
126
+ methods.
127
+
128
+ ## Phase Lifecycle ⛓️
129
+
130
+ Tigrbl operations execute through a fixed sequence of phases. Hook chains can
131
+ attach handlers at any phase to customize behavior or enforce policy.
132
+
133
+ | Phase | Description |
134
+ |-------|-------------|
135
+ | `PRE_TX_BEGIN` ⏳ | Pre-transaction checks before a database session is used. |
136
+ | `START_TX` 🚦 | Open a new transaction when one is not already active. |
137
+ | `PRE_HANDLER` 🧹 | Validate the request and prepare resources for the handler. |
138
+ | `HANDLER` ▶️ | Execute the core operation logic within the transaction. |
139
+ | `POST_HANDLER` 🔧 | Post-processing while still inside the transaction. |
140
+ | `PRE_COMMIT` ✅ | Final verification before committing; writes are frozen. |
141
+ | `END_TX` 🧾 | Commit and close the transaction. |
142
+ | `POST_COMMIT` 📌 | Steps that run after commit but before the response is returned. |
143
+ | `POST_RESPONSE` 📮 | Fire-and-forget work after the response has been sent. |
144
+ | `ON_ERROR` 🛑 | Fallback error handler when no phase-specific chain matches. |
145
+ | `ON_PRE_TX_BEGIN_ERROR` 🧯 | Handle errors raised during `PRE_TX_BEGIN`. |
146
+ | `ON_START_TX_ERROR` 🧯 | Handle errors raised during `START_TX`. |
147
+ | `ON_PRE_HANDLER_ERROR` 🧯 | Handle errors raised during `PRE_HANDLER`. |
148
+ | `ON_HANDLER_ERROR` 🧯 | Handle errors raised during `HANDLER`. |
149
+ | `ON_POST_HANDLER_ERROR` 🧯 | Handle errors raised during `POST_HANDLER`. |
150
+ | `ON_PRE_COMMIT_ERROR` 🧯 | Handle errors raised during `PRE_COMMIT`. |
151
+ | `ON_END_TX_ERROR` 🧯 | Handle errors raised during `END_TX`. |
152
+ | `ON_POST_COMMIT_ERROR` 🧯 | Handle errors raised during `POST_COMMIT`. |
153
+ | `ON_POST_RESPONSE_ERROR` 🧯 | Handle errors raised during `POST_RESPONSE`. |
154
+ | `ON_ROLLBACK` ↩️ | Run when the transaction rolls back to perform cleanup. |
155
+
156
+ ### Happy-path flow
157
+
158
+ ```
159
+
160
+ PRE\_TX\_BEGIN
161
+ |
162
+ START\_TX
163
+ |
164
+ PRE\_HANDLER
165
+ |
166
+ HANDLER
167
+ |
168
+ POST\_HANDLER
169
+ |
170
+ PRE\_COMMIT
171
+ |
172
+ END\_TX
173
+ |
174
+ POST\_COMMIT
175
+ |
176
+ POST\_RESPONSE
177
+
178
+ ```
179
+
180
+ If a phase raises an exception, control transfers to the matching
181
+ `ON_<PHASE>_ERROR` chain or falls back to `ON_ERROR`, with `ON_ROLLBACK`
182
+ executing when the transaction is rolled back.
183
+
184
+ ## Request → Response Flow Examples 🔀
185
+
186
+ ### REST example
187
+
188
+ ```
189
+
190
+ Client
191
+ |
192
+ v
193
+ HTTP Request
194
+ |
195
+ v
196
+ FastAPI Router
197
+ |
198
+ v
199
+ Tigrbl Runtime
200
+ |
201
+ v
202
+ Operation Handler
203
+ |
204
+ v
205
+ HTTP Response
206
+
207
+ ```
208
+
209
+ ### RPC example
210
+
211
+ ```
212
+
213
+ Client
214
+ |
215
+ v
216
+ JSON-RPC Request
217
+ |
218
+ v
219
+ RPC Dispatcher
220
+ |
221
+ v
222
+ Tigrbl Runtime
223
+ |
224
+ v
225
+ Operation Handler
226
+ |
227
+ v
228
+ JSON-RPC Response
229
+
230
+ ````
231
+
232
+ ## Hooks 🪝
233
+
234
+ Hooks allow you to plug custom logic into any phase of a verb. Use the
235
+ `hook_ctx` decorator to declare context-only hooks:
236
+
237
+ ```python
238
+ from tigrbl import Base, hook_ctx
239
+
240
+ class Item(Base):
241
+ __tablename__ = "items"
242
+
243
+ @hook_ctx(ops="create", phase="PRE_HANDLER")
244
+ async def validate(cls, ctx):
245
+ if ctx["request"].payload.get("name") == "bad":
246
+ raise ValueError("invalid name")
247
+ ````
248
+
249
+ The function runs during the `PRE_HANDLER` phase of `create`. The
250
+ `ctx` mapping provides request and response objects, a database session,
251
+ and values from earlier hooks.
252
+
253
+ Hooks can also be registered imperatively:
254
+
255
+ ```python
256
+ async def audit(ctx):
257
+ ...
258
+
259
+ class Item(Base):
260
+ __tigrbl_hooks__ = {"delete": {"POST_COMMIT": [audit]}}
261
+ ```
262
+
263
+ Running apps expose a `/system/hookz` route that lists all registered
264
+ hooks. 📋
265
+
266
+ ## Step Types 🧱
267
+
268
+ Tigrbl orders work into labeled steps that control how phases run:
269
+
270
+ * **secdeps** 🔐 – security dependencies executed before other checks. Downstream
271
+ applications declare these to enforce auth or policy.
272
+ * **deps** 🧩 – general dependencies resolved ahead of phase handlers. Downstream
273
+ code provides these to inject request context or resources.
274
+ * **sys** 🏗️ – system steps bundled with Tigrbl that drive core behavior.
275
+ Maintainers own these and downstream packages should not modify them.
276
+ * **atoms** ⚛️ – built-in runtime units such as schema collectors or wire
277
+ validators. These are maintained by the core team.
278
+ * **hooks** 🪝 – extension points that downstream packages register to customize
279
+ phase behavior.
280
+
281
+ Only `secdeps`, `deps`, and `hooks` are expected to be configured downstream;
282
+ `sys` and `atom` steps are maintained by the Tigrbl maintainers.
283
+
284
+ ## Kernelz Labeling 🔎
285
+
286
+ Running apps expose a `/system/kernelz` diagnostics endpoint that returns the
287
+ kernel's phase plan for each model and operation. Every entry is prefixed by
288
+ its phase and a descriptive label, for example:
289
+
290
+ ```
291
+ PRE_TX:secdep:myapp.auth.require_user
292
+ HANDLER:hook:wire:myapp.handlers.audit@HANDLER
293
+ END_TX:hook:sys:txn:commit@END_TX
294
+ POST_HANDLER:atom:wire:dump@POST_HANDLER
295
+ ```
296
+
297
+ The token after the phase identifies the step type:
298
+
299
+ * `secdep` and `dep` – security and general dependencies as
300
+ `PRE_TX:secdep:<callable>` and `PRE_TX:dep:<callable>`.
301
+ * `hook:sys` – built-in system hooks shipped with Tigrbl.
302
+ * `hook:wire` – default label for user hooks including module/function name + phase.
303
+ * `atom:{domain}:{subject}` – runtime atoms, e.g. `atom:wire:dump`.
304
+
305
+ These labels allow downstream services to inspect execution order and debug how
306
+ work is scheduled. 🧭
307
+
308
+ ## Configuration Overview ⚙️
309
+
310
+ ### Operation Config Precedence 🧮
311
+
312
+ When merging configuration for a given operation, Tigrbl layers settings in
313
+ increasing order of precedence:
314
+
315
+ 1. defaults
316
+ 2. app config
317
+ 3. API config
318
+ 4. table config
319
+ 5. column `.cfg` entries
320
+ 6. operation spec
321
+ 7. per-request overrides
322
+
323
+ Later entries override earlier ones, so request overrides win over all other
324
+ sources. This can be summarized as
325
+ `overrides > opspec > colspecs > tabspec > apispec > appspec > defaults`.
326
+
327
+ ### Schema Config Precedence 🧬
328
+
329
+ Tigrbl merges schema configuration from several scopes.
330
+ Later layers override earlier ones, with the precedence order:
331
+
332
+ 1. defaults (lowest)
333
+ 2. app configuration
334
+ 3. API configuration
335
+ 4. table configuration
336
+ 5. column-level `cfg` values
337
+ 6. op-specific `cfg`
338
+ 7. per-request overrides (highest)
339
+
340
+ This hierarchy ensures that the most specific settings always win. 🥇
341
+
342
+ ### Table-Level 🧾
343
+
344
+ * `__tigrbl_request_extras__` – verb-scoped virtual request fields.
345
+ * `__tigrbl_response_extras__` – verb-scoped virtual response fields.
346
+ * `__tigrbl_register_hooks__` – hook registration entry point.
347
+ * `__tigrbl_nested_paths__` – nested REST path segments.
348
+ * `__tigrbl_allow_anon__` – verbs permitted without auth.
349
+ * `__tigrbl_owner_policy__` / `__tigrbl_tenant_policy__` – server vs client field injection.
350
+ * `__tigrbl_verb_aliases__` & `__tigrbl_verb_alias_policy__` – custom verb names.
351
+
352
+ ### Routing 🧭
353
+
354
+ * `__tigrbl_nested_paths__` for hierarchical routing.
355
+ * `__tigrbl_verb_aliases__` for custom verbs.
356
+ * `__tigrbl_verb_alias_policy__` to scope alias application.
357
+
358
+ ### Persistence 💾
359
+
360
+ * Mixins such as `Upsertable`, `Bootstrappable`, `GUIDPk`, `Timestamped`.
361
+ * Policies `__tigrbl_owner_policy__` and `__tigrbl_tenant_policy__`.
362
+ * `transactional` decorator for atomic RPC + REST endpoints.
363
+
364
+ ### Security 🔐
365
+
366
+ * Pluggable `AuthNProvider` interface.
367
+ * `__tigrbl_allow_anon__` to permit anonymous access.
368
+
369
+ ### Default Precedence 🔧
370
+
371
+ When assembling values for persistence, defaults are resolved in this order:
372
+
373
+ 1. Client-supplied value
374
+ 2. API `default_factory`
375
+ 3. ORM default
376
+ 4. Database `server_default`
377
+ 5. HTTP 422 if the field is required and still missing
378
+
379
+ ### Database Guards 🛡️
380
+
381
+ Tigrbl executes each phase under database guards that temporarily replace
382
+ `commit` and `flush` on the SQLAlchemy session. Guards prevent writes or
383
+ commits outside their allowed phases and only permit commits when Tigrbl
384
+ owns the transaction. See the
385
+ [runtime documentation](tigrbl/v3/runtime/README.md#db-guards) for the full
386
+ matrix of phase policies.
387
+
388
+ The `START_TX` phase opens a transaction and disables `session.flush`,
389
+ allowing validation and hooks to run before any statements hit the
390
+ database. Once the transaction exists, `PRE_HANDLER`, `HANDLER`, and
391
+ `POST_HANDLER` phases permit flushes so pending writes reach the database
392
+ without committing. The workflow concludes in `END_TX`, which performs a
393
+ final flush and commits the transaction when the runtime owns it. ✅
394
+
395
+ ### Response and Template Specs 📑
396
+
397
+ Customize outbound responses with `ResponseSpec` and `TemplateSpec`. These dataclasses
398
+ control headers, status codes, and optional template rendering. See
399
+ [tigrbl/v3/response/README.md](tigrbl/v3/response/README.md) for field descriptions and examples.
400
+
401
+ ### Dependencies 📦
402
+
403
+ * SQLAlchemy for ORM integration.
404
+ * Pydantic for schema generation.
405
+ * FastAPI for routing and dependency injection.
406
+
407
+ ### Engine & Provider examples 🛠️
408
+
409
+ ```python
410
+ from tigrbl.engine.shortcuts import engine_spec, prov
411
+ from tigrbl.engine._engine import Engine, Provider
412
+
413
+ # Build an EngineSpec from a DSN string
414
+ spec = engine_spec("sqlite://:memory:")
415
+
416
+ # Or from keyword arguments
417
+ spec_pg = engine_spec(kind="postgres", async_=True, host="db", name="app_db")
418
+
419
+ # Lazy Provider from the spec
420
+ provider = prov(spec) # same as Provider(spec)
421
+ with provider.session() as session:
422
+ session.execute("SELECT 1")
423
+
424
+ # Engine façade wrapping a Provider
425
+ eng = Engine(spec_pg)
426
+ async with eng.asession() as session:
427
+ await session.execute("SELECT 1")
428
+
429
+ # Direct Provider construction is also supported
430
+ provider_pg = Provider(spec_pg)
431
+ ```
432
+
433
+ ### Attaching engine contexts 🔌
434
+
435
+ `engine_ctx` binds database configuration to different layers. It accepts a
436
+ DSN string, a mapping, an `EngineSpec`, a `Provider`, or an `Engine`. The
437
+ resolver chooses the most specific binding in the order
438
+ `op > table > api > app`.
439
+
440
+ #### Engine precedence 🥇
441
+
442
+ When engine contexts are declared at multiple scopes, Tigrbl resolves them
443
+ with strict precedence:
444
+
445
+ 1. **Op level** – bindings attached directly to an operation take highest priority.
446
+ 2. **Table/Model level** – definitions on a model or table override API and app defaults.
447
+ 3. **API level** – bindings on the API class apply when no model-specific context exists.
448
+ 4. **App level** – the default engine supplied to the application is used last.
449
+
450
+ This ordering ensures that the most specific engine context always wins.
451
+
452
+ #### Declarative bindings 📝
453
+
454
+ ```python
455
+ from types import SimpleNamespace
456
+ from tigrbl.engine.shortcuts import prov, engine
457
+
458
+ app = SimpleNamespace(db=prov(kind="sqlite", mode="memory"))
459
+ alt = SimpleNamespace(db=engine(kind="sqlite", mode="memory"))
460
+
461
+ class API:
462
+ db = {"kind": "sqlite", "memory": True}
463
+
464
+ class Item:
465
+ __tablename__ = "items"
466
+ table_config = {"db": {"kind": "sqlite", "memory": True}}
467
+
468
+ async def create(payload, *, db=None):
469
+ ...
470
+
471
+ create.__tigrbl_engine_ctx__ = {
472
+ "kind": "postgres",
473
+ "async": True,
474
+ "host": "db",
475
+ "name": "op_db",
476
+ }
477
+ ```
478
+
479
+ #### Decorative bindings 🎛️
480
+
481
+ ```python
482
+ from tigrbl.engine.decorators import engine_ctx
483
+ from tigrbl.engine.shortcuts import prov, engine
484
+
485
+ @engine_ctx(prov(kind="sqlite", mode="memory"))
486
+ class App:
487
+ pass
488
+
489
+ @engine_ctx(engine(kind="sqlite", mode="memory"))
490
+ class DecoratedAPI:
491
+ pass
492
+
493
+ @engine_ctx(kind="sqlite", mode="memory")
494
+ class DecoratedItem:
495
+ __tablename__ = "items"
496
+
497
+ @engine_ctx(kind="postgres", async_=True, host="db", name="op_db")
498
+ async def decorated_create(payload, *, db=None):
499
+ ...
500
+ ```
501
+
502
+ ## Glossary 📖
503
+
504
+ 1. Tables
505
+ 2. Schemas
506
+ 3. Schema Overlays (Request Extras)
507
+ 4. Phases
508
+ 5. Phase Lifecycle
509
+ 6. Request
510
+ 7. Request Ctx
511
+ 8. Default Flush
512
+ 9. Core
513
+ 10. Core\_Raw
514
+
515
+
516
+