tigrbl-base 0.4.2.dev4__tar.gz → 0.4.3.dev4__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 (38) hide show
  1. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/PKG-INFO +64 -4
  2. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/README.md +63 -3
  3. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/pyproject.toml +1 -1
  4. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/__init__.py +5 -0
  5. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_app_base.py +3 -3
  6. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_mapping_access.py +6 -0
  7. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_table_base.py +54 -1
  8. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/LICENSE +0 -0
  9. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/NOTICE +0 -0
  10. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_alias_base.py +0 -0
  11. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_assembly.py +0 -0
  12. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_binding_base.py +0 -0
  13. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_column_base.py +0 -0
  14. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_datatype_lowering.py +0 -0
  15. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_engine_base.py +0 -0
  16. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_engine_provider_base.py +0 -0
  17. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_headers_base.py +0 -0
  18. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_hook_base.py +0 -0
  19. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_middleware_base.py +0 -0
  20. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_op_base.py +0 -0
  21. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_request_base.py +0 -0
  22. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_response_base.py +0 -0
  23. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_rest_map.py +0 -0
  24. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_router_base.py +0 -0
  25. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_rpc_map.py +0 -0
  26. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_schema_base.py +0 -0
  27. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_security_base.py +0 -0
  28. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_session_abc.py +0 -0
  29. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_session_base.py +0 -0
  30. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_storage.py +0 -0
  31. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/_base/_table_registry_base.py +0 -0
  32. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/column/__init__.py +0 -0
  33. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/column/infer/__init__.py +0 -0
  34. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/column/infer/core.py +0 -0
  35. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/column/infer/jsonhints.py +0 -0
  36. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/column/infer/planning.py +0 -0
  37. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/column/infer/types.py +0 -0
  38. {tigrbl_base-0.4.2.dev4 → tigrbl_base-0.4.3.dev4}/tigrbl_base/column/infer/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tigrbl-base
3
- Version: 0.4.2.dev4
3
+ Version: 0.4.3.dev4
4
4
  Summary: Base contract package for Tigrbl apps, routers, tables, sessions, middleware, requests, responses, bindings, and engine interfaces.
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -250,7 +250,7 @@ Description-Content-Type: text/markdown
250
250
  <a href="https://discord.gg/K4YTAPapjR"><img src="https://img.shields.io/badge/Discord-Join%20chat-5865F2?logo=discord&logoColor=white" alt="Discord community for tigrbl-base"/></a>
251
251
  <a href="https://github.com/tigrbl/tigrbl/blob/master/pkgs/core/tigrbl_base/README.md"><img src="https://hits.sh/github.com/tigrbl/tigrbl/blob/master/pkgs/core/tigrbl_base/README.md.svg?label=hits" alt="Repository hits for tigrbl-base README"/></a>
252
252
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-525252" alt="Apache 2.0 license"/></a>
253
- <a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-3776ab" alt="Python versions 3.10 | 3.11 | 3.12 | 3.13 | 3.14 for tigrbl-base"/></a>
253
+ <a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%2C%203.11%2C%203.12%2C%203.13%2C%203.14-3776ab" alt="Python versions 3.10 | 3.11 | 3.12 | 3.13 | 3.14 for tigrbl-base"/></a>
254
254
  <a href="https://github.com/tigrbl/tigrbl/blob/master/docs/README.md"><img src="https://img.shields.io/badge/workspace-core-1f6feb" alt="Workspace group for tigrbl-base"/></a>
255
255
  </div>
256
256
 
@@ -307,7 +307,7 @@ pip install tigrbl-base
307
307
  | Entry points | none declared |
308
308
  | Optional extras | none declared |
309
309
  | Legal files | `LICENSE`, `NOTICE` |
310
- | Supported Python | `3.10 | 3.11 | 3.12 | 3.13 | 3.14` |
310
+ | Supported Python | `3.10, 3.11, 3.12, 3.13, 3.14` |
311
311
 
312
312
  ## What It Owns
313
313
 
@@ -316,6 +316,15 @@ pip install tigrbl-base
316
316
  Implementation orientation:
317
317
  - `tigrbl_base`: _base/, column/
318
318
 
