tigrbl 0.3.9.dev1__tar.gz → 0.3.10.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 (313) hide show
  1. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/PKG-INFO +1 -1
  2. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/pyproject.toml +1 -1
  3. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/_api.py +6 -0
  4. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/_router.py +5 -3
  5. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/tigrbl_api.py +18 -3
  6. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/app/tigrbl_app.py +91 -14
  7. tigrbl-0.3.9.dev1/tigrbl/transport/asgi_wsgi.py → tigrbl-0.3.10.dev1/tigrbl/app/transport.py +8 -86
  8. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/middlewares/__init__.py +2 -0
  9. tigrbl-0.3.10.dev1/tigrbl/middlewares/base.py +142 -0
  10. tigrbl-0.3.10.dev1/tigrbl/middlewares/cors.py +138 -0
  11. tigrbl-0.3.10.dev1/tigrbl/requests/adapters.py +68 -0
  12. tigrbl-0.3.10.dev1/tigrbl/responses/_transport.py +32 -0
  13. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/__init__.py +30 -9
  14. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/__init__.py +21 -0
  15. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/swagger.py +5 -0
  16. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/__init__.py +1 -5
  17. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/jsonrpc/dispatcher.py +0 -3
  18. tigrbl-0.3.9.dev1/tigrbl/middlewares/cors.py +0 -123
  19. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/LICENSE +0 -0
  20. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/README.md +0 -0
  21. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/README.md +0 -0
  22. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/__init__.py +0 -0
  23. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/__init__.py +0 -0
  24. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/_route.py +0 -0
  25. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/_routing.py +0 -0
  26. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/api_spec.py +0 -0
  27. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/mro_collect.py +0 -0
  28. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/resolve.py +0 -0
  29. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/api/shortcuts.py +0 -0
  30. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/app/__init__.py +0 -0
  31. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/app/_app.py +0 -0
  32. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/app/_model_registry.py +0 -0
  33. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/app/_routing_runtime.py +0 -0
  34. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/app/app_spec.py +0 -0
  35. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/app/mro_collect.py +0 -0
  36. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/app/shortcuts.py +0 -0
  37. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/__init__.py +0 -0
  38. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/api/__init__.py +0 -0
  39. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/api/common.py +0 -0
  40. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/api/include.py +0 -0
  41. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/api/resource_proxy.py +0 -0
  42. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/api/rpc.py +0 -0
  43. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/columns.py +0 -0
  44. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/handlers/__init__.py +0 -0
  45. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/handlers/builder.py +0 -0
  46. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/handlers/ctx.py +0 -0
  47. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/handlers/identifiers.py +0 -0
  48. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/handlers/namespaces.py +0 -0
  49. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/handlers/steps.py +0 -0
  50. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/hooks.py +0 -0
  51. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/model.py +0 -0
  52. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/model_helpers.py +0 -0
  53. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/model_registry.py +0 -0
  54. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/__init__.py +0 -0
  55. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/attach.py +0 -0
  56. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/collection.py +0 -0
  57. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/common.py +0 -0
  58. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/fastapi.py +0 -0
  59. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/helpers.py +0 -0
  60. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/io.py +0 -0
  61. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/io_headers.py +0 -0
  62. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/member.py +0 -0
  63. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/router.py +0 -0
  64. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rest/routing.py +0 -0
  65. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/rpc.py +0 -0
  66. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/schemas/__init__.py +0 -0
  67. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/schemas/builder.py +0 -0
  68. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/schemas/defaults.py +0 -0
  69. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/bindings/schemas/utils.py +0 -0
  70. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/README.md +0 -0
  71. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/__init__.py +0 -0
  72. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/_column.py +0 -0
  73. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/column_spec.py +0 -0
  74. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/field_spec.py +0 -0
  75. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/infer/__init__.py +0 -0
  76. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/infer/core.py +0 -0
  77. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/infer/jsonhints.py +0 -0
  78. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/infer/planning.py +0 -0
  79. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/infer/types.py +0 -0
  80. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/infer/utils.py +0 -0
  81. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/io_spec.py +0 -0
  82. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/mro_collect.py +0 -0
  83. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/shortcuts.py +0 -0
  84. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/column/storage_spec.py +0 -0
  85. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/config/__init__.py +0 -0
  86. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/config/constants.py +0 -0
  87. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/config/defaults.py +0 -0
  88. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/config/resolver.py +0 -0
  89. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/__init__.py +0 -0
  90. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/__init__.py +0 -0
  91. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/bulk.py +0 -0
  92. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/helpers/__init__.py +0 -0
  93. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/helpers/db.py +0 -0
  94. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/helpers/enum.py +0 -0
  95. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/helpers/filters.py +0 -0
  96. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/helpers/model.py +0 -0
  97. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/helpers/normalize.py +0 -0
  98. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/ops.py +0 -0
  99. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/crud/params.py +0 -0
  100. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/resolver.py +0 -0
  101. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/core/router_runtime.py +0 -0
  102. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/ddl/__init__.py +0 -0
  103. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/decorators.py +0 -0
  104. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/deps/__init__.py +0 -0
  105. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/deps/jinja.py +0 -0
  106. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/deps/pydantic.py +0 -0
  107. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/deps/sqlalchemy.py +0 -0
  108. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/docs/verbosity.md +0 -0
  109. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/__init__.py +0 -0
  110. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/_engine.py +0 -0
  111. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/bind.py +0 -0
  112. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/builders.py +0 -0
  113. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/capabilities.py +0 -0
  114. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/collect.py +0 -0
  115. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/decorators.py +0 -0
  116. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/docs/PLUGINS.md +0 -0
  117. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/engine_spec.py +0 -0
  118. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/plugins.py +0 -0
  119. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/registry.py +0 -0
  120. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/resolver.py +0 -0
  121. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/engine/shortcuts.py +0 -0
  122. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/headers/__init__.py +0 -0
  123. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/headers/_header.py +0 -0
  124. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/hook/__init__.py +0 -0
  125. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/hook/_hook.py +0 -0
  126. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/hook/decorators.py +0 -0
  127. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/hook/exceptions.py +0 -0
  128. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/hook/hook_spec.py +0 -0
  129. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/hook/mro_collect.py +0 -0
  130. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/hook/shortcuts.py +0 -0
  131. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/hook/types.py +0 -0
  132. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/middlewares/compose.py +0 -0
  133. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/middlewares/decorators.py +0 -0
  134. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/middlewares/middleware.py +0 -0
  135. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/middlewares/spec.py +0 -0
  136. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/__init__.py +0 -0
  137. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/_op.py +0 -0
  138. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/canonical.py +0 -0
  139. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/collect.py +0 -0
  140. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/decorators.py +0 -0
  141. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/model_registry.py +0 -0
  142. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/mro_collect.py +0 -0
  143. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/resolver.py +0 -0
  144. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/op/types.py +0 -0
  145. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/__init__.py +0 -0
  146. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/_RowBound.py +0 -0
  147. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/__init__.py +0 -0
  148. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/bootstrappable.py +0 -0
  149. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/bound.py +0 -0
  150. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/edges.py +0 -0
  151. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/fields.py +0 -0
  152. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/hierarchy.py +0 -0
  153. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/key_digest.py +0 -0
  154. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/lifecycle.py +0 -0
  155. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/locks.py +0 -0
  156. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/markers.py +0 -0
  157. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/operations.py +0 -0
  158. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/ownable.py +0 -0
  159. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/principals.py +0 -0
  160. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/tenant_bound.py +0 -0
  161. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/upsertable.py +0 -0
  162. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/mixins/utils.py +0 -0
  163. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/__init__.py +0 -0
  164. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/_base.py +0 -0
  165. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/audit.py +0 -0
  166. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/client.py +0 -0
  167. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/group.py +0 -0
  168. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/org.py +0 -0
  169. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/rbac.py +0 -0
  170. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/status.py +0 -0
  171. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/tenant.py +0 -0
  172. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/orm/tables/user.py +0 -0
  173. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/requests/__init__.py +0 -0
  174. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/requests/_request.py +0 -0
  175. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/responses/README.md +0 -0
  176. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/responses/__init__.py +0 -0
  177. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/responses/_response.py +0 -0
  178. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/responses/bind.py +0 -0
  179. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/responses/decorators.py +0 -0
  180. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/responses/resolver.py +0 -0
  181. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/responses/shortcuts.py +0 -0
  182. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/responses/types.py +0 -0
  183. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/rest/__init__.py +0 -0
  184. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/README.md +0 -0
  185. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/__init__.py +0 -0
  186. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/__init__.py +0 -0
  187. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/emit/__init__.py +0 -0
  188. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/emit/paired_post.py +0 -0
  189. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/emit/paired_pre.py +0 -0
  190. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/emit/readtime_alias.py +0 -0
  191. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/out/__init__.py +0 -0
  192. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/out/masking.py +0 -0
  193. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/refresh/__init__.py +0 -0
  194. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/refresh/demand.py +0 -0
  195. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/resolve/__init__.py +0 -0
  196. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/resolve/assemble.py +0 -0
  197. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/resolve/paired_gen.py +0 -0
  198. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/response/__init__.py +0 -0
  199. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/response/headers_from_payload.py +0 -0
  200. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/response/negotiate.py +0 -0
  201. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/response/negotiation.py +0 -0
  202. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/response/render.py +0 -0
  203. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/response/renderer.py +0 -0
  204. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/response/template.py +0 -0
  205. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/response/templates.py +0 -0
  206. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/schema/__init__.py +0 -0
  207. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/schema/collect_in.py +0 -0
  208. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/schema/collect_out.py +0 -0
  209. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/storage/__init__.py +0 -0
  210. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/storage/to_stored.py +0 -0
  211. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/wire/__init__.py +0 -0
  212. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/wire/build_in.py +0 -0
  213. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/wire/build_out.py +0 -0
  214. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/wire/dump.py +0 -0
  215. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/atoms/wire/validate_in.py +0 -0
  216. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/context.py +0 -0
  217. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/events.py +0 -0
  218. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/executor/__init__.py +0 -0
  219. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/executor/guards.py +0 -0
  220. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/executor/helpers.py +0 -0
  221. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/executor/invoke.py +0 -0
  222. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/executor/types.py +0 -0
  223. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/kernel.py +0 -0
  224. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/labels.py +0 -0
  225. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/opview.py +0 -0
  226. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/ordering.py +0 -0
  227. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/status/__init__.py +0 -0
  228. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/status/converters.py +0 -0
  229. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/status/exceptions.py +0 -0
  230. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/status/mappings.py +0 -0
  231. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/status/utils.py +0 -0
  232. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/system.py +0 -0
  233. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/runtime/trace.py +0 -0
  234. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/__init__.py +0 -0
  235. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/_schema.py +0 -0
  236. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/builder/__init__.py +0 -0
  237. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/builder/build_schema.py +0 -0
  238. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/builder/cache.py +0 -0
  239. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/builder/compat.py +0 -0
  240. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/builder/extras.py +0 -0
  241. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/builder/helpers.py +0 -0
  242. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/builder/list_params.py +0 -0
  243. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/builder/strip_parent_fields.py +0 -0
  244. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/collect.py +0 -0
  245. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/decorators.py +0 -0
  246. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/get_schema.py +0 -0
  247. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/schema_spec.py +0 -0
  248. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/shortcuts.py +0 -0
  249. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/types.py +0 -0
  250. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/schema/utils.py +0 -0
  251. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/__init__.py +0 -0
  252. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/dependencies.py +0 -0
  253. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/schemes/__init__.py +0 -0
  254. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/schemes/_base.py +0 -0
  255. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/schemes/api_key.py +0 -0
  256. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/schemes/http_bearer.py +0 -0
  257. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/schemes/mutual_tls.py +0 -0
  258. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/schemes/oauth2.py +0 -0
  259. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/security/schemes/openid_connect.py +0 -0
  260. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/session/README.md +0 -0
  261. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/session/__init__.py +0 -0
  262. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/session/abc.py +0 -0
  263. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/session/base.py +0 -0
  264. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/session/decorators.py +0 -0
  265. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/session/default.py +0 -0
  266. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/session/shortcuts.py +0 -0
  267. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/session/spec.py +0 -0
  268. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/shortcuts.py +0 -0
  269. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/specs.py +0 -0
  270. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/diagnostics/__init__.py +0 -0
  271. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/diagnostics/compat.py +0 -0
  272. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/diagnostics/healthz.py +0 -0
  273. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/diagnostics/hookz.py +0 -0
  274. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/diagnostics/kernelz.py +0 -0
  275. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/diagnostics/methodz.py +0 -0
  276. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/diagnostics/router.py +0 -0
  277. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/diagnostics/utils.py +0 -0
  278. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/lens.py +0 -0
  279. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/openapi/__init__.py +0 -0
  280. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/openapi/helpers.py +0 -0
  281. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/openapi/metadata.py +0 -0
  282. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/openapi/mount.py +0 -0
  283. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/openapi/schema.py +0 -0
  284. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/docs/openrpc.py +0 -0
  285. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/favicon/__init__.py +0 -0
  286. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/favicon/assets/favicon.svg +0 -0
  287. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/system/uvicorn.py +0 -0
  288. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/table/__init__.py +0 -0
  289. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/table/_base.py +0 -0
  290. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/table/_table.py +0 -0
  291. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/table/mro_collect.py +0 -0
  292. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/table/shortcuts.py +0 -0
  293. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/table/table_spec.py +0 -0
  294. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/background.py +0 -0
  295. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/httpx.py +0 -0
  296. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/jsonrpc/__init__.py +0 -0
  297. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/jsonrpc/helpers.py +0 -0
  298. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/jsonrpc/models.py +0 -0
  299. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/jsonrpc/openrpc.py +0 -0
  300. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/rest/__init__.py +0 -0
  301. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/rest/aggregator.py +0 -0
  302. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/transport/rest/decorators.py +0 -0
  303. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/__init__.py +0 -0
  304. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/allow_anon_provider.py +0 -0
  305. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/authn_abc.py +0 -0
  306. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/nested_path_provider.py +0 -0
  307. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/op.py +0 -0
  308. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/op_config_provider.py +0 -0
  309. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/op_verb_alias_provider.py +0 -0
  310. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/request_extras_provider.py +0 -0
  311. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/response_extras_provider.py +0 -0
  312. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/table_config_provider.py +0 -0
  313. {tigrbl-0.3.9.dev1 → tigrbl-0.3.10.dev1}/tigrbl/types/uuid.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tigrbl
