tigrbl 0.3.0.dev3__py3-none-any.whl → 0.3.1__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 (44) hide show
  1. tigrbl/api/_api.py +26 -1
  2. tigrbl/api/tigrbl_api.py +6 -1
  3. tigrbl/app/_app.py +26 -1
  4. tigrbl/app/_model_registry.py +41 -0
  5. tigrbl/app/tigrbl_app.py +6 -1
  6. tigrbl/bindings/rest/collection.py +24 -3
  7. tigrbl/bindings/rest/common.py +4 -0
  8. tigrbl/bindings/rest/io_headers.py +49 -0
  9. tigrbl/bindings/rest/member.py +19 -0
  10. tigrbl/bindings/rest/router.py +4 -0
  11. tigrbl/bindings/rest/routing.py +21 -1
  12. tigrbl/column/io_spec.py +3 -0
  13. tigrbl/engine/__init__.py +19 -0
  14. tigrbl/engine/_engine.py +14 -0
  15. tigrbl/engine/capabilities.py +29 -0
  16. tigrbl/engine/decorators.py +3 -1
  17. tigrbl/engine/docs/PLUGINS.md +49 -0
  18. tigrbl/engine/engine_spec.py +197 -103
  19. tigrbl/engine/plugins.py +52 -0
  20. tigrbl/engine/registry.py +36 -0
  21. tigrbl/orm/mixins/upsertable.py +7 -0
  22. tigrbl/response/shortcuts.py +31 -4
  23. tigrbl/runtime/atoms/response/__init__.py +2 -0
  24. tigrbl/runtime/atoms/response/headers_from_payload.py +57 -0
  25. tigrbl/runtime/kernel.py +27 -11
  26. tigrbl/runtime/opview.py +5 -3
  27. tigrbl/schema/collect.py +26 -2
  28. tigrbl/session/README.md +14 -0
  29. tigrbl/session/__init__.py +28 -0
  30. tigrbl/session/abc.py +76 -0
  31. tigrbl/session/base.py +151 -0
  32. tigrbl/session/decorators.py +43 -0
  33. tigrbl/session/default.py +118 -0
  34. tigrbl/session/shortcuts.py +50 -0
  35. tigrbl/session/spec.py +112 -0
  36. tigrbl/system/__init__.py +2 -1
  37. tigrbl/system/uvicorn.py +60 -0
  38. tigrbl/table/_base.py +28 -5
  39. tigrbl/types/__init__.py +3 -7
  40. tigrbl/types/uuid.py +55 -0
  41. {tigrbl-0.3.0.dev3.dist-info → tigrbl-0.3.1.dist-info}/METADATA +19 -4
  42. {tigrbl-0.3.0.dev3.dist-info → tigrbl-0.3.1.dist-info}/RECORD +44 -27
  43. {tigrbl-0.3.0.dev3.dist-info → tigrbl-0.3.1.dist-info}/WHEEL +1 -1
  44. {tigrbl-0.3.0.dev3.dist-info → tigrbl-0.3.1.dist-info/licenses}/LICENSE +0 -0
tigrbl/session/spec.py ADDED
@@ -0,0 +1,112 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, fields
4
+ from typing import Any, Mapping, MutableMapping, Optional, Union
5
+
6
+ SessionCfg = Union["SessionSpec", Mapping[str, Any], None]
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class SessionSpec:
11
+ """
12
+ Per-session policy for Tigrbl sessions.
13
+
14
+ These fields are backend-agnostic hints and constraints. Adapters should
15
+ validate and apply them where supported; critical ones (like isolation and
16
+ read_only) SHOULD be validated and enforced.
17
+ """
18
+
19
+ # Transaction policy
20
+ isolation: Optional[str] = (
21
+ None # "read_committed" | "repeatable_read" | "snapshot" | "serializable"
22
+ )
23
+ read_only: Optional[bool] = None
24
+ autobegin: Optional[bool] = True
25
+ expire_on_commit: Optional[bool] = None
26
+
27
+ # Retries & backoff
28
+ retry_on_conflict: Optional[bool] = None
29
+ max_retries: int = 0
30
+ backoff_ms: int = 0
31
+ backoff_jitter: bool = True
32
+
33
+ # Timeouts / resources
34
+ statement_timeout_ms: Optional[int] = None
35
+ lock_timeout_ms: Optional[int] = None
36
+ fetch_rows: Optional[int] = None
37
+ stream_chunk_rows: Optional[int] = None
38
+
39
+ # Consistency coordinates
40
+ min_lsn: Optional[str] = None
41
+ as_of_ts: Optional[str] = None
42
+ consistency: Optional[str] = None # "strong" | "bounded_staleness" | "eventual"
43
+ staleness_ms: Optional[int] = None
44
+
45
+ # Tenancy & security
46
+ tenant_id: Optional[str] = None
47
+ role: Optional[str] = None
48
+ rls_context: Mapping[str, str] = None
49
+
50
+ # Observability
51
+ trace_id: Optional[str] = None
52
+ query_tag: Optional[str] = None
53
+ tag: Optional[str] = None
54
+ tracing_sample: Optional[float] = None
55
+
56
+ # Cache / index hints
57
+ cache_read: Optional[bool] = None
58
+ cache_write: Optional[bool] = None
59
+ namespace: Optional[str] = None
60
+
61
+ # Data protection / compliance
62
+ kms_key_alias: Optional[str] = None
63
+ classification: Optional[str] = None
64
+ audit: Optional[bool] = None
65
+
66
+ # Idempotency & pagination
67
+ idempotency_key: Optional[str] = None
68
+ page_snapshot: Optional[str] = None
69
+
70
+ def merge(self, higher: "SessionSpec | Mapping[str, Any] | None") -> "SessionSpec":
71
+ """
72
+ Overlay another spec on top of this one (non-None fields take precedence).
73
+ Use to implement op > model > api > app precedence.
74
+ """
75
+ if higher is None:
76
+ return self
77
+ h = higher if isinstance(higher, SessionSpec) else SessionSpec.from_any(higher)
78
+ if h is None:
79
+ return self
80
+ vals: MutableMapping[str, Any] = {
81
+ f.name: getattr(self, f.name) for f in fields(SessionSpec)
82
+ }
83
+ for f in fields(SessionSpec):
84
+ hv = getattr(h, f.name)
85
+ if hv is not None:
86
+ vals[f.name] = hv
87
+ return SessionSpec(**vals) # type: ignore[arg-type]
88
+
89
+ def to_kwargs(self) -> dict[str, Any]:
90
+ """Return only non-None items as a plain dict (adapters can **kwargs this)."""
91
+ return {
92
+ f.name: getattr(self, f.name)
93
+ for f in fields(SessionSpec)
94
+ if getattr(self, f.name) is not None
95
+ }
96
+
97
+ @staticmethod
98
+ def from_any(x: SessionCfg) -> Optional["SessionSpec"]:
99
+ if x is None:
100
+ return None
101
+ if isinstance(x, SessionSpec):
102
+ return x
103
+ if isinstance(x, Mapping):
104
+ m = dict(x)
105
+ # aliases
106
+ if "readonly" in m and "read_only" not in m:
107
+ m["read_only"] = bool(m.pop("readonly"))
108
+ if "iso" in m and "isolation" not in m:
109
+ m["isolation"] = str(m.pop("iso"))
110
+ allowed = {f.name for f in fields(SessionSpec)}
111
+ return SessionSpec(**{k: v for k, v in m.items() if k in allowed})
112
+ raise TypeError(f"Unsupported SessionSpec input: {type(x)}")
tigrbl/system/__init__.py CHANGED
@@ -8,5 +8,6 @@ Tigrbl v3 – System/Diagnostics helpers.
8
8
  from __future__ import annotations
