tigrbl 0.3.6.dev1__tar.gz → 0.3.7.dev2__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 (312) hide show
  1. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/PKG-INFO +1 -1
  2. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/pyproject.toml +1 -1
  3. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/_router.py +1 -1
  4. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/app/tigrbl_app.py +2 -1
  5. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/common.py +2 -2
  6. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/fastapi.py +2 -2
  7. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/helpers.py +1 -1
  8. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/io.py +1 -1
  9. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/routing.py +1 -1
  10. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/resolver.py +1 -1
  11. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/router_runtime.py +2 -2
  12. tigrbl-0.3.7.dev2/tigrbl/headers/__init__.py +3 -0
  13. tigrbl-0.3.7.dev2/tigrbl/headers/_header.py +69 -0
  14. tigrbl-0.3.7.dev2/tigrbl/middlewares/__init__.py +27 -0
  15. tigrbl-0.3.7.dev2/tigrbl/middlewares/compose.py +17 -0
  16. tigrbl-0.3.7.dev2/tigrbl/middlewares/cors.py +123 -0
  17. tigrbl-0.3.7.dev2/tigrbl/middlewares/decorators.py +32 -0
  18. tigrbl-0.3.7.dev2/tigrbl/middlewares/middleware.py +37 -0
  19. tigrbl-0.3.7.dev2/tigrbl/middlewares/spec.py +26 -0
  20. tigrbl-0.3.7.dev2/tigrbl/requests/__init__.py +3 -0
  21. tigrbl-0.3.6.dev1/tigrbl/transport/request.py → tigrbl-0.3.7.dev2/tigrbl/requests/_request.py +21 -28
  22. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/response/__init__.py +1 -1
  23. tigrbl-0.3.7.dev2/tigrbl/response/stdapi.py +26 -0
  24. tigrbl-0.3.7.dev2/tigrbl/responses/__init__.py +19 -0
  25. tigrbl-0.3.6.dev1/tigrbl/response/stdapi.py → tigrbl-0.3.7.dev2/tigrbl/responses/_response.py +1 -36
  26. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/response/renderer.py +1 -1
  27. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/response/templates.py +1 -1
  28. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/executor/types.py +1 -1
  29. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/schemes/api_key.py +2 -2
  30. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/schemes/http_bearer.py +1 -1
  31. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/diagnostics/compat.py +1 -1
  32. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/lens.py +1 -1
  33. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/openapi/mount.py +1 -1
  34. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/openrpc.py +1 -1
  35. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/swagger.py +1 -1
  36. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/favicon/__init__.py +1 -1
  37. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/asgi_wsgi.py +80 -23
  38. tigrbl-0.3.7.dev2/tigrbl/transport/request.py +9 -0
  39. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/__init__.py +2 -2
  40. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/authn_abc.py +1 -1
  41. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/LICENSE +0 -0
  42. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/README.md +0 -0
  43. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/README.md +0 -0
  44. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/__init__.py +0 -0
  45. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/__init__.py +0 -0
  46. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/_api.py +0 -0
  47. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/_route.py +0 -0
  48. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/_routing.py +0 -0
  49. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/api_spec.py +0 -0
  50. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/mro_collect.py +0 -0
  51. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/resolve.py +0 -0
  52. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/shortcuts.py +0 -0
  53. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/api/tigrbl_api.py +0 -0
  54. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/app/__init__.py +0 -0
  55. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/app/_app.py +0 -0
  56. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/app/_model_registry.py +0 -0
  57. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/app/_routing_runtime.py +0 -0
  58. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/app/app_spec.py +0 -0
  59. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/app/mro_collect.py +0 -0
  60. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/app/shortcuts.py +0 -0
  61. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/__init__.py +0 -0
  62. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/api/__init__.py +0 -0
  63. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/api/common.py +0 -0
  64. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/api/include.py +0 -0
  65. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/api/resource_proxy.py +0 -0
  66. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/api/rpc.py +0 -0
  67. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/columns.py +0 -0
  68. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/handlers/__init__.py +0 -0
  69. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/handlers/builder.py +0 -0
  70. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/handlers/ctx.py +0 -0
  71. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/handlers/identifiers.py +0 -0
  72. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/handlers/namespaces.py +0 -0
  73. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/handlers/steps.py +0 -0
  74. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/hooks.py +0 -0
  75. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/model.py +0 -0
  76. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/model_helpers.py +0 -0
  77. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/model_registry.py +0 -0
  78. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/__init__.py +0 -0
  79. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/attach.py +0 -0
  80. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/collection.py +0 -0
  81. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/io_headers.py +0 -0
  82. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/member.py +0 -0
  83. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rest/router.py +0 -0
  84. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/rpc.py +0 -0
  85. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/schemas/__init__.py +0 -0
  86. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/schemas/builder.py +0 -0
  87. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/schemas/defaults.py +0 -0
  88. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/bindings/schemas/utils.py +0 -0
  89. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/README.md +0 -0
  90. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/__init__.py +0 -0
  91. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/_column.py +0 -0
  92. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/column_spec.py +0 -0
  93. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/field_spec.py +0 -0
  94. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/infer/__init__.py +0 -0
  95. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/infer/core.py +0 -0
  96. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/infer/jsonhints.py +0 -0
  97. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/infer/planning.py +0 -0
  98. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/infer/types.py +0 -0
  99. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/infer/utils.py +0 -0
  100. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/io_spec.py +0 -0
  101. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/mro_collect.py +0 -0
  102. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/shortcuts.py +0 -0
  103. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/column/storage_spec.py +0 -0
  104. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/config/__init__.py +0 -0
  105. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/config/constants.py +0 -0
  106. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/config/defaults.py +0 -0
  107. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/config/resolver.py +0 -0
  108. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/__init__.py +0 -0
  109. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/__init__.py +0 -0
  110. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/bulk.py +0 -0
  111. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/helpers/__init__.py +0 -0
  112. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/helpers/db.py +0 -0
  113. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/helpers/enum.py +0 -0
  114. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/helpers/filters.py +0 -0
  115. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/helpers/model.py +0 -0
  116. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/helpers/normalize.py +0 -0
  117. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/ops.py +0 -0
  118. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/core/crud/params.py +0 -0
  119. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/ddl/__init__.py +0 -0
  120. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/decorators.py +0 -0
  121. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/deps/__init__.py +0 -0
  122. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/deps/jinja.py +0 -0
  123. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/deps/pydantic.py +0 -0
  124. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/deps/sqlalchemy.py +0 -0
  125. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/docs/verbosity.md +0 -0
  126. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/__init__.py +0 -0
  127. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/_engine.py +0 -0
  128. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/bind.py +0 -0
  129. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/builders.py +0 -0
  130. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/capabilities.py +0 -0
  131. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/collect.py +0 -0
  132. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/decorators.py +0 -0
  133. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/docs/PLUGINS.md +0 -0
  134. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/engine_spec.py +0 -0
  135. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/plugins.py +0 -0
  136. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/registry.py +0 -0
  137. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/resolver.py +0 -0
  138. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/engine/shortcuts.py +0 -0
  139. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/hook/__init__.py +0 -0
  140. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/hook/_hook.py +0 -0
  141. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/hook/decorators.py +0 -0
  142. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/hook/exceptions.py +0 -0
  143. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/hook/hook_spec.py +0 -0
  144. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/hook/mro_collect.py +0 -0
  145. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/hook/shortcuts.py +0 -0
  146. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/hook/types.py +0 -0
  147. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/__init__.py +0 -0
  148. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/_op.py +0 -0
  149. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/canonical.py +0 -0
  150. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/collect.py +0 -0
  151. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/decorators.py +0 -0
  152. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/model_registry.py +0 -0
  153. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/mro_collect.py +0 -0
  154. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/resolver.py +0 -0
  155. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/op/types.py +0 -0
  156. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/__init__.py +0 -0
  157. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/_RowBound.py +0 -0
  158. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/__init__.py +0 -0
  159. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/bootstrappable.py +0 -0
  160. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/bound.py +0 -0
  161. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/edges.py +0 -0
  162. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/fields.py +0 -0
  163. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/hierarchy.py +0 -0
  164. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/key_digest.py +0 -0
  165. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/lifecycle.py +0 -0
  166. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/locks.py +0 -0
  167. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/markers.py +0 -0
  168. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/operations.py +0 -0
  169. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/ownable.py +0 -0
  170. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/principals.py +0 -0
  171. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/tenant_bound.py +0 -0
  172. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/upsertable.py +0 -0
  173. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/mixins/utils.py +0 -0
  174. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/__init__.py +0 -0
  175. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/_base.py +0 -0
  176. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/audit.py +0 -0
  177. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/client.py +0 -0
  178. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/group.py +0 -0
  179. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/org.py +0 -0
  180. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/rbac.py +0 -0
  181. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/status.py +0 -0
  182. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/tenant.py +0 -0
  183. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/orm/tables/user.py +0 -0
  184. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/response/README.md +0 -0
  185. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/response/bind.py +0 -0
  186. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/response/decorators.py +0 -0
  187. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/response/resolver.py +0 -0
  188. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/response/shortcuts.py +0 -0
  189. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/response/types.py +0 -0
  190. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/rest/__init__.py +0 -0
  191. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/README.md +0 -0
  192. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/__init__.py +0 -0
  193. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/__init__.py +0 -0
  194. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/emit/__init__.py +0 -0
  195. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/emit/paired_post.py +0 -0
  196. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/emit/paired_pre.py +0 -0
  197. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/emit/readtime_alias.py +0 -0
  198. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/out/__init__.py +0 -0
  199. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/out/masking.py +0 -0
  200. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/refresh/__init__.py +0 -0
  201. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/refresh/demand.py +0 -0
  202. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/resolve/__init__.py +0 -0
  203. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/resolve/assemble.py +0 -0
  204. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/resolve/paired_gen.py +0 -0
  205. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/response/__init__.py +0 -0
  206. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/response/headers_from_payload.py +0 -0
  207. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/response/negotiate.py +0 -0
  208. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/response/negotiation.py +0 -0
  209. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/response/render.py +0 -0
  210. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/response/template.py +0 -0
  211. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/schema/__init__.py +0 -0
  212. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/schema/collect_in.py +0 -0
  213. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/schema/collect_out.py +0 -0
  214. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/storage/__init__.py +0 -0
  215. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/storage/to_stored.py +0 -0
  216. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/wire/__init__.py +0 -0
  217. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/wire/build_in.py +0 -0
  218. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/wire/build_out.py +0 -0
  219. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/wire/dump.py +0 -0
  220. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/atoms/wire/validate_in.py +0 -0
  221. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/context.py +0 -0
  222. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/events.py +0 -0
  223. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/executor/__init__.py +0 -0
  224. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/executor/guards.py +0 -0
  225. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/executor/helpers.py +0 -0
  226. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/executor/invoke.py +0 -0
  227. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/kernel.py +0 -0
  228. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/labels.py +0 -0
  229. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/opview.py +0 -0
  230. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/ordering.py +0 -0
  231. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/status/__init__.py +0 -0
  232. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/status/converters.py +0 -0
  233. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/status/exceptions.py +0 -0
  234. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/status/mappings.py +0 -0
  235. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/status/utils.py +0 -0
  236. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/system.py +0 -0
  237. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/runtime/trace.py +0 -0
  238. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/__init__.py +0 -0
  239. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/_schema.py +0 -0
  240. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/builder/__init__.py +0 -0
  241. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/builder/build_schema.py +0 -0
  242. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/builder/cache.py +0 -0
  243. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/builder/compat.py +0 -0
  244. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/builder/extras.py +0 -0
  245. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/builder/helpers.py +0 -0
  246. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/builder/list_params.py +0 -0
  247. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/builder/strip_parent_fields.py +0 -0
  248. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/collect.py +0 -0
  249. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/decorators.py +0 -0
  250. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/get_schema.py +0 -0
  251. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/schema_spec.py +0 -0
  252. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/shortcuts.py +0 -0
  253. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/types.py +0 -0
  254. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/schema/utils.py +0 -0
  255. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/__init__.py +0 -0
  256. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/dependencies.py +0 -0
  257. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/schemes/__init__.py +0 -0
  258. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/schemes/_base.py +0 -0
  259. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/schemes/mutual_tls.py +0 -0
  260. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/schemes/oauth2.py +0 -0
  261. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/security/schemes/openid_connect.py +0 -0
  262. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/session/README.md +0 -0
  263. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/session/__init__.py +0 -0
  264. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/session/abc.py +0 -0
  265. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/session/base.py +0 -0
  266. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/session/decorators.py +0 -0
  267. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/session/default.py +0 -0
  268. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/session/shortcuts.py +0 -0
  269. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/session/spec.py +0 -0
  270. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/shortcuts.py +0 -0
  271. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/specs.py +0 -0
  272. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/__init__.py +0 -0
  273. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/diagnostics/__init__.py +0 -0
  274. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/diagnostics/healthz.py +0 -0
  275. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/diagnostics/hookz.py +0 -0
  276. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/diagnostics/kernelz.py +0 -0
  277. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/diagnostics/methodz.py +0 -0
  278. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/diagnostics/router.py +0 -0
  279. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/diagnostics/utils.py +0 -0
  280. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/__init__.py +0 -0
  281. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/openapi/__init__.py +0 -0
  282. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/openapi/helpers.py +0 -0
  283. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/openapi/metadata.py +0 -0
  284. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/docs/openapi/schema.py +0 -0
  285. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/favicon/assets/favicon.svg +0 -0
  286. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/system/uvicorn.py +0 -0
  287. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/table/__init__.py +0 -0
  288. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/table/_base.py +0 -0
  289. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/table/_table.py +0 -0
  290. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/table/mro_collect.py +0 -0
  291. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/table/shortcuts.py +0 -0
  292. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/table/table_spec.py +0 -0
  293. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/__init__.py +0 -0
  294. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/background.py +0 -0
  295. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/httpx.py +0 -0
  296. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/jsonrpc/__init__.py +0 -0
  297. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/jsonrpc/dispatcher.py +0 -0
  298. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/jsonrpc/helpers.py +0 -0
  299. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/jsonrpc/models.py +0 -0
  300. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/jsonrpc/openrpc.py +0 -0
  301. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/rest/__init__.py +0 -0
  302. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/rest/aggregator.py +0 -0
  303. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/transport/rest/decorators.py +0 -0
  304. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/allow_anon_provider.py +0 -0
  305. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/nested_path_provider.py +0 -0
  306. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/op.py +0 -0
  307. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/op_config_provider.py +0 -0
  308. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/op_verb_alias_provider.py +0 -0
  309. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/request_extras_provider.py +0 -0
  310. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/response_extras_provider.py +0 -0
  311. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/table_config_provider.py +0 -0
  312. {tigrbl-0.3.6.dev1 → tigrbl-0.3.7.dev2}/tigrbl/types/uuid.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tigrbl