3
- Version: 0.3.9.dev1
3
+ Version: 0.3.10.dev1
4
4
  Summary: A modern pure ASGI/WSGI Python framework for building schema-first REST and JSON-RPC APIs with SQLAlchemy models, typed validation, lifecycle hooks, and engine extension support.
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tigrbl"
3
- version = "0.3.9.dev1"
3
+ version = "0.3.10.dev1"
4
4
  description = "A modern pure ASGI/WSGI Python framework for building schema-first REST and JSON-RPC APIs with SQLAlchemy models, typed validation, lifecycle hooks, and engine extension support."
5
5
  license = "Apache-2.0"
6
6
  readme = "README.md"
@@ -18,6 +18,9 @@ class Api(APISpec, Router):
18
18
 
19
19
  MODELS: tuple[Any, ...] = ()
20
20
  TABLES: tuple[Any, ...] = ()
21
+ REST_PREFIX = "/api"
22
+ RPC_PREFIX = "/rpc"
23
+ SYSTEM_PREFIX = "/system"
21
24
 
22
25
  # dataclass inheritance makes instances unhashable; use identity semantics
23
26
  # for both hashing and equality so objects can participate in sets/dicts
@@ -48,6 +51,9 @@ class Api(APISpec, Router):
48
51
  self.security_deps = tuple(getattr(self, "SECURITY_DEPS", ()))