319
+ Package catalog:
320
+ - `_base/_app_base.py`, `_router_base.py`, and `_table_base.py`: abstract app, router, and table behavior used by concrete framework classes.
321
+ - `_base/_op_base.py`, `_binding_base.py`, `_rest_map.py`, and `_rpc_map.py`: operation, binding, REST mapping, and JSON-RPC mapping contracts.
322
+ - `_base/_schema_base.py`, `_request_base.py`, `_response_base.py`, `_headers_base.py`, and `_middleware_base.py`: request/response/schema/header/middleware abstractions.
323
+ - `_base/_engine_base.py`, `_engine_provider_base.py`, `_session_abc.py`, `_session_base.py`, and `_storage.py`: engine, provider, session, and storage interfaces.
324
+ - `_base/_column_base.py`, `_table_registry_base.py`, `_alias_base.py`, `_hook_base.py`, `_security_base.py`, and `_datatype_lowering.py`: table metadata, aliasing, hook/security contracts, and data-type lowering hooks.
325
+ - `_base/_assembly.py` and `_mapping_access.py`: assembly and mapping helpers for concrete implementations.
326
+ - `column/infer`: column inference planning, JSON hint handling, type interpretation, and utility helpers.
327
+
319
328
  ## Public API and Import Surface
320
329
 
321
330
  - Import roots: `tigrbl_base`.