3
- Version: 0.3.6.dev1
3
+ Version: 0.3.7.dev2
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.6.dev1"
3
+ version = "0.3.7.dev2"
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"
@@ -37,7 +37,7 @@ from tigrbl.transport.httpx import ensure_httpx_sync_transport
37
37
  from ._route import Route
38
38
  from ..system.docs.openapi import build_openapi, mount_openapi
39
39
  from ..system.docs.swagger import mount_swagger
40
- from ..transport.request import Request
40
+ from ..requests._request import Request
41
41
  from ..transport.rest.decorators import (
42
42
  delete as rest_delete,
43
43
  get as rest_get,
@@ -106,7 +106,8 @@ class TigrblApp(_App):
106
106
  self.middlewares = tuple(getattr(self, "MIDDLEWARES", ()))
107
107
  self._favicon_path = favicon_path
108
108
  for mw in self.middlewares:
109
- self.add_middleware(mw.__class__, **getattr(mw, "kwargs", {}))
109
+ mw_cls = getattr(mw, "cls", mw.__class__)
110
+ self.add_middleware(mw_cls, **getattr(mw, "kwargs", {}))
110
111
  self._install_favicon()
111
112
  # capture initial routes so refreshes retain ASGI defaults
112
113
  self._base_routes = list(self.router.routes)
@@ -13,11 +13,11 @@ from pydantic import BaseModel
13
13
 
14
14
  from ...api._api import APIRouter as Router
15
15
  from ...core.crud.params import Body, Path, Query
16
- from ...response.stdapi import Response
16
+ from ...responses._response import Response
17
17
  from ...runtime.status.exceptions import HTTPException
18
18
  from ...runtime.status.mappings import status as _status
19
19
  from ...security.dependencies import Depends, Security
20
- from ...transport.request import Request
20
+ from ...requests._request import Request
21
21
  from .helpers import (
22
22
  _Key,
23
23
  _coerce_parent_kw,
@@ -3,7 +3,7 @@
3
3
  Prefer importing directly from:
4
4
  - ``tigrbl.response`` for response classes
5
5
  - ``tigrbl.runtime.status`` for ``status`` and ``HTTPException``
6
- - ``tigrbl.api._api`` / ``tigrbl.transport.request`` / ``tigrbl.security.dependencies``
6
+ - ``tigrbl.api._api`` / ``tigrbl.requests._request`` / ``tigrbl.security.dependencies``
7
7
  """
8
8
 
9
9
  from __future__ import annotations
@@ -21,7 +21,7 @@ from ...response import (
21
21
  )
22
22
  from ...runtime.status import HTTPException, status
23
23
  from ...security.dependencies import Depends, Security
24
- from ...transport.request import Request
24
+ from ...requests._request import Request
25
25
 
26
26
  warnings.warn(
27
27
  "tigrbl.bindings.rest.asgi is deprecated; import from "
@@ -4,7 +4,7 @@ import logging
4
4
  from types import SimpleNamespace
5
5
  from typing import Any, Awaitable, Callable, Dict, Mapping, Sequence, Tuple
6
6
 
7
- from ...transport.request import Request
7
+ from ...requests._request import Request
8
8
  from ...op.types import PHASES
9
9
 
10
10
  try:
@@ -12,7 +12,7 @@ from pydantic import BaseModel, Field, create_model
12
12
  from ...core.crud.params import Query
13
13
  from ...runtime.status.exceptions import HTTPException
14
14
  from ...runtime.status.mappings import status as _status
15
- from ...transport.request import Request
15
+ from ...requests._request import Request
16
16
  from .helpers import _ensure_jsonable
17
17
  from ...op import OpSpec
18
18
 
@@ -9,7 +9,7 @@ from typing import Any, Dict, Optional, Sequence, Tuple
9
9
  from ...runtime.status.exceptions import HTTPException
10
10
  from ...runtime.status.mappings import status as _status
11
11
  from ...security.dependencies import Depends, Security
12
- from ...transport.request import Request
12
+ from ...requests._request import Request
13
13
  from ...op import OpSpec
14
14
  from ...security import HTTPBearer
15
15
  from ...op.types import CANON
@@ -7,7 +7,7 @@ from typing import Annotated, Any, Iterable, get_args, get_origin
7
7
  from ..core.crud.params import Param
8
8
  from ..runtime.status.exceptions import HTTPException
9
9
  from ..runtime.status.mappings import status
10
- from ..transport.request import Request
10
+ from ..requests._request import Request
11
11
 
12
12
 
13
13
  def split_annotated(annotation: Any) -> tuple[Any, tuple[Any, ...]]:
@@ -10,10 +10,10 @@ from ..api.resolve import (
10
10
  resolve_handler_kwargs,
11
11
  resolve_route_dependencies,
12
12
  )
13
- from ..response.stdapi import Response
13
+ from ..responses._response import Response
14
14
  from ..runtime.status.exceptions import HTTPException
15
15
  from ..runtime.status.mappings import status
16
- from ..transport.request import Request
16
+ from ..requests._request import Request
17
17
 
18
18
 
19
19
  def _is_http_response_like(obj: Any) -> bool:
@@ -0,0 +1,3 @@
1
+ from ._header import Headers
2
+
3
+ __all__ = ["Headers"]
@@ -0,0 +1,69 @@
1
+ """Shared case-insensitive HTTP header mapping primitives."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Iterable, Mapping, MutableMapping
6
+
7
+
8
+ class Headers(MutableMapping[str, str]):
9
+ """Case-insensitive header mapping for request/response objects."""
10
+
11
+ def __init__(
12
+ self,
13
+ values: Iterable[tuple[str, str]] | Mapping[str, str] | None = None,
14
+ ) -> None:
15
+ self._data: dict[str, tuple[str, str]] = {}
16
+ if values is None:
17
+ return
18
+ items = values.items() if hasattr(values, "items") else values
19
+ for key, value in items:
20
+ lower = key.lower()
21
+ self._data[lower] = (lower, str(value))
22
+
23
+ @staticmethod
24
+ def _attribute_key(name: str) -> str:
25
+ return name.replace("_", "-").lower()
26
+
27
+ def __getitem__(self, key: str) -> str:
28
+ return self._data[key.lower()][1]
29
+
30
+ def __setitem__(self, key: str, value: str) -> None:
31
+ lower = key.lower()
32
+ self._data[lower] = (lower, str(value))
33
+
34
+ def __delitem__(self, key: str) -> None:
35
+ del self._data[key.lower()]
36
+
37
+ def __iter__(self):
38
+ for original, _ in self._data.values():
39
+ yield original
40
+
41
+ def __len__(self) -> int:
42
+ return len(self._data)
43
+
44
+ def items(self):
45
+ return ((k, v) for k, v in self._data.values())
46
+
47
+ def as_list(self) -> list[tuple[str, str]]:
48
+ return list(self.items())
49
+
50
+ def get(self, key: str, default: str | None = None) -> str | None:
51
+ item = self._data.get(key.lower())
52
+ if item is None:
53
+ return default
54
+ return item[1]
55
+
56
+ def __getattr__(self, name: str) -> str:
57
+ key = self._attribute_key(name)
58
+ if key in self._data:
59
+ return self._data[key][1]
60
+ raise AttributeError(name)
61
+
62
+ def __setattr__(self, name: str, value: str) -> None:
63
+ if name.startswith("_"):
64
+ object.__setattr__(self, name, value)
65
+ return
66
+ self[self._attribute_key(name)] = value
67
+
68
+
69
+ __all__ = ["Headers"]
@@ -0,0 +1,27 @@
1
+ from .spec import (
2
+ ASGIApp,
3
+ ASGIReceive,
4
+ ASGISend,
5
+ MiddlewareSpec,
6
+ WSGIApp,
7
+ WSGIStartResponse,
8
+ )
9
+ from .middleware import Middleware
10
+ from .decorators import MiddlewareConfig, middleware, middlewares
11
+ from .compose import apply_middlewares
12
+ from .cors import CORSMiddleware
13
+
14
+ __all__ = [
15
+ "ASGIApp",
16
+ "ASGIReceive",
17
+ "ASGISend",
18
+ "WSGIApp",
19
+ "WSGIStartResponse",
20
+ "MiddlewareSpec",
21
+ "Middleware",
22
+ "MiddlewareConfig",
23
+ "middleware",
24
+ "middlewares",
25
+ "apply_middlewares",
26
+ "CORSMiddleware",
27
+ ]
@@ -0,0 +1,17 @@
1
+ """Helpers for composing ASGI/WSGI middleware stacks."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+
8
+ def apply_middlewares(
9
+ app: Any, middleware_stack: list[tuple[Any, dict[str, Any]]]
10
+ ) -> Any:
11
+ wrapped = app
12
+ for middleware_class, options in reversed(middleware_stack):
13
+ wrapped = middleware_class(wrapped, **(options or {}))
14
+ return wrapped
15
+
16
+
17
+ __all__ = ["apply_middlewares"]
@@ -0,0 +1,123 @@
1
+ """CORS middleware for ASGI/WSGI adapters."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from tigrbl.headers import Headers
8
+
9
+ from .middleware import Middleware
10
+ from .spec import ASGIReceive, ASGISend, WSGIStartResponse
11
+
12
+
13
+ class CORSMiddleware(Middleware):
14
+ def __init__(
15
+ self,
16
+ app,
17
+ *,
18
+ allow_origin: str = "*",
19
+ allow_methods: str = "GET,POST,PUT,PATCH,DELETE,OPTIONS",
20
+ allow_headers: str = "*",
21
+ allow_credentials: bool = False,
22
+ max_age: int = 600,
23
+ ) -> None:
24
+ super().__init__(
25
+ app,
26
+ allow_origin=allow_origin,
27
+ allow_methods=allow_methods,
28
+ allow_headers=allow_headers,
29
+ allow_credentials=allow_credentials,
30
+ max_age=max_age,
31
+ )
32
+ self.allow_origin = allow_origin
33
+ self.allow_methods = allow_methods
34
+ self.allow_headers = allow_headers
35
+ self.allow_credentials = allow_credentials
36
+ self.max_age = max_age
37
+
38
+ def _cors_headers(self) -> list[tuple[str, str]]:
39
+ headers = [
40
+ ("access-control-allow-origin", self.allow_origin),
41
+ ("access-control-allow-methods", self.allow_methods),
42
+ ("access-control-allow-headers", self.allow_headers),
43
+ ("access-control-max-age", str(self.max_age)),
44
+ ]
45
+ if self.allow_credentials:
46
+ headers.append(("access-control-allow-credentials", "true"))
47
+ return headers
48
+
49
+ async def asgi(
50
+ self,
51
+ scope: dict[str, Any],
52
+ receive: ASGIReceive,
53
+ send: ASGISend,
54
+ ) -> None:
55
+ if scope.get("type") != "http":
56
+ await self.app(scope, receive, send)
57
+ return
58
+
59
+ request_headers = Headers(
60
+ [
61
+ (k.decode("latin-1"), v.decode("latin-1"))
62
+ for k, v in scope.get("headers", [])
63
+ ]
64
+ )
65
+ is_preflight = (
66
+ (scope.get("method") or "").upper() == "OPTIONS"
67
+ and request_headers.get("origin") is not None
68
+ and request_headers.get("access-control-request-method") is not None
69
+ )
70
+ if is_preflight:
71
+ await send(
72
+ {
73
+ "type": "http.response.start",
74
+ "status": 204,
75
+ "headers": [
76
+ (k.encode("latin-1"), v.encode("latin-1"))
77
+ for k, v in self._cors_headers()
78
+ ],
79
+ }
80
+ )
81
+ await send({"type": "http.response.body", "body": b""})
82
+ return
83
+
84
+ async def send_with_cors(message: dict[str, Any]) -> None:
85
+ if message.get("type") == "http.response.start":
86
+ headers = list(message.get("headers", []))
87
+ headers.extend(
88
+ [
89
+ (k.encode("latin-1"), v.encode("latin-1"))
90
+ for k, v in self._cors_headers()
91
+ ]
92
+ )
93
+ message = {**message, "headers": headers}
94
+ await send(message)
95
+
96
+ await self.app(scope, receive, send_with_cors)
97
+
98
+ def wsgi(
99
+ self,
100
+ environ: dict[str, Any],
101
+ start_response: WSGIStartResponse,
102
+ ) -> list[bytes]:
103
+ method = (environ.get("REQUEST_METHOD") or "").upper()
104
+ is_preflight = (
105
+ method == "OPTIONS"
106
+ and environ.get("HTTP_ORIGIN")
107
+ and environ.get("HTTP_ACCESS_CONTROL_REQUEST_METHOD")
108
+ )
109
+
110
+ if is_preflight:
111
+ start_response("204 No Content", self._cors_headers())
112
+ return [b""]
113
+
114
+ def cors_start_response(
115
+ status: str, headers: list[tuple[str, str]], *args: Any
116
+ ):
117
+ merged = list(headers) + self._cors_headers()
118
+ return start_response(status, merged, *args)
119
+
120
+ return self.app(environ, cors_start_response)
121
+
122
+
123
+ __all__ = ["CORSMiddleware"]
@@ -0,0 +1,32 @@
1
+ """Decorators for attaching middleware specs to apps/apis."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from typing import Any
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class MiddlewareConfig:
11
+ cls: Any
12
+ kwargs: dict[str, Any]
13
+
14
+
15
+ def middleware(middleware_class: Any, /, **kwargs: Any) -> MiddlewareConfig:
16
+ """Build declarative middleware config objects for ``MIDDLEWARES``."""
17
+
18
+ return MiddlewareConfig(cls=middleware_class, kwargs=kwargs)
19
+
20
+
21
+ def middlewares(*configs: MiddlewareConfig):
22
+ """Attach middleware configs to class-level ``MIDDLEWARES``."""
23
+
24
+ def _decorator(target: Any) -> Any:
25
+ current = tuple(getattr(target, "MIDDLEWARES", ()))
26
+ setattr(target, "MIDDLEWARES", current + tuple(configs))
27
+ return target
28
+
29
+ return _decorator
30
+
31
+
32
+ __all__ = ["MiddlewareConfig", "middleware", "middlewares"]
@@ -0,0 +1,37 @@
1
+ """Base middleware implementation supporting ASGI and WSGI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from .spec import ASGIApp, ASGIReceive, ASGISend, WSGIApp, WSGIStartResponse
8
+
9
+
10
+ class Middleware:
11
+ """Base middleware for composing ASGI/WSGI pipelines."""
12
+
13
+ def __init__(self, app: ASGIApp | WSGIApp, **kwargs: Any) -> None:
14
+ self.app = app
15
+ self.kwargs = kwargs
16
+
17
+ async def asgi(
18
+ self,
19
+ scope: dict[str, Any],
20
+ receive: ASGIReceive,
21
+ send: ASGISend,
22
+ ) -> None:
23
+ await self.app(scope, receive, send)
24
+
25
+ def wsgi(
26
+ self,
27
+ environ: dict[str, Any],
28
+ start_response: WSGIStartResponse,
29
+ ) -> list[bytes]:
30
+ return self.app(environ, start_response)
31
+
32
+ def __call__(self, *args: Any, **kwargs: Any):
33
+ if len(args) == 3 and isinstance(args[0], dict):
34
+ return self.asgi(args[0], args[1], args[2])
35
+ if len(args) == 2 and isinstance(args[0], dict):
36
+ return self.wsgi(args[0], args[1])
37
+ raise TypeError("Invalid middleware invocation")
@@ -0,0 +1,26 @@
1
+ """Middleware protocol and callable type specs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Awaitable, Callable
6
+ from typing import Any, Protocol
7
+
8
+ ASGIReceive = Callable[[], Awaitable[dict[str, Any]]]
9
+ ASGISend = Callable[[dict[str, Any]], Awaitable[None]]
10
+ ASGIApp = Callable[[dict[str, Any], ASGIReceive, ASGISend], Awaitable[None]]
11
+ WSGIStartResponse = Callable[..., Any]
12
+ WSGIApp = Callable[[dict[str, Any], WSGIStartResponse], list[bytes]]
13
+
14
+
15
+ class MiddlewareSpec(Protocol):
16
+ """Protocol for middleware classes compatible with ASGI and WSGI."""
17
+
18
+ kwargs: dict[str, Any]
19
+
20
+ async def asgi(
21
+ self, scope: dict[str, Any], receive: ASGIReceive, send: ASGISend
22
+ ) -> None: ...
23
+
24
+ def wsgi(
25
+ self, environ: dict[str, Any], start_response: WSGIStartResponse
26
+ ) -> list[bytes]: ...
@@ -0,0 +1,3 @@
1
+ from ._request import Request, AwaitableValue, URL
2
+
3
+ __all__ = ["Request", "AwaitableValue", "URL"]
@@ -3,38 +3,12 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import json as json_module
6
- from collections.abc import MutableMapping
7
- from http.cookies import SimpleCookie
8
6
  from dataclasses import dataclass, field
7
+ from http.cookies import SimpleCookie
9
8
  from types import SimpleNamespace
10
9
  from typing import Any
11
10
 
12
-
13
- class Headers(MutableMapping[str, str]):
14
- """Case-insensitive header mapping."""
15
-
16
- def __init__(self, values: dict[str, str] | None = None) -> None:
17
- self._data: dict[str, str] = {}
18
- for key, value in (values or {}).items():
19
- self._data[key.lower()] = value
20
-
21
- def __getitem__(self, key: str) -> str:
22
- return self._data[key.lower()]
23
-
24
- def __setitem__(self, key: str, value: str) -> None:
25
- self._data[key.lower()] = value
26
-
27
- def __delitem__(self, key: str) -> None:
28
- del self._data[key.lower()]
29
-
30
- def __iter__(self):
31
- return iter(self._data)
32
-
33
- def __len__(self) -> int:
34
- return len(self._data)
35
-
36
- def get(self, key: str, default: str | None = None) -> str | None:
37
- return self._data.get(key.lower(), default)
11
+ from tigrbl.headers import Headers
38
12
 
39
13
 
40
14
  @dataclass(frozen=True)
@@ -73,6 +47,22 @@ class AwaitableValue:
73
47
  def __repr__(self) -> str:
74
48
  return repr(self.value)
75
49
 
50
+ def __getattr__(self, name: str) -> Any:
51
+ attr = getattr(self.value, name)
52
+ if callable(attr):
53
+
54
+ def _wrapped(*args: Any, **kwargs: Any) -> Any:
55
+ return attr(*args, **kwargs)
56
+
57
+ return _wrapped
58
+ return attr
59
+
60
+ def __iter__(self):
61
+ return iter(self.value)
62
+
63
+ def __len__(self) -> int:
64
+ return len(self.value)
65
+
76
66
 
77
67
  @dataclass
78
68
  class Request:
@@ -126,3 +116,6 @@ class Request:
126
116
  parsed = SimpleCookie()
127
117
  parsed.load(raw)
128
118
  return {name: morsel.value for name, morsel in parsed.items()}
119
+
120
+
121
+ __all__ = ["Request", "AwaitableValue", "URL"]
@@ -1,4 +1,4 @@
1
- from .stdapi import (
1
+ from ..responses._response import (
2
2
  Response as StdApiResponse,
3
3
  JSONResponse,
4
4
  HTMLResponse,
@@ -0,0 +1,26 @@
1
+ """Backward-compatible stdapi response exports.
2
+
3
+ Prefer importing from ``tigrbl.responses``.
4
+ """
5
+
6
+ from tigrbl.headers import Headers
7
+ from tigrbl.responses._response import (
8
+ FileResponse,
9
+ HTMLResponse,
10
+ JSONResponse,
11
+ PlainTextResponse,
12
+ RedirectResponse,
13
+ Response,
14
+ StreamingResponse,
15
+ )
16
+
17
+ __all__ = [
18
+ "Headers",
19
+ "Response",
20
+ "JSONResponse",
21
+ "HTMLResponse",
22
+ "PlainTextResponse",
23
+ "StreamingResponse",
24
+ "FileResponse",
25
+ "RedirectResponse",
26
+ ]
@@ -0,0 +1,19 @@
1
+ from ._response import (
2
+ Response,
3
+ JSONResponse,
4
+ HTMLResponse,
5
+ PlainTextResponse,
6
+ StreamingResponse,
7
+ FileResponse,
8
+ RedirectResponse,
9
+ )
10
+
11
+ __all__ = [
12
+ "Response",
13
+ "JSONResponse",
14
+ "HTMLResponse",
15
+ "PlainTextResponse",
16
+ "StreamingResponse",
17
+ "FileResponse",
18
+ "RedirectResponse",
19
+ ]
@@ -4,47 +4,12 @@ from __future__ import annotations
4
4
 
5
5
  import json as json_module
6
6
  import mimetypes
7
- from collections.abc import MutableMapping
8
7
  from dataclasses import dataclass, field
9
8
  from http.cookies import SimpleCookie
10
9
  from pathlib import Path
11
10
  from typing import Any, AsyncIterator, Iterable, Mapping
12
11
 
13
-
14
- class Headers(MutableMapping[str, str]):
15
- """Case-insensitive header mapping for response objects."""
16
-
17
- def __init__(
18
- self, values: Iterable[tuple[str, str]] | Mapping[str, str] | None = None
19
- ):
20
- self._data: dict[str, tuple[str, str]] = {}
21
- if values is None:
22
- return
23
- items = values.items() if hasattr(values, "items") else values
24
- for key, value in items:
25
- self._data[key.lower()] = (key.lower(), value)
26
-
27
- def __getitem__(self, key: str) -> str:
28
- return self._data[key.lower()][1]
29
-
30
- def __setitem__(self, key: str, value: str) -> None:
31
- self._data[key.lower()] = (key.lower(), value)
32
-
33
- def __delitem__(self, key: str) -> None:
34
- del self._data[key.lower()]
35
-
36
- def __iter__(self):
37
- for original, _ in self._data.values():
38
- yield original
39
-
40
- def __len__(self) -> int:
41
- return len(self._data)
42
-
43
- def items(self):
44
- return ((k, v) for k, v in self._data.values())
45
-
46
- def as_list(self) -> list[tuple[str, str]]:
47
- return [(k, v) for k, v in self._data.values()]
12
+ from tigrbl.headers import Headers
48
13
 
49
14
 
50
15
  @dataclass
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  from typing import Any, AsyncIterable, Iterable, Mapping, Optional, Union, cast
5
5
  import logging
6
6
 
7
- from ....response.stdapi import Response
7
+ from ....responses._response import Response
8
8
  from ....transport.background import BackgroundTask
9
9
 
10
10
  from ....response.shortcuts import (
@@ -3,7 +3,7 @@ from functools import lru_cache
3
3
  import logging
4
4
  from typing import Any, Dict, Iterable, Optional, Tuple
5
5
 
6
- from ....transport.request import Request
6
+ from ....requests._request import Request
7
7
  from ....deps.jinja import (
8
8
  Environment,
9
9
  FileSystemLoader,