tigrbl 0.3.7.dev1__tar.gz → 0.3.7.dev3__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.
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/PKG-INFO +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/pyproject.toml +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/__init__.py +2 -2
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/_router.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/api_spec.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/app/app_spec.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/app/tigrbl_app.py +2 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/__init__.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/common.py +2 -2
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/fastapi.py +4 -4
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/helpers.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/io.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/routing.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/resolver.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/router_runtime.py +2 -2
- tigrbl-0.3.7.dev3/tigrbl/headers/__init__.py +3 -0
- tigrbl-0.3.7.dev3/tigrbl/headers/_header.py +89 -0
- tigrbl-0.3.7.dev3/tigrbl/middlewares/__init__.py +27 -0
- tigrbl-0.3.7.dev3/tigrbl/middlewares/compose.py +17 -0
- tigrbl-0.3.7.dev3/tigrbl/middlewares/cors.py +123 -0
- tigrbl-0.3.7.dev3/tigrbl/middlewares/decorators.py +32 -0
- tigrbl-0.3.7.dev3/tigrbl/middlewares/middleware.py +37 -0
- tigrbl-0.3.7.dev3/tigrbl/middlewares/spec.py +26 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/types.py +1 -1
- tigrbl-0.3.7.dev3/tigrbl/requests/__init__.py +5 -0
- tigrbl-0.3.7.dev1/tigrbl/transport/request.py → tigrbl-0.3.7.dev3/tigrbl/requests/_request.py +67 -46
- {tigrbl-0.3.7.dev1/tigrbl/response → tigrbl-0.3.7.dev3/tigrbl/responses}/__init__.py +16 -18
- tigrbl-0.3.7.dev1/tigrbl/response/stdapi.py → tigrbl-0.3.7.dev3/tigrbl/responses/_response.py +20 -49
- {tigrbl-0.3.7.dev1/tigrbl/response → tigrbl-0.3.7.dev3/tigrbl/responses}/shortcuts.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/response/headers_from_payload.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/response/renderer.py +2 -2
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/response/templates.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/executor/types.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/diagnostics/compat.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/lens.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/openapi/mount.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/openrpc.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/swagger.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/favicon/__init__.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/table/_base.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/table/table_spec.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/asgi_wsgi.py +84 -23
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/jsonrpc/dispatcher.py +36 -10
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/__init__.py +2 -2
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/authn_abc.py +1 -1
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/LICENSE +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/README.md +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/README.md +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/_api.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/_route.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/_routing.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/mro_collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/resolve.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/api/tigrbl_api.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/app/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/app/_app.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/app/_model_registry.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/app/_routing_runtime.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/app/mro_collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/app/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/api/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/api/common.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/api/include.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/api/resource_proxy.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/api/rpc.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/columns.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/handlers/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/handlers/builder.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/handlers/ctx.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/handlers/identifiers.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/handlers/namespaces.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/handlers/steps.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/hooks.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/model.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/model_helpers.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/model_registry.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/attach.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/collection.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/io_headers.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/member.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rest/router.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/rpc.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/schemas/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/schemas/builder.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/schemas/defaults.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/bindings/schemas/utils.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/README.md +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/_column.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/column_spec.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/field_spec.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/infer/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/infer/core.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/infer/jsonhints.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/infer/planning.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/infer/types.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/infer/utils.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/io_spec.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/mro_collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/column/storage_spec.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/config/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/config/constants.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/config/defaults.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/config/resolver.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/bulk.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/helpers/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/helpers/db.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/helpers/enum.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/helpers/filters.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/helpers/model.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/helpers/normalize.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/ops.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/core/crud/params.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/ddl/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/decorators.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/deps/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/deps/jinja.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/deps/pydantic.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/deps/sqlalchemy.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/docs/verbosity.md +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/_engine.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/bind.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/builders.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/capabilities.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/decorators.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/docs/PLUGINS.md +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/engine_spec.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/plugins.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/registry.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/resolver.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/engine/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/hook/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/hook/_hook.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/hook/decorators.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/hook/exceptions.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/hook/hook_spec.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/hook/mro_collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/hook/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/hook/types.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/_op.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/canonical.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/decorators.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/model_registry.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/mro_collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/op/resolver.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/_RowBound.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/bootstrappable.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/bound.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/edges.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/fields.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/hierarchy.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/key_digest.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/lifecycle.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/locks.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/markers.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/operations.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/ownable.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/principals.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/tenant_bound.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/upsertable.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/mixins/utils.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/_base.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/audit.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/client.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/group.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/org.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/rbac.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/status.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/tenant.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/orm/tables/user.py +0 -0
- {tigrbl-0.3.7.dev1/tigrbl/response → tigrbl-0.3.7.dev3/tigrbl/responses}/README.md +0 -0
- {tigrbl-0.3.7.dev1/tigrbl/response → tigrbl-0.3.7.dev3/tigrbl/responses}/bind.py +0 -0
- {tigrbl-0.3.7.dev1/tigrbl/response → tigrbl-0.3.7.dev3/tigrbl/responses}/decorators.py +0 -0
- {tigrbl-0.3.7.dev1/tigrbl/response → tigrbl-0.3.7.dev3/tigrbl/responses}/resolver.py +0 -0
- {tigrbl-0.3.7.dev1/tigrbl/response → tigrbl-0.3.7.dev3/tigrbl/responses}/types.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/rest/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/README.md +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/emit/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/emit/paired_post.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/emit/paired_pre.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/emit/readtime_alias.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/out/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/out/masking.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/refresh/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/refresh/demand.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/resolve/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/resolve/assemble.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/resolve/paired_gen.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/response/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/response/negotiate.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/response/negotiation.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/response/render.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/response/template.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/schema/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/schema/collect_in.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/schema/collect_out.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/storage/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/storage/to_stored.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/wire/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/wire/build_in.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/wire/build_out.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/wire/dump.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/atoms/wire/validate_in.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/context.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/events.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/executor/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/executor/guards.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/executor/helpers.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/executor/invoke.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/kernel.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/labels.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/opview.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/ordering.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/status/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/status/converters.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/status/exceptions.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/status/mappings.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/status/utils.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/system.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/runtime/trace.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/_schema.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/builder/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/builder/build_schema.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/builder/cache.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/builder/compat.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/builder/extras.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/builder/helpers.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/builder/list_params.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/builder/strip_parent_fields.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/decorators.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/get_schema.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/schema_spec.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/types.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/schema/utils.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/dependencies.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/schemes/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/schemes/_base.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/schemes/api_key.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/schemes/http_bearer.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/schemes/mutual_tls.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/schemes/oauth2.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/security/schemes/openid_connect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/session/README.md +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/session/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/session/abc.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/session/base.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/session/decorators.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/session/default.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/session/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/session/spec.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/specs.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/diagnostics/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/diagnostics/healthz.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/diagnostics/hookz.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/diagnostics/kernelz.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/diagnostics/methodz.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/diagnostics/router.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/diagnostics/utils.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/openapi/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/openapi/helpers.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/openapi/metadata.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/docs/openapi/schema.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/favicon/assets/favicon.svg +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/system/uvicorn.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/table/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/table/_table.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/table/mro_collect.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/table/shortcuts.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/background.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/httpx.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/jsonrpc/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/jsonrpc/helpers.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/jsonrpc/models.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/jsonrpc/openrpc.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/rest/__init__.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/rest/aggregator.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/transport/rest/decorators.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/allow_anon_provider.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/nested_path_provider.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/op.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/op_config_provider.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/op_verb_alias_provider.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/request_extras_provider.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/response_extras_provider.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/table_config_provider.py +0 -0
- {tigrbl-0.3.7.dev1 → tigrbl-0.3.7.dev3}/tigrbl/types/uuid.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tigrbl
|
|
3
|
-
Version: 0.3.7.
|
|
3
|
+
Version: 0.3.7.dev3
|
|
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.7.
|
|
3
|
+
version = "0.3.7.dev3"
|
|
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"
|
|
@@ -43,8 +43,8 @@ from .op import alias_ctx, op_ctx, alias, op_alias
|
|
|
43
43
|
from .hook import hook_ctx
|
|
44
44
|
from .engine.decorators import engine_ctx
|
|
45
45
|
from .schema.decorators import schema_ctx
|
|
46
|
-
from .
|
|
47
|
-
from .
|
|
46
|
+
from .responses.decorators import response_ctx
|
|
47
|
+
from .responses.types import ResponseSpec
|
|
48
48
|
|
|
49
49
|
# ── Bindings (model + API orchestration) ───────────────────────────────────────
|
|
50
50
|
from .bindings import (
|
|
@@ -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 ..
|
|
40
|
+
from ..requests import Request
|
|
41
41
|
from ..transport.rest.decorators import (
|
|
42
42
|
delete as rest_delete,
|
|
43
43
|
get as rest_get,
|
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
4
|
from typing import Any, Callable, Optional, Sequence
|
|
5
5
|
from ..engine.engine_spec import EngineCfg
|
|
6
|
-
from ..
|
|
6
|
+
from ..responses.types import ResponseSpec
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
@dataclass
|
|
@@ -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
|
-
|
|
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)
|
|
@@ -46,7 +46,7 @@ from .hooks import normalize_and_attach as build_hooks
|
|
|
46
46
|
from .handlers import build_and_attach as build_handlers
|
|
47
47
|
from .rpc import register_and_attach as register_rpc
|
|
48
48
|
from .rest import build_router_and_attach as build_rest
|
|
49
|
-
from ..
|
|
49
|
+
from ..responses.bind import bind as bind_response
|
|
50
50
|
|
|
51
51
|
# API facade integration
|
|
52
52
|
from .api import include_model, include_models, rpc_call
|
|
@@ -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 ...
|
|
16
|
+
from ...responses 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 ...
|
|
20
|
+
from ...requests import Request
|
|
21
21
|
from .helpers import (
|
|
22
22
|
_Key,
|
|
23
23
|
_coerce_parent_kw,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""Deprecated compatibility module for REST ASGI-style primitives.
|
|
2
2
|
|
|
3
3
|
Prefer importing directly from:
|
|
4
|
-
- ``tigrbl.
|
|
4
|
+
- ``tigrbl.responses`` for response classes
|
|
5
5
|
- ``tigrbl.runtime.status`` for ``status`` and ``HTTPException``
|
|
6
|
-
- ``tigrbl.api._api`` / ``tigrbl.
|
|
6
|
+
- ``tigrbl.api._api`` / ``tigrbl.requests`` / ``tigrbl.security.dependencies``
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
@@ -21,11 +21,11 @@ from ...response import (
|
|
|
21
21
|
)
|
|
22
22
|
from ...runtime.status import HTTPException, status
|
|
23
23
|
from ...security.dependencies import Depends, Security
|
|
24
|
-
from ...
|
|
24
|
+
from ...requests import Request
|
|
25
25
|
|
|
26
26
|
warnings.warn(
|
|
27
27
|
"tigrbl.bindings.rest.asgi is deprecated; import from "
|
|
28
|
-
"tigrbl.
|
|
28
|
+
"tigrbl.responses, tigrbl.runtime.status, and concrete modules instead.",
|
|
29
29
|
DeprecationWarning,
|
|
30
30
|
stacklevel=2,
|
|
31
31
|
)
|
|
@@ -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 ...
|
|
15
|
+
from ...requests 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 ...
|
|
12
|
+
from ...requests 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 ..
|
|
10
|
+
from ..requests 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 ..
|
|
13
|
+
from ..responses import Response
|
|
14
14
|
from ..runtime.status.exceptions import HTTPException
|
|
15
15
|
from ..runtime.status.mappings import status
|
|
16
|
-
from ..
|
|
16
|
+
from ..requests import Request
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def _is_http_response_like(obj: Any) -> bool:
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Shared case-insensitive HTTP header mapping primitives."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable, Mapping, MutableMapping
|
|
6
|
+
from http.cookies import SimpleCookie
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HeaderCookies(dict[str, str]):
|
|
10
|
+
"""Dot-addressable cookie mapping parsed from a Cookie header value."""
|
|
11
|
+
|
|
12
|
+
def __getattr__(self, name: str) -> str:
|
|
13
|
+
try:
|
|
14
|
+
return self[name]
|
|
15
|
+
except KeyError as exc: # pragma: no cover - defensive
|
|
16
|
+
raise AttributeError(name) from exc
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Headers(MutableMapping[str, str]):
|
|
20
|
+
"""Case-insensitive header mapping for request/response objects."""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
values: Iterable[tuple[str, str]] | Mapping[str, str] | None = None,
|
|
25
|
+
) -> None:
|
|
26
|
+
self._data: dict[str, tuple[str, str]] = {}
|
|
27
|
+
if values is None:
|
|
28
|
+
return
|
|
29
|
+
items = values.items() if hasattr(values, "items") else values
|
|
30
|
+
for key, value in items:
|
|
31
|
+
lower = key.lower()
|
|
32
|
+
self._data[lower] = (lower, str(value))
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def _attribute_key(name: str) -> str:
|
|
36
|
+
return name.replace("_", "-").lower()
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def _parse_cookie_header(value: str) -> HeaderCookies:
|
|
40
|
+
parsed = SimpleCookie()
|
|
41
|
+
parsed.load(value)
|
|
42
|
+
return HeaderCookies({name: morsel.value for name, morsel in parsed.items()})
|
|
43
|
+
|
|
44
|
+
def __getitem__(self, key: str) -> str:
|
|
45
|
+
return self._data[key.lower()][1]
|
|
46
|
+
|
|
47
|
+
def __setitem__(self, key: str, value: str) -> None:
|
|
48
|
+
lower = key.lower()
|
|
49
|
+
self._data[lower] = (lower, str(value))
|
|
50
|
+
|
|
51
|
+
def __delitem__(self, key: str) -> None:
|
|
52
|
+
del self._data[key.lower()]
|
|
53
|
+
|
|
54
|
+
def __iter__(self):
|
|
55
|
+
for original, _ in self._data.values():
|
|
56
|
+
yield original
|
|
57
|
+
|
|
58
|
+
def __len__(self) -> int:
|
|
59
|
+
return len(self._data)
|
|
60
|
+
|
|
61
|
+
def items(self):
|
|
62
|
+
return ((k, v) for k, v in self._data.values())
|
|
63
|
+
|
|
64
|
+
def as_list(self) -> list[tuple[str, str]]:
|
|
65
|
+
return list(self.items())
|
|
66
|
+
|
|
67
|
+
def get(self, key: str, default: str | None = None) -> str | None:
|
|
68
|
+
item = self._data.get(key.lower())
|
|
69
|
+
if item is None:
|
|
70
|
+
return default
|
|
71
|
+
return item[1]
|
|
72
|
+
|
|
73
|
+
def __getattr__(self, name: str) -> str | HeaderCookies:
|
|
74
|
+
key = self._attribute_key(name)
|
|
75
|
+
if key not in self._data:
|
|
76
|
+
raise AttributeError(name)
|
|
77
|
+
value = self._data[key][1]
|
|
78
|
+
if key == "cookie":
|
|
79
|
+
return self._parse_cookie_header(value)
|
|
80
|
+
return value
|
|
81
|
+
|
|
82
|
+
def __setattr__(self, name: str, value: str) -> None:
|
|
83
|
+
if name.startswith("_"):
|
|
84
|
+
object.__setattr__(self, name, value)
|
|
85
|
+
return
|
|
86
|
+
self[self._attribute_key(name)] = value
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
__all__ = ["Headers", "HeaderCookies"]
|
|
@@ -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]: ...
|
|
@@ -8,7 +8,7 @@ from typing import Any, Literal, Mapping, Optional, Tuple, cast
|
|
|
8
8
|
from ..config.constants import CANON as CANONICAL_VERB_TUPLE
|
|
9
9
|
from ..hook.types import PHASE, HookPhase, PHASES, Ctx, StepFn, HookPredicate
|
|
10
10
|
from ..hook import HookSpec as OpHook
|
|
11
|
-
from ..
|
|
11
|
+
from ..responses.types import ResponseSpec
|
|
12
12
|
from ..engine.engine_spec import EngineCfg
|
|
13
13
|
from typing import TYPE_CHECKING
|
|
14
14
|
|