49
52
  self.deps = tuple(getattr(self, "DEPS", ()))
50
53
  self.response = getattr(self, "RESPONSE", None)
54
+ self.rest_prefix = getattr(self, "REST_PREFIX", "/api")
55
+ self.rpc_prefix = getattr(self, "RPC_PREFIX", "/rpc")
56
+ self.system_prefix = getattr(self, "SYSTEM_PREFIX", "/system")
51
57
  # ``models`` is expected to be a dict at runtime for registry lookups.
52
58
  self.models = initialize_model_registry(getattr(self, "MODELS", ()))
53
59
 
@@ -25,13 +25,15 @@ from tigrbl.core.router_runtime import (
25
25
  dispatch,
26
26
  is_metadata_route,
27
27
  )
28
- from tigrbl.transport.asgi_wsgi import (
28
+ from tigrbl.app.transport import (
29
29
  asgi_app as _asgi_app_impl,
30
- request_from_asgi as _request_from_asgi_impl,
31
- request_from_wsgi as _request_from_wsgi_impl,
32
30
  router_call as _router_call_impl,
33
31
  wsgi_app as _wsgi_app_impl,
34
32
  )
33
+ from tigrbl.requests.adapters import (
34
+ request_from_asgi as _request_from_asgi_impl,
35
+ request_from_wsgi as _request_from_wsgi_impl,
36
+ )
35
37
  from tigrbl.transport.httpx import ensure_httpx_sync_transport
36
38
 
37
39
  from ._route import Route
@@ -52,6 +52,9 @@ class TigrblApi(_Api):
52
52
  """
53
53
 
54
54
  PREFIX = ""
55
+ REST_PREFIX = "/api"
56
+ RPC_PREFIX = "/rpc"
57
+ SYSTEM_PREFIX = "/system"
55
58
  TAGS: Sequence[Any] = ()
56
59
  APIS: Sequence[Any] = ()
57
60
  MODELS: Sequence[Any] = ()
@@ -84,13 +87,14 @@ class TigrblApi(_Api):
84
87
  self.jsonrpc_prefix = (
85
88
  jsonrpc_prefix
86
89
  if jsonrpc_prefix is not None
87
- else getattr(self, "JSONRPC_PREFIX", "/rpc")
90
+ else getattr(self, "RPC_PREFIX", getattr(self, "JSONRPC_PREFIX", "/rpc"))
88
91
  )
89
92
  self.system_prefix = (
90
93
  system_prefix
91
94
  if system_prefix is not None
92
95
  else getattr(self, "SYSTEM_PREFIX", "/system")
93
96
  )
97
+ self.rest_prefix = getattr(self, "REST_PREFIX", "/api")
94
98
 
95
99
  # public containers (mirrors used by bindings.api)
96
100
  self.models = initialize_model_registry(getattr(self, "MODELS", ()))
@@ -106,6 +110,9 @@ class TigrblApi(_Api):
106
110
  self.core = SimpleNamespace()
107
111
  self.core_raw = SimpleNamespace()
108
112
 
113
+ # Auto-mount canonical API surfaces for standalone usage.
114
+ self.mount_jsonrpc()
115
+
109
116
  # API-level hooks map (merged into each model at include-time; precedence handled in bindings.hooks)
110
117
  self._api_hooks_map = copy.deepcopy(api_hooks) if api_hooks else None
111
118
  if models:
@@ -158,9 +165,12 @@ class TigrblApi(_Api):
158
165
  """
159
166
  # inject API-level hooks so the binder merges them
160
167
  self._merge_api_hooks_into_model(model, self._api_hooks_map)
161
- return _include_model(
168
+ included_model, router = _include_model(
162
169
  self, model, app=None, prefix=prefix, mount_router=mount_router
163
170
  )
171
+ if mount_router and prefix is None and router is not None:
172
+ self.include_router(router, prefix=self.rest_prefix)
173
+ return included_model, router
164
174
 
165
175
  def include_models(
166
176
  self,
@@ -171,13 +181,18 @@ class TigrblApi(_Api):
171
181
  ) -> Dict[str, Any]:
172
182
  for m in models:
173
183
  self._merge_api_hooks_into_model(m, self._api_hooks_map)
174
- return _include_models(
184
+ included = _include_models(
175
185
  self,
176
186
  models,
177
187
  app=None,
178
188
  base_prefix=base_prefix,
179
189
  mount_router=mount_router,
180
190
  )
191
+ if mount_router and base_prefix is None:
192
+ for router in included.values():
193
+ if router is not None:
194
+ self.include_router(router, prefix=self.rest_prefix)
195
+ return included
181
196
 
182
197
  async def rpc_call(
183
198
  self,
@@ -18,12 +18,11 @@ from typing import (
18
18
  )
19
19
 
20
20
  from ._app import App as _App
21
+ from ..api.tigrbl_api import TigrblApi
21
22
  from ..engine.engine_spec import EngineCfg
22
23
  from ..engine import resolver as _resolver
23
24
  from ..ddl import initialize as _ddl_initialize
24
25
  from ..bindings.api import (
25
- include_model as _include_model,
26
- include_models as _include_models,
27
26
  rpc_call as _rpc_call,
28
27
  _seed_security_and_deps,
29
28
  _mount_router,
@@ -127,6 +126,7 @@ class TigrblApp(_App):
127
126
  self.schemas = SimpleNamespace()
128
127
  self.handlers = SimpleNamespace()
129
128
  self.hooks = tuple(getattr(self, "HOOKS", ()))
129
+ self.state = SimpleNamespace()
130
130
  self.rpc = SimpleNamespace()
131
131
  self.rest = SimpleNamespace()
132
132
  self.routers: Dict[str, Any] = {}
@@ -143,6 +143,9 @@ class TigrblApp(_App):
143
143
 
144
144
  # API-level hooks map (merged into each model at include-time; precedence handled in bindings.hooks)
145
145
  self._api_hooks_map = copy.deepcopy(api_hooks) if api_hooks else None
146
+ self._default_api: TigrblApi | None = None
147
+ self.mount_openrpc(path="/openrpc.json")
148
+ self.mount_lens(path="/rdocs", spec_path="/openrpc.json")
146
149
  if apis:
147
150
  self.apis.extend(list(apis))
148
151
  self.include_apis(self.apis)
@@ -233,17 +236,47 @@ class TigrblApp(_App):
233
236
 
234
237
  # ------------------------- primary operations -------------------------
235
238
 
239
+ def _ensure_default_api(self) -> TigrblApi:
240
+ """Create and register the app-scoped default API when needed."""
241
+ if self._default_api is None:
242
+ self._default_api = TigrblApi(
243
+ engine=self.engine,
244
+ api_hooks=self._api_hooks_map,
245
+ )
246
+ # Mirror current app auth knobs onto the default API.
247
+ self._default_api.set_auth(
248
+ authn=self._authn,
249
+ allow_anon=self._allow_anon,
250
+ authorize=self._authorize,
251
+ optional_authn_dep=self._optional_authn_dep,
252
+ )
253
+ self.include_api(self._default_api)
254
+ return self._default_api
255
+
236
256
  def include_model(
237
257
  self, model: type, *, prefix: str | None = None, mount_router: bool = True
238
258
  ) -> Tuple[type, Any]:
239
259
  """
240
- Bind a model, mount its REST router, and attach all namespaces to this facade.
260
+ Include a model through an internal ``TigrblApi`` mounted on this app.
241
261
  """
242
- if not isinstance(self.hooks, SimpleNamespace):
243
- self.hooks = SimpleNamespace()
244
- # inject API-level hooks so the binder merges them
245
- self._merge_api_hooks_into_model(model, self._api_hooks_map)
246
- return _include_model(self, model, prefix=prefix, mount_router=mount_router)
262
+ default_api = self._ensure_default_api()
263
+
264
+ result = default_api.include_model(
265
+ model,
266
+ prefix=prefix,
267
+ mount_router=mount_router,
268
+ )
269
+ if mount_router:
270
+ _, router = result
271
+ if router is not None:
272
+ mount_prefix = prefix if prefix is not None else _default_prefix(model)
273
+ self.include_router(router, prefix=mount_prefix)
274
+ self.include_router(
275
+ router,
276
+ prefix=f"{default_api.rest_prefix}{mount_prefix}",
277
+ )
278
+ self._sync_default_api_namespaces()
279
+ return result
247
280
 
248
281
  def include_models(
249
282
  self,
@@ -252,16 +285,51 @@ class TigrblApp(_App):
252
285
  base_prefix: str | None = None,
253
286
  mount_router: bool = True,
254
287
  ) -> Dict[str, Any]:
255
- if not isinstance(self.hooks, SimpleNamespace):
256
- self.hooks = SimpleNamespace()
257
- for m in models:
258
- self._merge_api_hooks_into_model(m, self._api_hooks_map)
259
- return _include_models(
260
- self,
288
+ default_api = self._ensure_default_api()
289
+
290
+ result = default_api.include_models(
261
291
  models,
262
292
  base_prefix=base_prefix,
263
293
  mount_router=mount_router,
264
294
  )
295
+ if mount_router:
296
+ for model in models:
297
+ router = getattr(
298
+ getattr(model, "rest", SimpleNamespace()),
299
+ "router",
300
+ None,
301
+ )
302
+ if router is None:
303
+ continue
304
+ mount_prefix = (
305
+ f"{base_prefix}{_default_prefix(model)}"
306
+ if base_prefix is not None
307
+ else _default_prefix(model)
308
+ )
309
+ self.include_router(router, prefix=mount_prefix)
310
+ self.include_router(
311
+ router,
312
+ prefix=f"{default_api.rest_prefix}{mount_prefix}",
313
+ )
314
+ self._sync_default_api_namespaces()
315
+ return result
316
+
317
+ def _sync_default_api_namespaces(self) -> None:
318
+ """Mirror the auto-created API registries onto the app facade."""
319
+ if self._default_api is None:
320
+ return
321
+ self.models = self._default_api.models
322
+ self.schemas = self._default_api.schemas
323
+ self.handlers = self._default_api.handlers
324
+ self.hooks = self._default_api.hooks
325
+ self.rpc = self._default_api.rpc
326
+ self.rest = self._default_api.rest
327
+ self.routers = self._default_api.routers
328
+ self.tables = self._default_api.tables
329
+ self.columns = self._default_api.columns
330
+ self.table_config = self._default_api.table_config
331
+ self.core = self._default_api.core
332
+ self.core_raw = self._default_api.core_raw
265
333
 
266
334
  def include_api(
267
335
  self,
@@ -479,6 +547,15 @@ class TigrblApp(_App):
479
547
  if optional_authn_dep is not None:
480
548
  self._optional_authn_dep = optional_authn_dep
481
549
 
550
+ if self._default_api is not None:
551
+ self._default_api.set_auth(
552
+ authn=self._authn,
553
+ allow_anon=self._allow_anon,
554
+ authorize=self._authorize,
555
+ optional_authn_dep=self._optional_authn_dep,
556
+ )
557
+ self._sync_default_api_namespaces()
558
+
482
559
  # Refresh already-included models so routers pick up new auth settings
483
560
  if self.models:
484
561
  self._refresh_security()
@@ -1,39 +1,15 @@
1
- """ASGI and WSGI runtime adapters for stdapi routers."""
1
+ """ASGI/WSGI application adapters for router instances."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import traceback
7
7
  from typing import Any, Callable
8
- from urllib.parse import parse_qs
9
8
 
10
9
  from tigrbl.middlewares import apply_middlewares
11
- from tigrbl.requests import Request
10
+ from tigrbl.requests.adapters import request_from_asgi, request_from_wsgi
12
11
  from tigrbl.responses import Response
13
-
14
-
15
- NO_BODY_STATUS = set(range(100, 200)) | {204, 205, 304}
16
-
17
-
18
- def _finalize_response(
19
- scope: dict[str, Any],
20
- status: int,
21
- headers: list[tuple[bytes, bytes]],
22
- body: bytes,
23
- ) -> tuple[list[tuple[bytes, bytes]], bytes]:
24
- """Enforce HTTP body/header invariants immediately before transport writes."""
25
-
26
- method = str(scope.get("method", "GET")).upper()
27
-
28
- if method == "HEAD" or status in NO_BODY_STATUS:
29
- drop = {b"content-length", b"content-type", b"transfer-encoding"}
30
- headers = [(k, v) for (k, v) in headers if k.lower() not in drop]
31
- return headers, b""
32
-
33
- headers = [(k, v) for (k, v) in headers if k.lower() != b"content-length"]
34
- headers.append((b"content-length", str(len(body)).encode("latin-1")))
35
-
36
- return headers, body
12
+ from tigrbl.responses._transport import finalize_transport_response
37
13
 
38
14
 
39
15
  async def asgi_app(
@@ -107,7 +83,7 @@ async def asgi_app(
107
83
 
108
84
  req = request_from_asgi(router, scope, body)
109
85
  resp = await router._dispatch(req)
110
- headers, finalized_body = _finalize_response(
86
+ headers, finalized_body = finalize_transport_response(
111
87
  scope,
112
88
  resp.status_code,
113
89
  [(k.encode("latin-1"), v.encode("latin-1")) for k, v in resp.headers],
@@ -142,7 +118,7 @@ def wsgi_app(
142
118
  ) -> list[bytes]:
143
119
  req = request_from_wsgi(router, _environ)
144
120
  resp = asyncio.run(router._dispatch(req))
145
- headers, finalized_body = _finalize_response(
121
+ headers, finalized_body = finalize_transport_response(
146
122
  {"method": req.method},
147
123
  resp.status_code,
148
124
  [(k.encode("latin-1"), v.encode("latin-1")) for k, v in resp.headers],
@@ -169,63 +145,6 @@ def wsgi_app(
169
145
  return [resp.body]
170
146
 
171
147
 
172
- def request_from_wsgi(router: Any, environ: dict[str, Any]) -> Request:
173
- method = (environ.get("REQUEST_METHOD") or "GET").upper()
174
- path = environ.get("PATH_INFO") or "/"
175
- script_name = environ.get("SCRIPT_NAME") or ""
176
-
177
- headers: dict[str, str] = {}
178
- for key, value in environ.items():
179
- if key.startswith("HTTP_"):
180
- header_key = key[5:].replace("_", "-").lower()
181
- headers[header_key] = str(value)
182
- if "CONTENT_TYPE" in environ:
183
- headers["content-type"] = str(environ["CONTENT_TYPE"])
184
-
185
- query = parse_qs(environ.get("QUERY_STRING") or "", keep_blank_values=True)
186
-
187
- try:
188
- length = int(environ.get("CONTENT_LENGTH") or "0")
189
- except ValueError:
190
- length = 0
191
- body = environ["wsgi.input"].read(length) if length > 0 else b""
192
-
193
- return Request(
194
- method=method,
195
- path=path,
196
- headers=headers,
197
- query=query,
198
- path_params={},
199
- body=body,
200
- script_name=script_name,
201
- app=router,
202
- )
203
-
204
-
205
- def request_from_asgi(router: Any, scope: dict[str, Any], body: bytes) -> Request:
206
- method = (scope.get("method") or "GET").upper()
207
- path = scope.get("path") or "/"
208
- headers: dict[str, str] = {
209
- key.decode("latin-1").lower(): value.decode("latin-1")
210
- for key, value in scope.get("headers", [])
211
- }
212
- query = parse_qs(
213
- scope.get("query_string", b"").decode("latin-1"),
214
- keep_blank_values=True,
215
- )
216
- return Request(
217
- method=method,
218
- path=path,
219
- headers=headers,
220
- query=query,
221
- path_params={},
222
- body=body,
223
- script_name=scope.get("root_path") or "",
224
- app=router,
225
- scope=scope,
226
- )
227
-
228
-
229
148
  def router_call(router: Any, *args: Any, **kwargs: Any):
230
149
  del kwargs
231
150
  if len(args) == 2 and isinstance(args[0], dict) and callable(args[1]):
@@ -240,3 +159,6 @@ def router_call(router: Any, *args: Any, **kwargs: Any):
240
159
  if len(args) == 3 and isinstance(args[0], dict):
241
160
  return asgi_app(router, args[0], args[1], args[2])
242
161
  raise TypeError("Invalid ASGI/WSGI invocation")
162
+
163
+
164
+ __all__ = ["asgi_app", "router_call", "wsgi_app"]
@@ -7,6 +7,7 @@ from .spec import (
7
7
  WSGIStartResponse,
8
8
  )
9
9
  from .middleware import Middleware
10
+ from .base import BaseHTTPMiddleware
10
11
  from .decorators import MiddlewareConfig, middleware, middlewares
11
12
  from .compose import apply_middlewares
12
13
  from .cors import CORSMiddleware
@@ -19,6 +20,7 @@ __all__ = [
19
20
  "WSGIStartResponse",
20
21
  "MiddlewareSpec",
21
22
  "Middleware",
23
+ "BaseHTTPMiddleware",
22
24
  "MiddlewareConfig",
23
25
  "middleware",
24
26
  "middlewares",
@@ -0,0 +1,142 @@
1
+ """Request/response middleware base with ``dispatch`` + ``call_next`` semantics."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+ from urllib.parse import urlencode
7
+
8
+ from tigrbl.requests import Request
9
+ from tigrbl.requests.adapters import request_from_asgi
10
+ from tigrbl.responses import Response
11
+ from tigrbl.responses._transport import finalize_transport_response
12
+
13
+ from .middleware import Middleware
14
+ from .spec import ASGIReceive, ASGISend
15
+
16
+
17
+ class BaseHTTPMiddleware(Middleware):
18
+ """Base middleware for intercepting HTTP requests in ASGI mode."""
19
+
20
+ async def dispatch(
21
+ self,
22
+ request: Request,
23
+ call_next: Any,
24
+ ) -> Response:
25
+ """Process the request and optionally delegate to downstream middleware/app."""
26
+
27
+ return await call_next(request)
28
+
29
+ @staticmethod
30
+ def _scope_from_request(scope: dict[str, Any], request: Request) -> dict[str, Any]:
31
+ query_string = urlencode(
32
+ [
33
+ (name, value)
34
+ for name, values in request.query.items()
35
+ for value in values
36
+ ],
37
+ doseq=True,
38
+ ).encode("latin-1")
39
+ return {
40
+ **scope,
41
+ "method": request.method,
42
+ "path": request.path,
43
+ "query_string": query_string,
44
+ "headers": [
45
+ (key.encode("latin-1"), value.encode("latin-1"))
46
+ for key, value in request.headers.items()
47
+ ],
48
+ "root_path": request.script_name,
49
+ }
50
+
51
+ async def asgi(
52
+ self,
53
+ scope: dict[str, Any],
54
+ receive: ASGIReceive,
55
+ send: ASGISend,
56
+ ) -> None:
57
+ if scope.get("type") != "http":
58
+ await self.app(scope, receive, send)
59
+ return
60
+
61
+ request_body = b""
62
+ more_body = True
63
+ while more_body:
64
+ message = await receive()
65
+ request_body += message.get("body", b"")
66
+ more_body = message.get("more_body", False)
67
+
68
+ request = request_from_asgi(None, scope, request_body)
69
+
70
+ async def call_next(forward_request: Request | None = None) -> Response:
71
+ target_request = forward_request or request
72
+ target_scope = self._scope_from_request(scope, target_request)
73
+
74
+ messages: list[dict[str, Any]] = []
75
+ body_sent = False
76
+
77
+ async def receive_for_app() -> dict[str, Any]:
78
+ nonlocal body_sent
79
+ if body_sent:
80
+ return {"type": "http.request", "body": b"", "more_body": False}
81
+ body_sent = True
82
+ return {
83
+ "type": "http.request",
84
+ "body": target_request.body,
85
+ "more_body": False,
86
+ }
87
+
88
+ async def send_from_app(message: dict[str, Any]) -> None:
89
+ messages.append(message)
90
+
91
+ await self.app(target_scope, receive_for_app, send_from_app)
92
+
93
+ start = next(
94
+ message
95
+ for message in messages
96
+ if message.get("type") == "http.response.start"
97
+ )
98
+ raw_headers = list(start.get("headers", []))
99
+ body = b"".join(
100
+ message.get("body", b"")
101
+ for message in messages
102
+ if message.get("type") == "http.response.body"
103
+ )
104
+ headers, finalized_body = finalize_transport_response(
105
+ target_scope,
106
+ int(start.get("status", 200)),
107
+ raw_headers,
108
+ body,
109
+ )
110
+ return Response(
111
+ status_code=int(start.get("status", 200)),
112
+ headers=[
113
+ (key.decode("latin-1"), value.decode("latin-1"))
114
+ for key, value in headers
115
+ ],
116
+ body=finalized_body,
117
+ )
118
+
119
+ response = await self.dispatch(request, call_next)
120
+ headers, finalized_body = finalize_transport_response(
121
+ scope,
122
+ response.status_code,
123
+ response.raw_headers,
124
+ response.body,
125
+ )
126
+ await send(
127
+ {
128
+ "type": "http.response.start",
129
+ "status": response.status_code,
130
+ "headers": headers,
131
+ }
132
+ )
133
+ await send(
134
+ {
135
+ "type": "http.response.body",
136
+ "body": finalized_body,
137
+ "more_body": False,
138
+ }
139
+ )
140
+
141
+
142
+ __all__ = ["BaseHTTPMiddleware"]