@@ -323,6 +332,55 @@ Implementation orientation:
323
332
  - Workspace dependencies: [`tigrbl-core`](https://pypi.org/project/tigrbl-core/), [`tigrbl-atoms`](https://pypi.org/project/tigrbl-atoms/).
324
333
  - External runtime dependencies: `sqlalchemy>=2.0`, `pydantic>=2.0`.
325
334
 
335
+ ## Abstraction Semantics
336
+
337
+ `tigrbl-base` is the abstract contract layer between core specs and concrete implementations. It is useful when you need interface behavior without importing the facade or concrete ASGI/application classes.
338
+
339
+ The package answers questions such as:
340
+
341
+ - What must an app/router/table expose for assembly?
342
+ - How do REST and JSON-RPC maps represent operation bindings?
343
+ - What does a request, response, middleware, hook, session, engine provider, or storage adapter need to provide?
344
+ - How should column metadata be inferred before a concrete table class lowers it into ORM/schema/runtime behavior?
345
+
346
+ It should not own route registration side effects, transport IO, database engine construction, or runtime execution. Those belong in `tigrbl-concrete`, engine packages, kernel/runtime packages, or the facade.
347
+
348
+ ## Base Contracts by Area
349
+
350
+ | Area | Base responsibility |
351
+ |---|---|
352
+ | App/router/table | Provide shared assembly, inclusion, registration, and metadata contracts. |
353
+ | Operations and bindings | Represent operation maps, REST maps, RPC maps, alias behavior, and binding access. |
354
+ | Schema and IO | Provide base shape for request/response/schema objects without deciding concrete rendering. |
355
+ | Engine/session/storage | Define provider/session/storage contracts so concrete engines can plug in consistently. |
356
+ | Hooks/security/middleware | Provide registration and interface surfaces for lifecycle customization and request policy. |
357
+ | Columns | Infer and lower type information while keeping spec-level intent separate from concrete ORM wiring. |
358
+
359
+ ## Column Inference
360
+
361
+ `tigrbl_base.column.infer` supports the framework's schema-first and table-first workflows. It helps interpret Python typing, JSON hints, planning metadata, and column options before concrete packages lower them into SQLAlchemy/Pydantic/runtime representations.
362
+
363
+ Best practices for column inference:
364
+ - Keep inference deterministic; the same type hints and config should produce the same plan.
365
+ - Keep storage intent separate from wire-schema intent.
366
+ - Preserve explicit user configuration over inferred defaults.
367
+ - Add tests for ambiguous type handling instead of silently guessing.
368
+
369
+ ## Extension Guidance
370
+
371
+ - Depend on `tigrbl-base` when you are writing concrete adapters, engine adapters, or framework tests that need abstract contracts.
372
+ - Do not import `tigrbl` facade classes here; base should remain lower than the public facade.
373
+ - Keep methods small and contract-oriented. Put operational side effects in concrete implementations or atoms.
374
+ - Treat base classes as compatibility surfaces. Renaming or tightening a method affects all concrete packages.
375
+ - Prefer composition with `tigrbl-core` specs rather than duplicating spec fields in base classes.
376
+
377
+ Authoring BCP for this boundary:
378
+ - Do use `tigrbl-base` for abstract app/router/table/session/request/response/binding/security/middleware/storage contracts and column inference behavior.
379
+ - Do keep column inference deterministic and spec-driven before concrete packages lower intent into ORM, schema, runtime, or docs behavior.
380
+ - Do not make `tigrbl-base` the public application import path for normal service code.
381
+ - Do not put route registration side effects, direct database transaction calls, concrete engine construction, FastAPI/Starlette route objects, or runtime execution into this package.
382
+ - Avoid treating SQLAlchemy materialization as the source of truth here. Base may prepare and validate metadata, but reusable field behavior should remain represented by Tigrbl specs.
383
+
326
384
  ## Usage Examples
327
385
 
328
386
  ### Verify the installed package
@@ -383,6 +441,8 @@ Choose `tigrbl-base` when the quick-answer table matches your use case. Choose [
383
441
  - [Package layout](https://github.com/tigrbl/tigrbl/blob/master/docs/developer/PACKAGE_LAYOUT.md)
384
442
  - [Current target](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/CURRENT_TARGET.md)
385
443
  - [Current state](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/CURRENT_STATE.md)
444
+ - [Next steps](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/NEXT_STEPS.md)
445
+ - [Documentation pointers](https://github.com/tigrbl/tigrbl/blob/master/docs/governance/DOC_POINTERS.md)
386
446
  - [SSOT registry](https://github.com/tigrbl/tigrbl/blob/master/.ssot/registry.json)
387
447
  - [Release workflow](https://github.com/tigrbl/tigrbl/actions/workflows/publish.yml)
388
448
 
@@ -394,7 +454,7 @@ Choose `tigrbl-base` when the quick-answer table matches your use case. Choose [
394
454
 
395
455
  ## Package-local Boundary
396
456
 
397
- This README is the package-local distribution entry point for `tigrbl-base`. It answers install, usage, API, ownership, and certification-orientation questions for this package. Broader architectural decisions, release status, and cross-package proof chains remain in the repository-level docs and SSOT registry.
457
+ This file is a package-local distribution entry point. This README is the package-local distribution entry point for `tigrbl-base`. It answers install, usage, API, ownership, and certification-orientation questions for this package. Broader architectural decisions, release status, and cross-package proof chains remain in the repository-level docs and SSOT registry.
398
458
 
399
459
  ## License
400
460
 
@@ -7,7 +7,7 @@
7
7
  <a href="https://discord.gg/K4YTAPapjR"><img src="https://img.shields.io/badge/Discord-Join%20chat-5865F2?logo=discord&logoColor=white" alt="Discord community for tigrbl-base"/></a>
8
8
  <a href="https://github.com/tigrbl/tigrbl/blob/master/pkgs/core/tigrbl_base/README.md"><img src="https://hits.sh/github.com/tigrbl/tigrbl/blob/master/pkgs/core/tigrbl_base/README.md.svg?label=hits" alt="Repository hits for tigrbl-base README"/></a>
9
9
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-525252" alt="Apache 2.0 license"/></a>
10
- <a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-3776ab" alt="Python versions 3.10 | 3.11 | 3.12 | 3.13 | 3.14 for tigrbl-base"/></a>
10
+ <a href="pyproject.toml"><img src="https://img.shields.io/badge/python-3.10%2C%203.11%2C%203.12%2C%203.13%2C%203.14-3776ab" alt="Python versions 3.10 | 3.11 | 3.12 | 3.13 | 3.14 for tigrbl-base"/></a>
11
11
  <a href="https://github.com/tigrbl/tigrbl/blob/master/docs/README.md"><img src="https://img.shields.io/badge/workspace-core-1f6feb" alt="Workspace group for tigrbl-base"/></a>
12
12
  </div>
13
13
 
@@ -64,7 +64,7 @@ pip install tigrbl-base
64
64
  | Entry points | none declared |
65
65
  | Optional extras | none declared |
66
66
  | Legal files | `LICENSE`, `NOTICE` |
67
- | Supported Python | `3.10 | 3.11 | 3.12 | 3.13 | 3.14` |
67
+ | Supported Python | `3.10, 3.11, 3.12, 3.13, 3.14` |
68
68
 
69
69
  ## What It Owns
70
70
 
@@ -73,6 +73,15 @@ pip install tigrbl-base
73
73
  Implementation orientation:
74
74
  - `tigrbl_base`: _base/, column/
75
75
 
76
+ Package catalog:
77
+ - `_base/_app_base.py`, `_router_base.py`, and `_table_base.py`: abstract app, router, and table behavior used by concrete framework classes.
78
+ - `_base/_op_base.py`, `_binding_base.py`, `_rest_map.py`, and `_rpc_map.py`: operation, binding, REST mapping, and JSON-RPC mapping contracts.
79
+ - `_base/_schema_base.py`, `_request_base.py`, `_response_base.py`, `_headers_base.py`, and `_middleware_base.py`: request/response/schema/header/middleware abstractions.
80
+ - `_base/_engine_base.py`, `_engine_provider_base.py`, `_session_abc.py`, `_session_base.py`, and `_storage.py`: engine, provider, session, and storage interfaces.
81
+ - `_base/_column_base.py`, `_table_registry_base.py`, `_alias_base.py`, `_hook_base.py`, `_security_base.py`, and `_datatype_lowering.py`: table metadata, aliasing, hook/security contracts, and data-type lowering hooks.
82
+ - `_base/_assembly.py` and `_mapping_access.py`: assembly and mapping helpers for concrete implementations.
83
+ - `column/infer`: column inference planning, JSON hint handling, type interpretation, and utility helpers.
84
+
76
85
  ## Public API and Import Surface
77
86
 
78
87
  - Import roots: `tigrbl_base`.
@@ -80,6 +89,55 @@ Implementation orientation:
80
89
  - Workspace dependencies: [`tigrbl-core`](https://pypi.org/project/tigrbl-core/), [`tigrbl-atoms`](https://pypi.org/project/tigrbl-atoms/).
81
90
  - External runtime dependencies: `sqlalchemy>=2.0`, `pydantic>=2.0`.
82
91
 
92
+ ## Abstraction Semantics
93
+
94
+ `tigrbl-base` is the abstract contract layer between core specs and concrete implementations. It is useful when you need interface behavior without importing the facade or concrete ASGI/application classes.
95
+
96
+ The package answers questions such as:
97
+
98
+ - What must an app/router/table expose for assembly?
99
+ - How do REST and JSON-RPC maps represent operation bindings?
100
+ - What does a request, response, middleware, hook, session, engine provider, or storage adapter need to provide?
101
+ - How should column metadata be inferred before a concrete table class lowers it into ORM/schema/runtime behavior?
102
+
103
+ It should not own route registration side effects, transport IO, database engine construction, or runtime execution. Those belong in `tigrbl-concrete`, engine packages, kernel/runtime packages, or the facade.
104
+
105
+ ## Base Contracts by Area
106
+
107
+ | Area | Base responsibility |
108
+ |---|---|
109
+ | App/router/table | Provide shared assembly, inclusion, registration, and metadata contracts. |
110
+ | Operations and bindings | Represent operation maps, REST maps, RPC maps, alias behavior, and binding access. |
111
+ | Schema and IO | Provide base shape for request/response/schema objects without deciding concrete rendering. |
112
+ | Engine/session/storage | Define provider/session/storage contracts so concrete engines can plug in consistently. |
113
+ | Hooks/security/middleware | Provide registration and interface surfaces for lifecycle customization and request policy. |
114
+ | Columns | Infer and lower type information while keeping spec-level intent separate from concrete ORM wiring. |
115
+
116
+ ## Column Inference
117
+
118
+ `tigrbl_base.column.infer` supports the framework's schema-first and table-first workflows. It helps interpret Python typing, JSON hints, planning metadata, and column options before concrete packages lower them into SQLAlchemy/Pydantic/runtime representations.
119
+
120
+ Best practices for column inference:
121
+ - Keep inference deterministic; the same type hints and config should produce the same plan.
122
+ - Keep storage intent separate from wire-schema intent.
123
+ - Preserve explicit user configuration over inferred defaults.
124
+ - Add tests for ambiguous type handling instead of silently guessing.
125
+
126
+ ## Extension Guidance
127
+
128
+ - Depend on `tigrbl-base` when you are writing concrete adapters, engine adapters, or framework tests that need abstract contracts.
129
+ - Do not import `tigrbl` facade classes here; base should remain lower than the public facade.
130
+ - Keep methods small and contract-oriented. Put operational side effects in concrete implementations or atoms.
131
+ - Treat base classes as compatibility surfaces. Renaming or tightening a method affects all concrete packages.
132
+ - Prefer composition with `tigrbl-core` specs rather than duplicating spec fields in base classes.
133
+
134
+ Authoring BCP for this boundary:
135
+ - Do use `tigrbl-base` for abstract app/router/table/session/request/response/binding/security/middleware/storage contracts and column inference behavior.
136
+ - Do keep column inference deterministic and spec-driven before concrete packages lower intent into ORM, schema, runtime, or docs behavior.
137
+ - Do not make `tigrbl-base` the public application import path for normal service code.
138
+ - Do not put route registration side effects, direct database transaction calls, concrete engine construction, FastAPI/Starlette route objects, or runtime execution into this package.
139
+ - Avoid treating SQLAlchemy materialization as the source of truth here. Base may prepare and validate metadata, but reusable field behavior should remain represented by Tigrbl specs.
140
+
83
141
  ## Usage Examples
84
142
 
85
143
  ### Verify the installed package
@@ -140,6 +198,8 @@ Choose `tigrbl-base` when the quick-answer table matches your use case. Choose [
140
198
  - [Package layout](https://github.com/tigrbl/tigrbl/blob/master/docs/developer/PACKAGE_LAYOUT.md)
141
199
  - [Current target](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/CURRENT_TARGET.md)
142
200
  - [Current state](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/CURRENT_STATE.md)
201
+ - [Next steps](https://github.com/tigrbl/tigrbl/blob/master/docs/conformance/NEXT_STEPS.md)
202
+ - [Documentation pointers](https://github.com/tigrbl/tigrbl/blob/master/docs/governance/DOC_POINTERS.md)
143
203
  - [SSOT registry](https://github.com/tigrbl/tigrbl/blob/master/.ssot/registry.json)
144
204
  - [Release workflow](https://github.com/tigrbl/tigrbl/actions/workflows/publish.yml)
145
205
 
@@ -151,7 +211,7 @@ Choose `tigrbl-base` when the quick-answer table matches your use case. Choose [
151
211
 
152
212
  ## Package-local Boundary
153
213
 
154
- This README is the package-local distribution entry point for `tigrbl-base`. It answers install, usage, API, ownership, and certification-orientation questions for this package. Broader architectural decisions, release status, and cross-package proof chains remain in the repository-level docs and SSOT registry.
214
+ This file is a package-local distribution entry point. This README is the package-local distribution entry point for `tigrbl-base`. It answers install, usage, API, ownership, and certification-orientation questions for this package. Broader architectural decisions, release status, and cross-package proof chains remain in the repository-level docs and SSOT registry.
155
215
 
156
216
  ## License
157
217
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tigrbl-base"
3
- version = "0.4.2.dev4"
3
+ version = "0.4.3.dev4"
4
4
  description = "Base contract package for Tigrbl apps, routers, tables, sessions, middleware, requests, responses, bindings, and engine interfaces."
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -22,6 +22,8 @@ _EXPORTS = {
22
22
  "SchemaBase": "_schema_base",
23
23
  "SessionABC": "_session_abc",
24
24
  "TigrblSessionBase": "_session_base",
25
+ "CrudTableBase": "_table_base",
26
+ "RealtimeTableBase": "_table_base",
25
27
  "TableBase": "_table_base",
26
28
  "TableRegistryBase": "_table_registry_base",
27
29
  "AttrDict": "_mapping_access",
@@ -29,6 +31,9 @@ _EXPORTS = {
29
31
 
30
32
  __all__ = list(_EXPORTS)
31
33
 
34
+ for _symbol in __all__:
35
+ globals().pop(_symbol, None)
36
+
32
37
 
33
38
  def __getattr__(name: str) -> Any:
34
39
  module_name = _EXPORTS.get(name)
@@ -5,7 +5,7 @@ import inspect
5
5
  from typing import Any
6
6
  from typing import Callable, Optional, Sequence
7
7
 
8
- from tigrbl_core._spec.app_spec import AppSpec
8
+ from tigrbl_core._spec.app_spec import AppSpec, normalize_execution_backend
9
9
  from tigrbl_core._spec.engine_spec import EngineCfg
10
10
  from tigrbl_core._spec.response_spec import ResponseSpec
11
11
 
@@ -100,7 +100,7 @@ class AppBase(AppSpec):
100
100
  title=spec.title,
101
101
  description=spec.description,
102
102
  version=spec.version,
103
- execution_backend=spec.execution_backend,
103
+ execution_backend=normalize_execution_backend(spec.execution_backend),
104
104
  engine=spec.engine,
105
105
  routers=routers,
106
106
  ops=tuple(spec.ops or ()),
@@ -133,7 +133,7 @@ class AppBase(AppSpec):
133
133
  title=str(spec.title or "Tigrbl"),
134
134
  description=spec.description,
135
135
  version=str(spec.version or "0.1.0"),
136
- execution_backend=str(spec.execution_backend or "auto"),
136
+ execution_backend=normalize_execution_backend(spec.execution_backend),
137
137
  engine=spec.engine,
138
138
  routers=cls._bind_mapped_children(spec.routers, parent=parent),
139
139
  ops=cls._bind_mapped_children(spec.ops, parent=parent),
@@ -15,5 +15,11 @@ class AttrDict(dict):
15
15
  def __setattr__(self, key: str, value: Any) -> None: # pragma: no cover - trivial
16
16
  self[key] = value
17
17
 
18
+ def __delattr__(self, item: str) -> None:
19
+ try:
20
+ del self[item]
21
+ except KeyError as exc:
22
+ raise AttributeError(item) from exc
23
+
18
24
 
19
25
  __all__ = ["AttrDict"]
@@ -11,6 +11,13 @@ from sqlalchemy import CheckConstraint, ForeignKey, MetaData
11
11
  from sqlalchemy.types import Enum as SAEnum, String
12
12
 
13
13
  from ._datatype_lowering import lower_datatype_to_sqla_type
14
+ from tigrbl_core._spec.table_profile_spec import (
15
+ CRUD_TABLE_PROFILE,
16
+ PLAIN_TABLE_PROFILE,
17
+ REALTIME_TABLE_PROFILE,
18
+ TableProfileError,
19
+ coerce_table_profile,
20
+ )
14
21
 
15
22
  # ──────────────────────────────────────────────────────────────────────────────
16
23
  # Helpers – type inference & SA type instantiation
@@ -342,6 +349,39 @@ def _attach_model_ops_namespace(model: type) -> None:
342
349
  model.opspecs = ops_ns
343
350
 
344
351
 
352
+ def _normalize_table_profile_declaration(cls: type) -> None:
353
+ profile_attr = "TABLE_PROFILE"
354
+ explicit_profile = profile_attr in cls.__dict__
355
+
356
+ legacy_attrs = {
357
+ "DEFAULT_CANON_VERBS",
358
+ "should_wire_canonical",
359
+ "__tigrbl_defaults_mode__",
360
+ "__tigrbl_defaults_include__",
361
+ "__tigrbl_defaults_exclude__",
362
+ "__tigrbl_ops__",
363
+ "OPS",
364
+ }
365
+ present_legacy = sorted(name for name in legacy_attrs if name in cls.__dict__)
366
+ cfg = cls.__dict__.get("table_config")
367
+ if isinstance(cfg, dict) and (
368
+ "binding_profiles" in cfg
369
+ or "default_bindings" in cfg
370
+ or "default_binding_profiles" in cfg
371
+ ):
372
+ present_legacy.append("table_config.binding_profiles")
373
+
374
+ if explicit_profile and present_legacy:
375
+ raise TableProfileError(
376
+ f"{cls.__name__} declares TABLE_PROFILE and legacy table default "
377
+ f"authority {', '.join(present_legacy)}"
378
+ )
379
+
380
+ value = cls.__dict__.get(profile_attr, getattr(cls, profile_attr, PLAIN_TABLE_PROFILE))
381
+ normalized = coerce_table_profile(value)
382
+ setattr(cls, profile_attr, normalized)
383
+
384
+
345
385
  # ──────────────────────────────────────────────────────────────────────────────
346
386
  # Declarative Base
347
387
  # ──────────────────────────────────────────────────────────────────────────────
@@ -349,8 +389,11 @@ def _attach_model_ops_namespace(model: type) -> None:
349
389
 
350
390
  class TableBase(DeclarativeBase):
351
391
  __allow_unmapped__ = True
392
+ TABLE_PROFILE = PLAIN_TABLE_PROFILE
352
393
 
353
394
  def __init_subclass__(cls, **kw):
395
+ _normalize_table_profile_declaration(cls)
396
+
354
397
  # 0) Remove any previously registered class with the same module path.
355
398
  try:
356
399
  reg = TableBase.registry._class_registry
@@ -540,4 +583,14 @@ class TableBase(DeclarativeBase):
540
583
  return getattr(self, key)
541
584
 
542
585
 
543
- __all__ = ["TableBase"]
586
+ class CrudTableBase(TableBase):
587
+ __abstract__ = True
588
+ TABLE_PROFILE = CRUD_TABLE_PROFILE
589
+
590
+
591
+ class RealtimeTableBase(TableBase):
592
+ __abstract__ = True
593
+ TABLE_PROFILE = REALTIME_TABLE_PROFILE
594
+
595
+
596
+ __all__ = ["CrudTableBase", "RealtimeTableBase", "TableBase"]