9
9
 
10
10
  from .diagnostics import mount_diagnostics
11
+ from .uvicorn import stop_uvicorn_server
11
12
 
12
- __all__ = ["mount_diagnostics"]
13
+ __all__ = ["mount_diagnostics", "stop_uvicorn_server"]
@@ -0,0 +1,60 @@
1
+ """Utilities for running uvicorn during tests or tooling."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+
7
+ import uvicorn
8
+
9
+
10
+ async def _cancel_task(task: asyncio.Task) -> None:
11
+ if task.done():
12
+ return
13
+ task.cancel()
14
+ try:
15
+ await task
16
+ except asyncio.CancelledError:
17
+ return
18
+
19
+
20
+ async def _close_servers(server: uvicorn.Server) -> None:
21
+ servers = []
22
+ primary = getattr(server, "server", None)
23
+ if primary is not None:
24
+ servers.append(primary)
25
+ extra = getattr(server, "servers", None)
26
+ if extra:
27
+ servers.extend(extra)
28
+ for srv in servers:
29
+ close = getattr(srv, "close", None)
30
+ if callable(close):
31
+ close()
32
+ wait_closed = getattr(srv, "wait_closed", None)
33
+ if callable(wait_closed):
34
+ await wait_closed()
35
+
36
+
37
+ async def stop_uvicorn_server(
38
+ server: uvicorn.Server,
39
+ task: asyncio.Task,
40
+ *,
41
+ timeout: float = 5.0,
42
+ ) -> None:
43
+ """Request uvicorn shutdown and ensure the task exits."""
44
+ if task.done():
45
+ return
46
+
47
+ server.should_exit = True
48
+ try:
49
+ await asyncio.wait_for(task, timeout=timeout)
50
+ return
51
+ except asyncio.TimeoutError:
52
+ server.force_exit = True
53
+ shutdown = getattr(server, "shutdown", None)
54
+ if callable(shutdown):
55
+ try:
56
+ await asyncio.wait_for(shutdown(), timeout=timeout)
57
+ except asyncio.TimeoutError:
58
+ pass
59
+ await _close_servers(server)
60
+ await _cancel_task(task)
tigrbl/table/_base.py CHANGED
@@ -174,18 +174,41 @@ class Base(DeclarativeBase):
174
174
  __allow_unmapped__ = True
175
175
 
176
176
  def __init_subclass__(cls, **kw):
177
- # 0) Remove any previously registered class with the same name.
177
+ # 0) Remove any previously registered class with the same module path.
178
178
  try:
179
179
  reg = Base.registry._class_registry
180
- keys = [cls.__name__, f"{cls.__module__}.{cls.__name__}"]
181
- existing = next((reg.get(k) for k in keys if reg.get(k) is not None), None)
180
+ key = f"{cls.__module__}.{cls.__name__}"
181
+ existing = reg.get(key)
182
182
  if existing is not None:
183
183
  try:
184
184
  Base.registry._dispose_cls(existing)
185
185
  except Exception:
186
186
  pass
187
- for k in keys:
188
- reg.pop(k, None)
187
+ reg.pop(key, None)
188
+ if reg.get(cls.__name__) is existing:
189
+ reg.pop(cls.__name__, None)
190
+ except Exception:
191
+ pass
192
+
193
+ # 0.5) If a table with the same name already exists, allow this class
194
+ # to extend it instead of raising duplicate-table errors.
195
+ try:
196
+ table_name = getattr(cls, "__tablename__", None)
197
+ if table_name and table_name in Base.metadata.tables:
198
+ table_args = getattr(cls, "__table_args__", None)
199
+ if table_args is None:
200
+ cls.__table_args__ = {"extend_existing": True}
201
+ elif isinstance(table_args, dict):
202
+ table_args = dict(table_args)
203
+ table_args["extend_existing"] = True
204
+ cls.__table_args__ = table_args
205
+ elif isinstance(table_args, tuple):
206
+ if table_args and isinstance(table_args[-1], dict):
207
+ table_dict = dict(table_args[-1])
208
+ table_dict["extend_existing"] = True
209
+ cls.__table_args__ = (*table_args[:-1], table_dict)
210
+ else:
211
+ cls.__table_args__ = (*table_args, {"extend_existing": True})
189
212
  except Exception:
190
213
  pass
191
214
 
tigrbl/types/__init__.py CHANGED
@@ -25,7 +25,6 @@ from ..deps.sqlalchemy import (
25
25
  ARRAY,
26
26
  PgEnum,
27
27
  JSONB,
28
- _PgUUID,
29
28
  TSVECTOR,
30
29
  # ORM
31
30
  Mapped,
@@ -67,6 +66,7 @@ from ..deps.fastapi import (
67
66
 
68
67
  # ── Local Package ─────────────────────────────────────────────────────────
69
68
  from .op import _Op, _SchemaVerb
69
+ from .uuid import PgUUID, SqliteUUID
70
70
  from .authn_abc import AuthNProvider
71
71
  from .table_config_provider import TableConfigProvider
72
72
  from .nested_path_provider import NestedPathProvider
@@ -88,12 +88,6 @@ DateTime = _DateTime(timezone=False)
88
88
  TZDateTime = _DateTime(timezone=True)
89
89
 
90
90
 
91
- class PgUUID(_PgUUID):
92
- @property
93
- def hex(self):
94
- return self.as_uuid.hex
95
-
96
-
97
91
  # ── Public Re-exports (Backwards Compatibility) ──────────────────────────
98
92
  __all__: list[str] = [
99
93
  # local
@@ -110,6 +104,8 @@ __all__: list[str] = [
110
104
  "list_request_extras_providers",
111
105
  "list_response_extras_providers",
112
106
  "OpConfigProvider",
107
+ # add ons
108
+ "SqliteUUID",
113
109
  # builtin types
114
110
  "MethodType",
115
111
  "SimpleNamespace",
tigrbl/types/uuid.py ADDED
@@ -0,0 +1,55 @@
1
+ # ── Standard Library ─────────────────────────────────────────────────────
2
+ from __future__ import annotations
3
+
4
+ from typing import Any
5
+ import uuid
6
+
7
+ # ── Third-party Dependencies ────────────────────────────────────────────
8
+ from sqlalchemy.types import TypeDecorator
9
+
10
+ # ── Local Package ───────────────────────────────────────────────────────
11
+ from ..deps.sqlalchemy import String, _PgUUID
12
+
13
+
14
+ class PgUUID(_PgUUID):
15
+ @property
16
+ def hex(self):
17
+ return self.as_uuid.hex
18
+
19
+
20
+ class SqliteUUID(TypeDecorator):
21
+ """UUID type that stores hyphenated strings on SQLite to avoid numeric coercion."""
22
+
23
+ impl = String(36)
24
+ cache_ok = True
25
+
26
+ def __init__(self, as_uuid: bool = True):
27
+ super().__init__()
28
+ self.as_uuid = as_uuid
29
+
30
+ @property
31
+ def python_type(self) -> type:
32
+ return uuid.UUID if self.as_uuid else str
33
+
34
+ def load_dialect_impl(self, dialect) -> Any:
35
+ if dialect.name == "postgresql":
36
+ return dialect.type_descriptor(PgUUID(as_uuid=self.as_uuid))
37
+ return dialect.type_descriptor(String(36))
38
+
39
+ def process_bind_param(self, value: Any, dialect) -> Any:
40
+ if value is None:
41
+ return None
42
+ if self.as_uuid:
43
+ if not isinstance(value, uuid.UUID):
44
+ value = uuid.UUID(str(value))
45
+ return value if dialect.name == "postgresql" else str(value)
46
+ return str(value)
47
+
48
+ def process_result_value(self, value: Any, dialect) -> Any:
49
+ if value is None:
50
+ return None
51
+ if self.as_uuid:
52
+ if isinstance(value, uuid.UUID):
53
+ return value
54
+ return uuid.UUID(str(value))
55
+ return str(value)
@@ -1,8 +1,10 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: tigrbl
3
- Version: 0.3.0.dev3
3
+ Version: 0.3.1
4
4
  Summary: Automatic API generation tools by Swarmauri.
5
- License: Apache-2.0
5
+ License-Expression: Apache-2.0
6
+ License-File: LICENSE
7
+ Keywords: tigrbl,sdk,standards
6
8
  Author: Swarmauri Team
7
9
  Author-email: team@swarmauri.com
8
10
  Requires-Python: >=3.10,<3.13
@@ -11,8 +13,12 @@ Classifier: Development Status :: 3 - Alpha
11
13
  Classifier: Programming Language :: Python :: 3.10
12
14
  Classifier: Programming Language :: Python :: 3.11
13
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
14
19
  Provides-Extra: postgres
15
20
  Provides-Extra: templates
21
+ Provides-Extra: tests
16
22
  Requires-Dist: aiosqlite (>=0.19.0)
17
23
  Requires-Dist: asyncpg (>=0.30.0) ; extra == "postgres"
18
24
  Requires-Dist: fastapi (>=0.100.0)
@@ -25,10 +31,11 @@ Requires-Dist: sqlalchemy (>=2.0)
25
31
  Requires-Dist: swarmauri_base
26
32
  Requires-Dist: swarmauri_core
27
33
  Requires-Dist: swarmauri_standard
34
+ Requires-Dist: tigrbl-tests ; extra == "tests"
28
35
  Requires-Dist: uvicorn
29
36
  Description-Content-Type: text/markdown
30
37
 
31
- ![Tigrbl Logo](../../../assets/tigrbl_full_logo.png)
38
+ ![Tigrbl Logo](https://github.com/swarmauri/swarmauri-sdk/blob/a170683ecda8ca1c4f912c966d4499649ffb8224/assets/tigrbl.brand.theme.svg)
32
39
 
33
40
  <p align="center">
34
41
  <a href="https://pypi.org/project/tigrbl/">
@@ -48,6 +55,14 @@ Description-Content-Type: text/markdown
48
55
  # Tigrbl 🐅🐂
49
56
  A high-leverage meta-framework that turns plain SQLAlchemy models into a fully-featured REST+RPC surface with near-zero boilerplate. 🚀
50
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
+
51
66
  ## Terminology 📚
52
67
 
53
68
  - **Tenant** 🏢 – a namespace used to group related resources.
@@ -1,17 +1,18 @@
1
1
  tigrbl/README.md,sha256=ed4kzQZJ44MkqbWEcFDFVQC6wbuMY7KkFlWmm4YCEgg,3753
2
2
  tigrbl/__init__.py,sha256=9Sx1PgBOHRcu5mo001oENxKhCuJEEZjpnyISYJjJOrg,4286
3
3
  tigrbl/api/__init__.py,sha256=iU8usWi_Xa5brbyYsFqLV06Ad9vTXFuVsyN7NFyyuY4,137
4
- tigrbl/api/_api.py,sha256=RVVK3qA2SiSxWmJBEc6jT3FEbBxH5u5g0CX7xCzQdi4,2848
4
+ tigrbl/api/_api.py,sha256=dMWJfCC8YVrzY7pzGetm0xxBqC7FGuw_QPFeiH1nKP8,3840
5
5
  tigrbl/api/api_spec.py,sha256=ESSts5TW2pb4a9wU9H6drmKeU7YbZwx_xPaQ54RFuR4,991
6
6
  tigrbl/api/mro_collect.py,sha256=V9U62GsBKDJ0R0N-8f2lVAEpjaO7i74LUcNliwnW-Co,1598
7
7
  tigrbl/api/shortcuts.py,sha256=_Ha6yQilo8siXQrSd3ALiK6IzFmgL_OePqs5gy9bFRs,1454
8
- tigrbl/api/tigrbl_api.py,sha256=qi1bI3tD-ND49u3pPm2AbWbYO7rwBRvO724Afl8iq1E,10466
8
+ tigrbl/api/tigrbl_api.py,sha256=UKSvSLaG7vzmM5r39iyNWUslUMiN6eWZlJtXyW5K4Ak,10704
9
9
  tigrbl/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- tigrbl/app/_app.py,sha256=oVhITLiaDj8MY7AP5kDrCiFiFjxPAIygsM6x-Z0gH3I,2592
10
+ tigrbl/app/_app.py,sha256=bsg58JEbnLpjBJvvjLayHKGZvrYL7434tTiLZhx1jyY,3596
11
+ tigrbl/app/_model_registry.py,sha256=v6UoDd7hmv5J4DpNEV13BOgIKIcKou10w3zyZVPd-po,1506
11
12
  tigrbl/app/app_spec.py,sha256=RzVHibgoIyQQtlQzRtrWDa4pSD7PpWsysgfztJ1tSRY,1474
12
13
  tigrbl/app/mro_collect.py,sha256=JfmkAnUGLgVVaevAjVU9O_8JMyJAYiTXTmrxW4EdPx8,2025
13
14
  tigrbl/app/shortcuts.py,sha256=PEMbmwaqW8a3jkcHM5AXsYA2mmuXGFpOTnqlJnUX9Lo,1775
14
- tigrbl/app/tigrbl_app.py,sha256=o-amxlU6UzolA9v8ZVvcrrRe5LLns1005F6gpkV_yas,11584
15
+ tigrbl/app/tigrbl_app.py,sha256=4WqA509WekXx1BCW7Ph2tqdFEYkzcrHCYJz8MIVjG4w,11817
15
16
  tigrbl/bindings/__init__.py,sha256=GcM5PTKNLS1Jx__OiAcjLI5yybL40RrA8OzMVPno4_U,2643
16
17
  tigrbl/bindings/api/__init__.py,sha256=hqPCVcqQIsfLb_rU-rnK6gUKLVduYc3VujXV8lN0S_c,448
17
18
  tigrbl/bindings/api/common.py,sha256=2U5ig5JmrD3Vsq6SBgDMTSyq66aznNdw4yVqjghutFA,3652
@@ -31,14 +32,15 @@ tigrbl/bindings/model_helpers.py,sha256=3rbt7YFT2ohBGNsd7nfKnnSnHz1nOmeE_xIyAjub
31
32
  tigrbl/bindings/model_registry.py,sha256=ACMOIiQbyLs-89BwSNjY6iAS6xR8_vUdl0OcuT1p7ro,2424
32
33
  tigrbl/bindings/rest/__init__.py,sha256=u3vD4v9bhD8wotjt7e2Wt46pmGOC5BWHo9co9KOYLxQ,193
33
34
  tigrbl/bindings/rest/attach.py,sha256=7fGb1El6ZdCBVn3LvEcyFTNYPPeaEaIGLbyAGzM7ebE,1036
34
- tigrbl/bindings/rest/collection.py,sha256=_On1B3ga-4YZ2vsNNcNVEoPmCamxj9vAn0UIspcL5xU,8759
35
- tigrbl/bindings/rest/common.py,sha256=2iWC6sYW-4xgpXfDpVQxHlMgZLHlQhSFIwUvR9kd-NU,2435
35
+ tigrbl/bindings/rest/collection.py,sha256=GK2xD19SXkDSDeVlDiFmgsmT0zj8ssIYFFf91grfSmE,9680
36
+ tigrbl/bindings/rest/common.py,sha256=K9Kpo3fxj90lcrk8lhGZp-NiInDSv4EqO8Td8VeoimU,2545
36
37
  tigrbl/bindings/rest/fastapi.py,sha256=eUg2Aj5JCBlsMSBsf0GJF9KueZnGYhUeGHQ9N7-UB6Y,2072
37
38
  tigrbl/bindings/rest/helpers.py,sha256=LrYhqokKAqgyXbxDGKIvXkW14xGoBmcSBurr9eyrPHY,3768
38
39
  tigrbl/bindings/rest/io.py,sha256=Sl1nFpAuqv9jqw835YxhdEQ43CJ2XPPA29zeUsBxDsM,11107
39
- tigrbl/bindings/rest/member.py,sha256=829_4kLdAuOhLn5HFhwZjDiWFtDMBC9UULW7TfRaiTU,12306
40
- tigrbl/bindings/rest/router.py,sha256=Vxn4Z97rk2Pyux5W3ngfakaYShVi5gealWqfD1-kYvY,10723
41
- tigrbl/bindings/rest/routing.py,sha256=4TQaJHRCc5Fixo_d05BLbqr8OCUFQpUQv84GwvIHwBM,3767
40
+ tigrbl/bindings/rest/io_headers.py,sha256=ZUqhXfVlQrosnjnIFr5BP1W9fbpGdxafdYB6Dnots8g,1646
41
+ tigrbl/bindings/rest/member.py,sha256=aSuvfBWMpGMx-rYK5Zr3Y2ATTBbBkj4IxaZyN0Yh91Q,13081
42
+ tigrbl/bindings/rest/router.py,sha256=ofkC_uLot5L5wfhyr3Vclzxog-5TjAn4Gd5D5haezRM,10877
43
+ tigrbl/bindings/rest/routing.py,sha256=5Wi3fhgLysEcaHc2dzWk1523NcRZFJpcBiMKr4aaxlo,4440
42
44
  tigrbl/bindings/rpc.py,sha256=TsRNQ2q6LH7Dn8j_fguKimUOXRKUB8gmdOek7bp8Yjo,13196
43
45
  tigrbl/bindings/schemas/__init__.py,sha256=2D5skLUnHvtn0a4zm5AIxj2JHJN7GqFuCOr_hKslCuQ,313
44
46
  tigrbl/bindings/schemas/builder.py,sha256=nOTnaDCqGgptZEyFtAjNqfph2YcTytI7M35B2VJyz4o,13116
@@ -55,7 +57,7 @@ tigrbl/column/infer/jsonhints.py,sha256=IBoNQJUKIIpZdwrYfsKQUA1djHC37XPm8mE-crn1
55
57
  tigrbl/column/infer/planning.py,sha256=-Iuruex37A3z-n7Nw4kI_Y40mXLOoatY_lPnLtEDHyI,4319
56
58
  tigrbl/column/infer/types.py,sha256=EOyPYKQgpmwVxCapiDlxPwVvEmqsXN8AMOpoRyAzpFQ,2683
57
59
  tigrbl/column/infer/utils.py,sha256=J8VcLGA-KXjy3IJ2ROQ1alyfYP9qj8ukb5Z3IMvasi4,1532
58
- tigrbl/column/io_spec.py,sha256=qwXYiVDf2ar5zaF7zoFoLxqbvlXr2cUQEFXXibpgLOU,4079
60
+ tigrbl/column/io_spec.py,sha256=GkMTkzk_2fOIo8XK_0rbYRW-Re9rCuIfPMpR4dvUyJE,4223
59
61
  tigrbl/column/mro_collect.py,sha256=jAmt-trA95xxcs5SOjwA3sxh9J_MAXDlVFSbpTcyla0,2084
60
62
  tigrbl/column/shortcuts.py,sha256=a6ns1Y5zdbgzzKeUDZq86ejV2la_HZVHmLSgWucPxKc,2606
61
63
  tigrbl/column/storage_spec.py,sha256=U19K6QlELQ9tTyxEA5xRWEcjCcIHcb9-iRfDwluPl_8,2396
@@ -82,13 +84,17 @@ tigrbl/deps/jinja.py,sha256=dau8Y2v9UY3sptLhzP_8MpjKwlU-34_QraNgQXr4OCM,698
82
84
  tigrbl/deps/pydantic.py,sha256=cLReo5Gd3V7TDJ9L3sMOFD93FWMd5QnZZoCaOJ6ip14,497
83
85
  tigrbl/deps/sqlalchemy.py,sha256=0gdeq-l-5XgMVpykrSQ-NPA-sojIaVoa1BG_NSjojjQ,2392
84
86
  tigrbl/deps/starlette.py,sha256=I90mc0aLxDymtf0mne2tT03rOLpfS7F9x_bYLVIeJGs,1001
85
- tigrbl/engine/__init__.py,sha256=l6-YpvHC7OzGkqP5jbl70I0okjJSyDrcaWyC5faEOFo,623
86
- tigrbl/engine/_engine.py,sha256=HVTVKpZJyH086cFXBwNsl_-cc9_avMFUI_RyhnwjnqA,4098
87
+ tigrbl/engine/__init__.py,sha256=6Vv8FqSaA1xSKqegmFd2jNM2xeuw6h8rI9cNMn9qj_A,1092
88
+ tigrbl/engine/_engine.py,sha256=MGsYL3FjNzXqBCeLwmmucCvqxqRYBX4cXLCuKQv46_o,4571
87
89
  tigrbl/engine/bind.py,sha256=BsUYNfUCPAp4o0Lvb-_-wmvrRptmucGbzs2Janm2A8Y,1065
88
90
  tigrbl/engine/builders.py,sha256=HN_zDN-aFA3LzAjNKrByWY_LdNhgkbdGVbgjgkxO0Wk,8599
91
+ tigrbl/engine/capabilities.py,sha256=7bj0nPtmi8a-x9wD-eq2gKH_KOs0adwyDl5tc4kVuHE,1099
89
92
  tigrbl/engine/collect.py,sha256=aYJZckPRoEM2P7glpikpcg5tvDDZuOliwxeik-C5KNs,3808
90
- tigrbl/engine/decorators.py,sha256=A1aTBDgQqoY4ZP-8pHcPCqCYAsXLmX3_JZdsAA-Ipfk,3836
91
- tigrbl/engine/engine_spec.py,sha256=eDBRRjRDRKcYyZfSTcH7OuU222RmgPu3j0bIkTtiZdQ,9222
93
+ tigrbl/engine/decorators.py,sha256=xYra9IUF8gR72EsKHfZApPmOWze_lGL_MDXlv5XDfMY,3981
94
+ tigrbl/engine/docs/PLUGINS.md,sha256=jcKf_e8X1c3zZfEWCiGgeblfq5nGXTnu2uvDX_B_RdM,1318
95
+ tigrbl/engine/engine_spec.py,sha256=zVgQSzkwR53Z1cx1VOoHX449BSYe1QE8YnoXZMMqNdA,13047
96
+ tigrbl/engine/plugins.py,sha256=UveqYo9VlDn4Y7xgGvsHi_O1ugd0kBYxIuyFMSDWoug,1497
97
+ tigrbl/engine/registry.py,sha256=MmTe7job1W9k18-g0fx6rZzVU9-D_5fElW9TXo0_HxA,1113
92
98
  tigrbl/engine/resolver.py,sha256=3Ds6WEgFoIYcIDyaHprUKPCZ6CYWW0JLG3iqlSTPNEQ,7664
93
99
  tigrbl/engine/shortcuts.py,sha256=BR_u3wsrkp83vup_jtNUTp5a2LrSLKxFj1vYTVIYsL4,6519
94
100
  tigrbl/hook/__init__.py,sha256=PtUNKKLQ1CAdkxFQgymutDkNzeyeVOfnMq2jQ_fbKIs,448
@@ -123,7 +129,7 @@ tigrbl/orm/mixins/operations.py,sha256=XDeoeF003b2GymFTzj5_olkgzrjrFYfOjPi3jQrYz
123
129
  tigrbl/orm/mixins/ownable.py,sha256=v41-KWrw5dlnLPOPxP7BDerg1Cd3B4iD5sM-ejGGnZ4,11304
124
130
  tigrbl/orm/mixins/principals.py,sha256=YIHsEgAcckQQlNggC5xD3XxApINakqDLt3rMLuk2s7w,2746
125
131
  tigrbl/orm/mixins/tenant_bound.py,sha256=op07P55fTpM94CctF03l2M6Ozkge1xrX1upHN5h_CAs,10095
126
- tigrbl/orm/mixins/upsertable.py,sha256=UtNv7mFZUyrdCQQSrei4_jOFBSVfozuhaEtK171G6T8,3800
132
+ tigrbl/orm/mixins/upsertable.py,sha256=O0Rl2QJQl21j0T0CmYenB5ZoLJ40uUxjEki84CUSsg8,3989
127
133
  tigrbl/orm/mixins/utils.py,sha256=_sTN4CnEkyEeXgTRr_VHsFtG33Mimm1EFoFhpPutGQo,1257
128
134
  tigrbl/orm/tables/__init__.py,sha256=3NtStrO9wE2YulZkrVvhrcKWmkTyfZK2n-J-urA3_JU,1929
129
135
  tigrbl/orm/tables/_base.py,sha256=8z6nAdogoEKpi0gvBelAL7jsRkT_rn_lrqGLCsjrbN0,231
@@ -140,7 +146,7 @@ tigrbl/response/__init__.py,sha256=Y26CVXUlk7zvcP7oorZHxbJ5D0-KC_LcDIxQjw0QlB4,8
140
146
  tigrbl/response/bind.py,sha256=fj5deXrOBn-jauvW0j2yNdVziOBvPOvbOklFQFeoyYk,293
141
147
  tigrbl/response/decorators.py,sha256=iOBBME2jSvuS_KV9zDCQKBQDNg80QLFtYboJehwqvRM,940
142
148
  tigrbl/response/resolver.py,sha256=ZCcQiBxzZuC_iteOQVcQdLBQmY8wSSJ2HYryb2YzzUA,2532
143
- tigrbl/response/shortcuts.py,sha256=xtvfKahPWSWQzyEMAHLPuPFu_129bNg65eZDHQegD_U,3906
149
+ tigrbl/response/shortcuts.py,sha256=nihXsZna0wzAH8ML9xxWyvzDM77ge2pR-JD7k8S8byM,4690
144
150
  tigrbl/response/types.py,sha256=110etKRHl0jnnhwFPCWwl6DawQ7cOel1yq4lo3r9KIk,1329
145
151
  tigrbl/rest/__init__.py,sha256=XmCGc3HdPqRJfzehJj1MfhpJFlheDMMlVSZz1EE2yZQ,824
146
152
  tigrbl/runtime/README.md,sha256=0sCqYWNPcdG6tFA7fVyri2DVbuTsiw3T5WwnTzF-i78,5956
@@ -157,7 +163,8 @@ tigrbl/runtime/atoms/refresh/demand.py,sha256=FCWXiHzehdy1W7YOn2-D3bIXGBFHOZuP4N
157
163
  tigrbl/runtime/atoms/resolve/__init__.py,sha256=xRdUnSxI5k3mUgVbx9VBRyrbJM3uKeHS22R8BWMfhc4,1363
158
164
  tigrbl/runtime/atoms/resolve/assemble.py,sha256=Pzs8Pm_8trAB17saAfezgZUM4IPk4kIMrahZKgFRKac,6301
159
165
  tigrbl/runtime/atoms/resolve/paired_gen.py,sha256=Jj4v5Wg3zfdv3omv-3DG8c93I6ynEbxHhJFza_SE-Mc,5676
160
- tigrbl/runtime/atoms/response/__init__.py,sha256=spdjtuxvJJlKDdslf5G9rBSTr5Do_eAHyr3wQbSWxro,545
166
+ tigrbl/runtime/atoms/response/__init__.py,sha256=9bDiy1eX9TAT7SnRkUOtQEuI_P-MRU1sRiXuPHvIXXY,679
167
+ tigrbl/runtime/atoms/response/headers_from_payload.py,sha256=kuMwkvyQYyX_voFRNIfYqKWb1EqeG5N7HVn_j9co0gw,1705
161
168
  tigrbl/runtime/atoms/response/negotiate.py,sha256=G6QPl_U1Oz8csFpMitSlvzAvUsVLzc-fo-G3eJX2jak,913
162
169
  tigrbl/runtime/atoms/response/negotiation.py,sha256=G2wy6Enr93nuLJVELFdY5W6J14G6gsEvHZi64YSbp-o,1125
163
170
  tigrbl/runtime/atoms/response/render.py,sha256=uo3laUH8d4-9dCP4LevfxeysLCs0UxZDjSJuznHPpsc,970
@@ -186,9 +193,9 @@ tigrbl/runtime/executor/guards.py,sha256=HiE9J_Y-AslRJZYBrjZmGFecq9Tx4nn6HMqL1jr
186
193
  tigrbl/runtime/executor/helpers.py,sha256=PU7Bj7VTdGaldNYuBRsrV4408G4UqxJIWwPUwtUgNaA,2239
187
194
  tigrbl/runtime/executor/invoke.py,sha256=IUSkjXXqRDX1cOmDcpXloKHgwI_HRYW2SsqOrKheB8U,4754
188
195
  tigrbl/runtime/executor/types.py,sha256=oxgyv5EI2hs2MixjXQAdhNu5nWpQ2F0kXC6pXNU_pSE,2386
189
- tigrbl/runtime/kernel.py,sha256=BEaBa_EMl_s9J5KqtzB2KBVr1tM1NAANNUtunLi66dU,22441
196
+ tigrbl/runtime/kernel.py,sha256=cL1bnw2glp33AjiFchMg8MZsJ3lb7c2JPhz26JejP1I,22895
190
197
  tigrbl/runtime/labels.py,sha256=aBXx65lMPlR60wXH4M_xeuXN4w3z07ep6NxICAiSy68,13134
191
- tigrbl/runtime/opview.py,sha256=8Fa-Ycc_cSTTvvo-ZaJ7OpmGbzZObiZ_Yg8BJOJi4oU,2727
198
+ tigrbl/runtime/opview.py,sha256=UHbQbGg5GGi2AWFip8qBUD6fe6h8VNU232GRly1aT-I,2792
192
199
  tigrbl/runtime/ordering.py,sha256=CtV0XCTAoucv1v-opylWJSQP_bDW-_qfU1GqLs9h9_g,9533
193
200
  tigrbl/runtime/system.py,sha256=Kv9xSVNVAfp6pVU_RpRSXJDA-OIUmP9IsFT6FI09aMk,10868
194
201
  tigrbl/runtime/trace.py,sha256=67XPisJg7t5jpXghfYRdJK7hES89Jk_TQUYb2u2cDVk,9865
@@ -202,16 +209,24 @@ tigrbl/schema/builder/extras.py,sha256=t-94VjVULlTDFsRDJ3IBkBUFYkwZbWajjS1JIyTEx
202
209
  tigrbl/schema/builder/helpers.py,sha256=_YfZh1-bgfWrQ912eq77M6nG4XsrNY_qFODtUux1CgQ,1386
203
210
  tigrbl/schema/builder/list_params.py,sha256=DL97zDb271FtzBXk0FTcDzrnrRzeQorkdYNP8kuxsG8,3537
204
211
  tigrbl/schema/builder/strip_parent_fields.py,sha256=i2H3gzbcbhZT0Ddq0Uj9ESN_Bsfc-c54gRzXROtjjiI,2250
205
- tigrbl/schema/collect.py,sha256=4mp8XHyR98x1uBm5mTPNRj7mEJyGDnJ3hJB_PMJkvm0,1864
212
+ tigrbl/schema/collect.py,sha256=JmHAoa5rIc5vsJraI_JF6FA9mV4-Q6FHEPc3ItjOkz0,2772
206
213
  tigrbl/schema/decorators.py,sha256=HISPz7aeTWx9kG8Z5OW0UddY-wXM3ICpdLn98wIUx1w,2171
207
214
  tigrbl/schema/get_schema.py,sha256=_yMadRKoQUA37yMfS98xQpb1jIQeOBelbnUKa_b5GHQ,2572
208
215
  tigrbl/schema/schema_spec.py,sha256=un30EyrHnzXVi5O8Q4yUHzSFrBERhVPHxrMEyxJpYW8,429
209
216
  tigrbl/schema/shortcuts.py,sha256=ExUWm51DBaN99FjO3_A59imzhWV-0QOJIpresWSlUGk,921
210
217
  tigrbl/schema/types.py,sha256=-F7OkmqGE9Dot7DhiLe1_EBq27ei_bLUqP1qJj0KKeQ,803
211
218
  tigrbl/schema/utils.py,sha256=KEAljLM2eWV5nTS-fDod4fTLVOsUVqf2VQ39mwMSV1w,4741
219
+ tigrbl/session/README.md,sha256=KwwLMo080URVFsmVE2QPsda4-nm3LsKIky408zl_C8o,744
220
+ tigrbl/session/__init__.py,sha256=N_5cgpnBWtis1lmTyb1Bkc4eTrSSFYDUA169LEjbbJE,613
221
+ tigrbl/session/abc.py,sha256=gn_4lqwdH-i-4sQeBsQ3C34mS9Ct21aCZpqXiDP6zpw,2311
222
+ tigrbl/session/base.py,sha256=FiRFoVuAQTWRMjFjKcX3eyLyamxCNHncDt24iRu4hG8,4830
223
+ tigrbl/session/decorators.py,sha256=33nyxdUl7PrVcRTsWNmKOMB9Doyooxw84n7R2OrKVSo,1233
224
+ tigrbl/session/default.py,sha256=TJKiC-txQiPE1b_iHcwwMprV88UN-dSUVVfkzk6nIJ8,3859
225
+ tigrbl/session/shortcuts.py,sha256=-gHsO5B-er1ngdbYVibuSUazrfVpi4e2ZVQWxodjEWs,1465
226
+ tigrbl/session/spec.py,sha256=DitJpopj6yjkNXnWsMYIJSK-4S8JLXv7vADoK676jsU,3803
212
227
  tigrbl/shortcuts.py,sha256=wa3AlX4r4IbzAkxANeRsIbFdy_zu0s6xFdTKZsAohyM,712
213
228
  tigrbl/specs.py,sha256=SBGeNuzmyU4t0TyrDQlZg_MElC7B6i--ghGEgSIX3vU,1163
214
- tigrbl/system/__init__.py,sha256=tGe9YztVgMaTFYnt_2MbUDVeqQ7v5N4DgSfeE1OemUY,246
229
+ tigrbl/system/__init__.py,sha256=KzuvZppotGl-tcrwxKkD-mjBRHQyaeZ7AzcBTkI34cs,310
215
230
  tigrbl/system/diagnostics/__init__.py,sha256=QtQfmaE7LreWKH2Zggmh8kIAilzhF1gQYdhNOVAGuCE,717
216
231
  tigrbl/system/diagnostics/compat.py,sha256=g3rzIWKPvspdaDRlwnFzcbsmORfbo1Bjwa1VTrf0Bco,990
217
232
  tigrbl/system/diagnostics/healthz.py,sha256=hB-FX6DUJYOlQGdF-5Skb0bspO8Hi4IEOFg7AxcsrV0,1319
@@ -220,8 +235,9 @@ tigrbl/system/diagnostics/kernelz.py,sha256=MuM7-95yaIu28nZ3KOWYhfbYeb489Ep6ucmR
220
235
  tigrbl/system/diagnostics/methodz.py,sha256=rZ9QpNJMxH_gH-zkSv6vK-qw3ZLRLEImP32Ki-JmyC4,1577
221
236
  tigrbl/system/diagnostics/router.py,sha256=5RAv6LPoN4luGwIPnYGak66uT9FslYPc-d_GKqc4S8c,1854
222
237
  tigrbl/system/diagnostics/utils.py,sha256=qxC8pUNK2lQKh5cGlF-PSFA-cfJFLlAHW0-iEosvPgg,1172
238
+ tigrbl/system/uvicorn.py,sha256=ogvIqfv-1CxAPZ8BADucaNAy_ePsLA3IVIZxmhdfL3A,1526
223
239
  tigrbl/table/__init__.py,sha256=yyP9iZBUJh-D7TCy9WQIvMXKL3ztyX-EXdTK4RTE7iw,207
224
- tigrbl/table/_base.py,sha256=TLov-nRcvg-qiAyYflP_6o5PNeIvixNrDE_eRrEULxo,8790
240
+ tigrbl/table/_base.py,sha256=OpZHeV2dQtWd8yom2wntmHBV5QwWcCUJITIoDOJGBoA,9938
225
241
  tigrbl/table/_table.py,sha256=B7ft2SMnbp3aTWKO44M4EWTHmzFKyQlpdj-3QULRaGk,1740
226
242
  tigrbl/table/mro_collect.py,sha256=JwL0zAeLNUgJcgd2JuLKcbFc806zBguhFqpCkeZyzRw,2027
227
243
  tigrbl/table/shortcuts.py,sha256=-IZAZyMTsiCdKV0w7nq1C2YBsB6iE_uNGJb-PatlO8I,1716
@@ -233,7 +249,7 @@ tigrbl/transport/jsonrpc/helpers.py,sha256=oyqx36m8n7EofciPVvTEM9Pz1l51zJwsI224A
233
249
  tigrbl/transport/jsonrpc/models.py,sha256=omtjb-NN8HyWgIZ5tHafEsbwC7f1XlttAFHFA41Xn2k,973
234
250
  tigrbl/transport/rest/__init__.py,sha256=AU_twrP0A958FtXvLSf1i60Jn-UZSRUkAZ1Gd2TeYaw,764
235
251
  tigrbl/transport/rest/aggregator.py,sha256=V1zDvv1bwpNyt6rUPmEUEV5nORjb5sHU5LJ00m1ybYY,4454
236
- tigrbl/types/__init__.py,sha256=P1xW-fVGrbSfScKZUMZ6nVKIUdIUndEkecAsbbOEKhU,4153
252
+ tigrbl/types/__init__.py,sha256=JwQCoSrk3-aPtlfd9dLXO1YAPuLc_CPUa6Uye8frFBg,4119
237
253
  tigrbl/types/allow_anon_provider.py,sha256=5mWvSfk_eCY_o6oMm1gSEqz6cKyJyoZ1-DcVYm0KmpA,565
238
254
  tigrbl/types/authn_abc.py,sha256=GtlXkMb59GEEXNEfeRX_ZfNzu-S4hcLsESzBAaPT2Fg,769
239
255
  tigrbl/types/nested_path_provider.py,sha256=1z-4Skz_X_hy-XGEAQnNv6vyrfFNsPIvlhBqf457Sjc,609
@@ -243,7 +259,8 @@ tigrbl/types/op_verb_alias_provider.py,sha256=_8Ix5bsD0PNKBsnn7k7KtO0JHmTSrm4Xlv
243
259
  tigrbl/types/request_extras_provider.py,sha256=JOIpzx1PYA2AYYvkMiXrxlwpBLOPD2cQaPvaA0lzQck,646
244
260
  tigrbl/types/response_extras_provider.py,sha256=sFB0R3vyUqmpT-o8983hH9FAlOq6-wwNVK6vfuCPHCg,653
245
261
  tigrbl/types/table_config_provider.py,sha256=EkfOhy9UDfy7EgiZddw9KIl5tRujRjXJlr4cSk1Rm5k,361
246
- tigrbl-0.3.0.dev3.dist-info/LICENSE,sha256=djUXOlCxLVszShEpZXshZ7v33G-2qIC_j9KXpWKZSzQ,11359
247
- tigrbl-0.3.0.dev3.dist-info/METADATA,sha256=nZp7ZM_2RHObTozW_arwqb7yNrFLPTer-CPJVyJcNUE,17194
248
- tigrbl-0.3.0.dev3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
249
- tigrbl-0.3.0.dev3.dist-info/RECORD,,
262
+ tigrbl/types/uuid.py,sha256=pD-JrhS0L2GXeJ0Hv_oKzRuiXmxHDTVoMqExO48iqZE,1993
263
+ tigrbl-0.3.1.dist-info/METADATA,sha256=hQLW4W1KzwgBkvTZ0cLSbVRTRC5pvcRtDhfPF1dsd_g,17848
264
+ tigrbl-0.3.1.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
265
+ tigrbl-0.3.1.dist-info/licenses/LICENSE,sha256=djUXOlCxLVszShEpZXshZ7v33G-2qIC_j9KXpWKZSzQ,11359
266
+ tigrbl-0.3.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.3
2
+ Generator: poetry-core 2.3.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any