tigrbl 0.3.4.dev2__tar.gz → 0.3.5__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.4.dev2 → tigrbl-0.3.5}/PKG-INFO +257 -14
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/README.md +252 -5
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/pyproject.toml +6 -10
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/__init__.py +14 -3
- tigrbl-0.3.5/tigrbl/api/__init__.py +19 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/api/_api.py +49 -7
- tigrbl-0.3.5/tigrbl/api/_route.py +119 -0
- tigrbl-0.3.5/tigrbl/api/_router.py +271 -0
- tigrbl-0.3.5/tigrbl/api/_routing.py +143 -0
- tigrbl-0.3.5/tigrbl/api/resolve.py +151 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/api/tigrbl_api.py +49 -4
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/app/_app.py +19 -8
- tigrbl-0.3.5/tigrbl/app/_routing_runtime.py +24 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/app/tigrbl_app.py +116 -5
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/api/include.py +6 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/collection.py +3 -3
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/common.py +26 -12
- tigrbl-0.3.5/tigrbl/bindings/rest/fastapi.py +52 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/helpers.py +1 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/io.py +4 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/io_headers.py +1 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/member.py +3 -3
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/router.py +50 -4
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/routing.py +11 -4
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rpc.py +26 -12
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/__init__.py +4 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/storage_spec.py +13 -0
- tigrbl-0.3.5/tigrbl/core/crud/params.py +50 -0
- tigrbl-0.3.5/tigrbl/core/resolver.py +81 -0
- tigrbl-0.3.5/tigrbl/core/router_runtime.py +164 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/ddl/__init__.py +9 -6
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/deps/__init__.py +10 -5
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/builders.py +14 -5
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/engine_spec.py +7 -4
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/resolver.py +137 -4
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/shortcuts.py +19 -4
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/_RowBound.py +1 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/ownable.py +1 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/tenant_bound.py +1 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/response/__init__.py +16 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/response/shortcuts.py +34 -40
- tigrbl-0.3.5/tigrbl/response/stdapi.py +194 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/__init__.py +2 -2
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/response/renderer.py +2 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/response/templates.py +1 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/wire/validate_in.py +2 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/executor/invoke.py +1 -1
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/executor/types.py +1 -3
- {tigrbl-0.3.4.dev2/tigrbl/runtime/errors → tigrbl-0.3.5/tigrbl/runtime/status}/__init__.py +3 -1
- {tigrbl-0.3.4.dev2/tigrbl/runtime/errors → tigrbl-0.3.5/tigrbl/runtime/status}/converters.py +2 -3
- {tigrbl-0.3.4.dev2/tigrbl/runtime/errors → tigrbl-0.3.5/tigrbl/runtime/status}/exceptions.py +26 -1
- {tigrbl-0.3.4.dev2/tigrbl/runtime/errors → tigrbl-0.3.5/tigrbl/runtime/status}/mappings.py +23 -0
- {tigrbl-0.3.4.dev2/tigrbl/runtime/errors → tigrbl-0.3.5/tigrbl/runtime/status}/utils.py +1 -38
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/system.py +1 -1
- tigrbl-0.3.5/tigrbl/security/__init__.py +297 -0
- tigrbl-0.3.5/tigrbl/security/dependencies.py +21 -0
- tigrbl-0.3.5/tigrbl/system/__init__.py +77 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/diagnostics/compat.py +2 -2
- tigrbl-0.3.5/tigrbl/system/docs/__init__.py +42 -0
- tigrbl-0.3.5/tigrbl/system/docs/lens.py +99 -0
- tigrbl-0.3.5/tigrbl/system/docs/openapi/__init__.py +34 -0
- tigrbl-0.3.5/tigrbl/system/docs/openapi/helpers.py +204 -0
- tigrbl-0.3.5/tigrbl/system/docs/openapi/metadata.py +21 -0
- tigrbl-0.3.5/tigrbl/system/docs/openapi/mount.py +30 -0
- tigrbl-0.3.5/tigrbl/system/docs/openapi/schema.py +138 -0
- {tigrbl-0.3.4.dev2/tigrbl/transport/jsonrpc → tigrbl-0.3.5/tigrbl/system/docs}/openrpc.py +29 -1
- tigrbl-0.3.5/tigrbl/system/docs/swagger.py +68 -0
- tigrbl-0.3.5/tigrbl/system/favicon/__init__.py +41 -0
- tigrbl-0.3.5/tigrbl/transport/__init__.py +121 -0
- tigrbl-0.3.5/tigrbl/transport/asgi_wsgi.py +181 -0
- tigrbl-0.3.5/tigrbl/transport/background.py +29 -0
- tigrbl-0.3.5/tigrbl/transport/httpx.py +25 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/transport/jsonrpc/dispatcher.py +49 -29
- tigrbl-0.3.5/tigrbl/transport/jsonrpc/openrpc.py +3 -0
- tigrbl-0.3.5/tigrbl/transport/request.py +48 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/transport/rest/__init__.py +10 -1
- tigrbl-0.3.5/tigrbl/transport/rest/decorators.py +30 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/__init__.py +8 -13
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/authn_abc.py +1 -1
- tigrbl-0.3.4.dev2/tigrbl/api/__init__.py +0 -6
- tigrbl-0.3.4.dev2/tigrbl/bindings/rest/fastapi.py +0 -76
- tigrbl-0.3.4.dev2/tigrbl/deps/fastapi.py +0 -41
- tigrbl-0.3.4.dev2/tigrbl/deps/starlette.py +0 -36
- tigrbl-0.3.4.dev2/tigrbl/system/__init__.py +0 -13
- tigrbl-0.3.4.dev2/tigrbl/transport/__init__.py +0 -75
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/LICENSE +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/README.md +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/api/api_spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/api/mro_collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/api/shortcuts.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/app/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/app/_model_registry.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/app/app_spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/app/mro_collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/app/shortcuts.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/api/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/api/common.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/api/resource_proxy.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/api/rpc.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/columns.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/handlers/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/handlers/builder.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/handlers/ctx.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/handlers/identifiers.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/handlers/namespaces.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/handlers/steps.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/hooks.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/model.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/model_helpers.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/model_registry.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/rest/attach.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/schemas/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/schemas/builder.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/schemas/defaults.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/bindings/schemas/utils.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/README.md +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/_column.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/column_spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/field_spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/infer/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/infer/core.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/infer/jsonhints.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/infer/planning.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/infer/types.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/infer/utils.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/io_spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/mro_collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/column/shortcuts.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/config/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/config/constants.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/config/defaults.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/config/resolver.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/bulk.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/helpers/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/helpers/db.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/helpers/enum.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/helpers/filters.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/helpers/model.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/helpers/normalize.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/core/crud/ops.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/decorators.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/deps/jinja.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/deps/pydantic.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/deps/sqlalchemy.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/docs/verbosity.md +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/_engine.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/bind.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/capabilities.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/decorators.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/docs/PLUGINS.md +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/plugins.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/engine/registry.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/hook/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/hook/_hook.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/hook/decorators.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/hook/hook_spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/hook/mro_collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/hook/shortcuts.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/hook/types.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/_op.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/canonical.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/decorators.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/model_registry.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/mro_collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/resolver.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/op/types.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/bootstrappable.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/bound.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/edges.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/fields.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/hierarchy.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/key_digest.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/lifecycle.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/locks.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/markers.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/operations.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/principals.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/upsertable.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/mixins/utils.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/_base.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/audit.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/client.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/group.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/org.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/rbac.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/status.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/tenant.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/orm/tables/user.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/response/README.md +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/response/bind.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/response/decorators.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/response/resolver.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/response/types.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/rest/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/README.md +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/emit/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/emit/paired_post.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/emit/paired_pre.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/emit/readtime_alias.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/out/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/out/masking.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/refresh/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/refresh/demand.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/resolve/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/resolve/assemble.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/resolve/paired_gen.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/response/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/response/headers_from_payload.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/response/negotiate.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/response/negotiation.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/response/render.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/response/template.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/schema/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/schema/collect_in.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/schema/collect_out.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/storage/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/storage/to_stored.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/wire/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/wire/build_in.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/wire/build_out.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/atoms/wire/dump.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/context.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/events.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/executor/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/executor/guards.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/executor/helpers.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/kernel.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/labels.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/opview.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/ordering.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/runtime/trace.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/_schema.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/builder/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/builder/build_schema.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/builder/cache.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/builder/compat.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/builder/extras.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/builder/helpers.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/builder/list_params.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/builder/strip_parent_fields.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/decorators.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/get_schema.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/schema_spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/shortcuts.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/types.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/schema/utils.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/session/README.md +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/session/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/session/abc.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/session/base.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/session/decorators.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/session/default.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/session/shortcuts.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/session/spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/shortcuts.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/specs.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/diagnostics/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/diagnostics/healthz.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/diagnostics/hookz.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/diagnostics/kernelz.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/diagnostics/methodz.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/diagnostics/router.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/diagnostics/utils.py +0 -0
- {tigrbl-0.3.4.dev2/tigrbl/deps → tigrbl-0.3.5/tigrbl/system/favicon/assets}/favicon.svg +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/system/uvicorn.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/table/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/table/_base.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/table/_table.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/table/mro_collect.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/table/shortcuts.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/table/table_spec.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/transport/jsonrpc/__init__.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/transport/jsonrpc/helpers.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/transport/jsonrpc/models.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/transport/rest/aggregator.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/allow_anon_provider.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/nested_path_provider.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/op.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/op_config_provider.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/op_verb_alias_provider.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/request_extras_provider.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/response_extras_provider.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/table_config_provider.py +0 -0
- {tigrbl-0.3.4.dev2 → tigrbl-0.3.5}/tigrbl/types/uuid.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tigrbl
|
|
3
|
-
Version: 0.3.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.3.5
|
|
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
|
|
7
|
-
Keywords: tigrbl,sdk,standards
|
|
8
|
-
Author:
|
|
9
|
-
Author-email:
|
|
7
|
+
Keywords: tigrbl,sdk,standards,asgi,rest,rpc
|
|
8
|
+
Author: Jacob Stewart
|
|
9
|
+
Author-email: jacob@swarmauri.com
|
|
10
10
|
Requires-Python: >=3.10,<3.13
|
|
11
11
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
12
|
Classifier: Development Status :: 3 - Alpha
|
|
@@ -21,16 +21,12 @@ Provides-Extra: templates
|
|
|
21
21
|
Provides-Extra: tests
|
|
22
22
|
Requires-Dist: aiosqlite (>=0.19.0)
|
|
23
23
|
Requires-Dist: asyncpg (>=0.30.0) ; extra == "postgres"
|
|
24
|
-
Requires-Dist: fastapi (>=0.100.0)
|
|
25
24
|
Requires-Dist: greenlet (>=3.2.3)
|
|
26
25
|
Requires-Dist: httpx (>=0.27.0)
|
|
27
26
|
Requires-Dist: jinja2 (>=3.1.4) ; extra == "templates"
|
|
28
27
|
Requires-Dist: psycopg2-binary (>=2.9.9) ; extra == "postgres"
|
|
29
28
|
Requires-Dist: pydantic (>=2.0.0)
|
|
30
29
|
Requires-Dist: sqlalchemy (>=2.0)
|
|
31
|
-
Requires-Dist: swarmauri_base
|
|
32
|
-
Requires-Dist: swarmauri_core
|
|
33
|
-
Requires-Dist: swarmauri_standard
|
|
34
30
|
Requires-Dist: tigrbl-tests ; extra == "tests"
|
|
35
31
|
Requires-Dist: uvicorn
|
|
36
32
|
Description-Content-Type: text/markdown
|
|
@@ -53,7 +49,7 @@ Description-Content-Type: text/markdown
|
|
|
53
49
|
---
|
|
54
50
|
|
|
55
51
|
# Tigrbl 🐅🐂
|
|
56
|
-
A high-leverage meta-framework that turns plain SQLAlchemy models into a fully-featured REST+RPC surface with near-zero boilerplate. 🚀
|
|
52
|
+
A high-leverage ASGI meta-framework that turns plain SQLAlchemy models into a fully-featured REST+RPC surface with near-zero boilerplate. 🚀
|
|
57
53
|
|
|
58
54
|
## Features ✨
|
|
59
55
|
|
|
@@ -61,7 +57,7 @@ A high-leverage meta-framework that turns plain SQLAlchemy models into a fully-f
|
|
|
61
57
|
- 🔌 Unified REST and RPC endpoints from a single definition
|
|
62
58
|
- 🪝 Hookable phase system for deep customization
|
|
63
59
|
- 🧩 Pluggable engine and provider abstractions
|
|
64
|
-
- 🚀 Built
|
|
60
|
+
- 🚀 Built as an ASGI-native framework with Pydantic-powered schema generation
|
|
65
61
|
|
|
66
62
|
## Terminology 📚
|
|
67
63
|
|
|
@@ -402,7 +398,232 @@ control headers, status codes, and optional template rendering. See
|
|
|
402
398
|
|
|
403
399
|
* SQLAlchemy for ORM integration.
|
|
404
400
|
* Pydantic for schema generation.
|
|
405
|
-
*
|
|
401
|
+
* ASGI-native routing and dependency injection.
|
|
402
|
+
|
|
403
|
+
## Best Design Practices ✅
|
|
404
|
+
|
|
405
|
+
The following practices are the canonical, production-ready patterns for
|
|
406
|
+
building on Tigrbl. Each rule is explained and demonstrated with
|
|
407
|
+
approved usage. These are not optional—adhering to them keeps the runtime
|
|
408
|
+
predictable, preserves hook lifecycle guarantees, and ensures schema
|
|
409
|
+
consistency across REST and RPC surfaces.
|
|
410
|
+
|
|
411
|
+
### 1) Never import SQLAlchemy directly or bypass Tigrbl APIs
|
|
412
|
+
|
|
413
|
+
**Why:** Direct imports bypass Tigrbl's compatibility layer and make it
|
|
414
|
+
harder to evolve internal dependencies. Use the Tigrbl exports so your
|
|
415
|
+
code stays aligned with the framework’s versioned ASGI API.
|
|
416
|
+
|
|
417
|
+
✅ **Preferred:**
|
|
418
|
+
```python
|
|
419
|
+
from tigrbl import Base, TigrblApp, TigrblApi
|
|
420
|
+
from tigrbl.types import Integer, String, Mapped
|
|
421
|
+
from tigrbl.types import Depends, HTTPException, Request
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
🚫 **Avoid:**
|
|
425
|
+
```python
|
|
426
|
+
from sqlalchemy import Integer, String
|
|
427
|
+
from some_framework import Depends
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### 2) Do not coerce UUIDs manually
|
|
431
|
+
|
|
432
|
+
**Why:** Tigrbl schemas and types already normalize UUIDs. Manual coercion
|
|
433
|
+
creates inconsistent behavior across engines and breaks schema-level
|
|
434
|
+
validation.
|
|
435
|
+
|
|
436
|
+
✅ **Preferred:**
|
|
437
|
+
```python
|
|
438
|
+
from tigrbl.types import PgUUID, uuid4, Mapped
|
|
439
|
+
|
|
440
|
+
class Item(Table):
|
|
441
|
+
__tablename__ = "items"
|
|
442
|
+
id: Mapped[PgUUID] = acol(primary_key=True, default=uuid4)
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
🚫 **Avoid:**
|
|
446
|
+
```python
|
|
447
|
+
from uuid import UUID
|
|
448
|
+
|
|
449
|
+
item_id = UUID(str(payload["id"]))
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### 3) Use engine specs for persistence, not ad-hoc engines
|
|
453
|
+
|
|
454
|
+
**Why:** Engine specs make persistence declarative, testable, and
|
|
455
|
+
compatible with engine resolution across app, API, table, and op scopes.
|
|
456
|
+
|
|
457
|
+
✅ **Preferred:**
|
|
458
|
+
```python
|
|
459
|
+
from tigrbl.engine.shortcuts import engine_spec
|
|
460
|
+
from tigrbl.engine.decorators import engine_ctx
|
|
461
|
+
|
|
462
|
+
spec = engine_spec(kind="postgres", async_=True, host="db", name="app_db")
|
|
463
|
+
|
|
464
|
+
@engine_ctx(spec)
|
|
465
|
+
class App:
|
|
466
|
+
...
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
🚫 **Avoid:**
|
|
470
|
+
```python
|
|
471
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
|
472
|
+
|
|
473
|
+
engine = create_async_engine("postgresql+asyncpg://...")
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### 4) Never call DB session methods directly
|
|
477
|
+
|
|
478
|
+
**Why:** Direct calls bypass the hook lifecycle and the database guards.
|
|
479
|
+
Use model handlers or `app.<Model>.handlers.<op>` so hooks, policies, and
|
|
480
|
+
schema enforcement run consistently.
|
|
481
|
+
|
|
482
|
+
✅ **Preferred:**
|
|
483
|
+
```python
|
|
484
|
+
result = await Item.handlers.create(payload, ctx=request_ctx)
|
|
485
|
+
# or from a Tigrbl app instance:
|
|
486
|
+
result = await app.Item.handlers.create(payload, ctx=request_ctx)
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
🚫 **Avoid:**
|
|
490
|
+
```python
|
|
491
|
+
db.add(item)
|
|
492
|
+
await db.execute(statement)
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### 5) Always use encapsulated payloads as inputs and outputs
|
|
496
|
+
|
|
497
|
+
**Why:** Tigrbl expects request/response envelopes to preserve metadata,
|
|
498
|
+
support policy enforcement, and keep REST/RPC in lockstep.
|
|
499
|
+
|
|
500
|
+
✅ **Preferred:**
|
|
501
|
+
```python
|
|
502
|
+
from tigrbl import get_schema
|
|
503
|
+
|
|
504
|
+
CreateIn = get_schema(Item, "create", "in")
|
|
505
|
+
CreateOut = get_schema(Item, "create", "out")
|
|
506
|
+
|
|
507
|
+
payload = CreateIn(name="Widget")
|
|
508
|
+
result = await Item.handlers.create(payload, ctx=request_ctx)
|
|
509
|
+
response = CreateOut(result=result)
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
🚫 **Avoid:**
|
|
513
|
+
```python
|
|
514
|
+
payload = {"name": "Widget"}
|
|
515
|
+
result = await Item.handlers.create(payload)
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### 6) Encapsulation must use `get_schema(...)`
|
|
519
|
+
|
|
520
|
+
**Why:** `get_schema` guarantees the envelope is aligned to the configured
|
|
521
|
+
schema and respects schema overrides, request extras, and response extras.
|
|
522
|
+
|
|
523
|
+
✅ **Preferred:**
|
|
524
|
+
```python
|
|
525
|
+
ListIn = get_schema(Item, "list", "in")
|
|
526
|
+
ListOut = get_schema(Item, "list", "out")
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
🚫 **Avoid:**
|
|
530
|
+
```python
|
|
531
|
+
from pydantic import BaseModel
|
|
532
|
+
|
|
533
|
+
class ListIn(BaseModel):
|
|
534
|
+
payload: dict
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### 7) `Table` must be the first inherited class for all models
|
|
538
|
+
|
|
539
|
+
**Why:** Tigrbl inspects base classes for lifecycle and configuration.
|
|
540
|
+
Putting `Table` first preserves deterministic MRO behavior.
|
|
541
|
+
|
|
542
|
+
✅ **Preferred:**
|
|
543
|
+
```python
|
|
544
|
+
from tigrbl.orm.tables import Table
|
|
545
|
+
from tigrbl.orm.mixins import Timestamped
|
|
546
|
+
|
|
547
|
+
class Item(Table, Timestamped):
|
|
548
|
+
__tablename__ = "items"
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
🚫 **Avoid:**
|
|
552
|
+
```python
|
|
553
|
+
class Item(Timestamped, Table):
|
|
554
|
+
__tablename__ = "items"
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### 8) Never call `db.flush()` or `db.commit()`
|
|
558
|
+
|
|
559
|
+
**Why:** The hook lifecycle owns transactional boundaries. Manual flush or
|
|
560
|
+
commit short-circuits phase guards and can corrupt the request lifecycle.
|
|
561
|
+
|
|
562
|
+
✅ **Preferred:**
|
|
563
|
+
```python
|
|
564
|
+
@hook_ctx(ops="create", phase="HANDLER")
|
|
565
|
+
async def handler(ctx):
|
|
566
|
+
await Item.handlers.create(ctx["request"].payload, ctx=ctx)
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
🚫 **Avoid:**
|
|
570
|
+
```python
|
|
571
|
+
db.flush()
|
|
572
|
+
db.commit()
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### 9) Use ops for new REST/RPC methods—never add ad-hoc framework routes
|
|
576
|
+
|
|
577
|
+
**Why:** Ops keep routing, schemas, hooks, and policies unified. Custom
|
|
578
|
+
custom framework routes bypass these guarantees.
|
|
579
|
+
|
|
580
|
+
✅ **Preferred:**
|
|
581
|
+
```python
|
|
582
|
+
from tigrbl import op_ctx
|
|
583
|
+
|
|
584
|
+
@op_ctx(name="rotate_keys", method="POST", path="/keys/rotate")
|
|
585
|
+
async def rotate_keys(payload, *, ctx):
|
|
586
|
+
return await Key.handlers.rotate(payload, ctx=ctx)
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
🚫 **Avoid:**
|
|
590
|
+
```python
|
|
591
|
+
from some_framework import APIRouter
|
|
592
|
+
|
|
593
|
+
router = APIRouter()
|
|
594
|
+
|
|
595
|
+
@router.post("/keys/rotate")
|
|
596
|
+
async def rotate_keys(payload):
|
|
597
|
+
...
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### 10) Use context decorators where appropriate
|
|
601
|
+
|
|
602
|
+
**Why:** Context decorators (`engine_ctx`, `schema_ctx`, `op_ctx`,
|
|
603
|
+
`hook_ctx`) provide explicit, declarative binding of behavior and are
|
|
604
|
+
resolved deterministically by the runtime.
|
|
605
|
+
|
|
606
|
+
✅ **Preferred:**
|
|
607
|
+
```python
|
|
608
|
+
from tigrbl import hook_ctx, op_ctx, schema_ctx
|
|
609
|
+
from tigrbl.engine.decorators import engine_ctx
|
|
610
|
+
|
|
611
|
+
@engine_ctx(kind="sqlite", mode="memory")
|
|
612
|
+
class Item(Table):
|
|
613
|
+
__tablename__ = "items"
|
|
614
|
+
|
|
615
|
+
@schema_ctx(ops="create", cfg={"exclude": {"id"}})
|
|
616
|
+
class ItemCreateSchema:
|
|
617
|
+
model = Item
|
|
618
|
+
|
|
619
|
+
@op_ctx(name="export", method="GET", path="/items/export")
|
|
620
|
+
async def export_items(payload, *, ctx):
|
|
621
|
+
return await Item.handlers.list(payload, ctx=ctx)
|
|
622
|
+
|
|
623
|
+
@hook_ctx(ops="create", phase="PRE_HANDLER")
|
|
624
|
+
async def validate(ctx):
|
|
625
|
+
...
|
|
626
|
+
```
|
|
406
627
|
|
|
407
628
|
### Engine & Provider examples 🛠️
|
|
408
629
|
|
|
@@ -499,6 +720,30 @@ async def decorated_create(payload, *, db=None):
|
|
|
499
720
|
...
|
|
500
721
|
```
|
|
501
722
|
|
|
723
|
+
### Swarmauri class + Tigrbl lifecycle integration 🧬
|
|
724
|
+
|
|
725
|
+
If you need to run concrete Swarmauri classes inside Tigrbl's runtime, see:
|
|
726
|
+
|
|
727
|
+
* [`examples/swarmauri_tigrbl_bridge.py`](./examples/swarmauri_tigrbl_bridge.py)
|
|
728
|
+
* [`examples/swarmauri_tigrbl_bridge_smooth.py`](./examples/swarmauri_tigrbl_bridge_smooth.py)
|
|
729
|
+
|
|
730
|
+
The bridge examples cover two integration styles:
|
|
731
|
+
|
|
732
|
+
* **Factory + schema-rich envelope** (`swarmauri_tigrbl_bridge.py`)
|
|
733
|
+
* Swarmauri Pydantic JSON workflows (`model_validate_json`, `model_dump_json`,
|
|
734
|
+
`model_json_schema`) with `HumanMessage`.
|
|
735
|
+
* A Swarmauri `Factory` invocation during `PRE_HANDLER` via `hook_ctx`.
|
|
736
|
+
* Tigrbl default verbs (`create`, `get`, `list`, `update`, `delete`) plus a custom op.
|
|
737
|
+
* `engine_ctx` at model and operation scope.
|
|
738
|
+
* Generated OpenAPI and OpenRPC documents mounted from the same model bindings.
|
|
739
|
+
|
|
740
|
+
* **Smoother direct-model flow** (`swarmauri_tigrbl_bridge_smooth.py`)
|
|
741
|
+
* Uses hooks + default `create` persistence to normalize Swarmauri payloads.
|
|
742
|
+
* Adds a `Conversation` table with a persisted one-to-many relationship to messages.
|
|
743
|
+
* Avoids extra `json_schema` fields in request/response payload contracts.
|
|
744
|
+
* Returns `HumanMessage.model_validate_json(...)` directly from a custom op.
|
|
745
|
+
* Uses the concrete model classes themselves to derive input/output schema docs.
|
|
746
|
+
|
|
502
747
|
## Glossary 📖
|
|
503
748
|
|
|
504
749
|
1. Tables
|
|
@@ -512,5 +757,3 @@ async def decorated_create(payload, *, db=None):
|
|
|
512
757
|
9. Core
|
|
513
758
|
10. Core\_Raw
|
|
514
759
|
|
|
515
|
-
|
|
516
|
-
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
18
|
# Tigrbl 🐅🐂
|
|
19
|
-
A high-leverage meta-framework that turns plain SQLAlchemy models into a fully-featured REST+RPC surface with near-zero boilerplate. 🚀
|
|
19
|
+
A high-leverage ASGI meta-framework that turns plain SQLAlchemy models into a fully-featured REST+RPC surface with near-zero boilerplate. 🚀
|
|
20
20
|
|
|
21
21
|
## Features ✨
|
|
22
22
|
|
|
@@ -24,7 +24,7 @@ A high-leverage meta-framework that turns plain SQLAlchemy models into a fully-f
|
|
|
24
24
|
- 🔌 Unified REST and RPC endpoints from a single definition
|
|
25
25
|
- 🪝 Hookable phase system for deep customization
|
|
26
26
|
- 🧩 Pluggable engine and provider abstractions
|
|
27
|
-
- 🚀 Built
|
|
27
|
+
- 🚀 Built as an ASGI-native framework with Pydantic-powered schema generation
|
|
28
28
|
|
|
29
29
|
## Terminology 📚
|
|
30
30
|
|
|
@@ -365,7 +365,232 @@ control headers, status codes, and optional template rendering. See
|
|
|
365
365
|
|
|
366
366
|
* SQLAlchemy for ORM integration.
|
|
367
367
|
* Pydantic for schema generation.
|
|
368
|
-
*
|
|
368
|
+
* ASGI-native routing and dependency injection.
|
|
369
|
+
|
|
370
|
+
## Best Design Practices ✅
|
|
371
|
+
|
|
372
|
+
The following practices are the canonical, production-ready patterns for
|
|
373
|
+
building on Tigrbl. Each rule is explained and demonstrated with
|
|
374
|
+
approved usage. These are not optional—adhering to them keeps the runtime
|
|
375
|
+
predictable, preserves hook lifecycle guarantees, and ensures schema
|
|
376
|
+
consistency across REST and RPC surfaces.
|
|
377
|
+
|
|
378
|
+
### 1) Never import SQLAlchemy directly or bypass Tigrbl APIs
|
|
379
|
+
|
|
380
|
+
**Why:** Direct imports bypass Tigrbl's compatibility layer and make it
|
|
381
|
+
harder to evolve internal dependencies. Use the Tigrbl exports so your
|
|
382
|
+
code stays aligned with the framework’s versioned ASGI API.
|
|
383
|
+
|
|
384
|
+
✅ **Preferred:**
|
|
385
|
+
```python
|
|
386
|
+
from tigrbl import Base, TigrblApp, TigrblApi
|
|
387
|
+
from tigrbl.types import Integer, String, Mapped
|
|
388
|
+
from tigrbl.types import Depends, HTTPException, Request
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
🚫 **Avoid:**
|
|
392
|
+
```python
|
|
393
|
+
from sqlalchemy import Integer, String
|
|
394
|
+
from some_framework import Depends
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### 2) Do not coerce UUIDs manually
|
|
398
|
+
|
|
399
|
+
**Why:** Tigrbl schemas and types already normalize UUIDs. Manual coercion
|
|
400
|
+
creates inconsistent behavior across engines and breaks schema-level
|
|
401
|
+
validation.
|
|
402
|
+
|
|
403
|
+
✅ **Preferred:**
|
|
404
|
+
```python
|
|
405
|
+
from tigrbl.types import PgUUID, uuid4, Mapped
|
|
406
|
+
|
|
407
|
+
class Item(Table):
|
|
408
|
+
__tablename__ = "items"
|
|
409
|
+
id: Mapped[PgUUID] = acol(primary_key=True, default=uuid4)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
🚫 **Avoid:**
|
|
413
|
+
```python
|
|
414
|
+
from uuid import UUID
|
|
415
|
+
|
|
416
|
+
item_id = UUID(str(payload["id"]))
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### 3) Use engine specs for persistence, not ad-hoc engines
|
|
420
|
+
|
|
421
|
+
**Why:** Engine specs make persistence declarative, testable, and
|
|
422
|
+
compatible with engine resolution across app, API, table, and op scopes.
|
|
423
|
+
|
|
424
|
+
✅ **Preferred:**
|
|
425
|
+
```python
|
|
426
|
+
from tigrbl.engine.shortcuts import engine_spec
|
|
427
|
+
from tigrbl.engine.decorators import engine_ctx
|
|
428
|
+
|
|
429
|
+
spec = engine_spec(kind="postgres", async_=True, host="db", name="app_db")
|
|
430
|
+
|
|
431
|
+
@engine_ctx(spec)
|
|
432
|
+
class App:
|
|
433
|
+
...
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
🚫 **Avoid:**
|
|
437
|
+
```python
|
|
438
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
|
439
|
+
|
|
440
|
+
engine = create_async_engine("postgresql+asyncpg://...")
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### 4) Never call DB session methods directly
|
|
444
|
+
|
|
445
|
+
**Why:** Direct calls bypass the hook lifecycle and the database guards.
|
|
446
|
+
Use model handlers or `app.<Model>.handlers.<op>` so hooks, policies, and
|
|
447
|
+
schema enforcement run consistently.
|
|
448
|
+
|
|
449
|
+
✅ **Preferred:**
|
|
450
|
+
```python
|
|
451
|
+
result = await Item.handlers.create(payload, ctx=request_ctx)
|
|
452
|
+
# or from a Tigrbl app instance:
|
|
453
|
+
result = await app.Item.handlers.create(payload, ctx=request_ctx)
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
🚫 **Avoid:**
|
|
457
|
+
```python
|
|
458
|
+
db.add(item)
|
|
459
|
+
await db.execute(statement)
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### 5) Always use encapsulated payloads as inputs and outputs
|
|
463
|
+
|
|
464
|
+
**Why:** Tigrbl expects request/response envelopes to preserve metadata,
|
|
465
|
+
support policy enforcement, and keep REST/RPC in lockstep.
|
|
466
|
+
|
|
467
|
+
✅ **Preferred:**
|
|
468
|
+
```python
|
|
469
|
+
from tigrbl import get_schema
|
|
470
|
+
|
|
471
|
+
CreateIn = get_schema(Item, "create", "in")
|
|
472
|
+
CreateOut = get_schema(Item, "create", "out")
|
|
473
|
+
|
|
474
|
+
payload = CreateIn(name="Widget")
|
|
475
|
+
result = await Item.handlers.create(payload, ctx=request_ctx)
|
|
476
|
+
response = CreateOut(result=result)
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
🚫 **Avoid:**
|
|
480
|
+
```python
|
|
481
|
+
payload = {"name": "Widget"}
|
|
482
|
+
result = await Item.handlers.create(payload)
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### 6) Encapsulation must use `get_schema(...)`
|
|
486
|
+
|
|
487
|
+
**Why:** `get_schema` guarantees the envelope is aligned to the configured
|
|
488
|
+
schema and respects schema overrides, request extras, and response extras.
|
|
489
|
+
|
|
490
|
+
✅ **Preferred:**
|
|
491
|
+
```python
|
|
492
|
+
ListIn = get_schema(Item, "list", "in")
|
|
493
|
+
ListOut = get_schema(Item, "list", "out")
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
🚫 **Avoid:**
|
|
497
|
+
```python
|
|
498
|
+
from pydantic import BaseModel
|
|
499
|
+
|
|
500
|
+
class ListIn(BaseModel):
|
|
501
|
+
payload: dict
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### 7) `Table` must be the first inherited class for all models
|
|
505
|
+
|
|
506
|
+
**Why:** Tigrbl inspects base classes for lifecycle and configuration.
|
|
507
|
+
Putting `Table` first preserves deterministic MRO behavior.
|
|
508
|
+
|
|
509
|
+
✅ **Preferred:**
|
|
510
|
+
```python
|
|
511
|
+
from tigrbl.orm.tables import Table
|
|
512
|
+
from tigrbl.orm.mixins import Timestamped
|
|
513
|
+
|
|
514
|
+
class Item(Table, Timestamped):
|
|
515
|
+
__tablename__ = "items"
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
🚫 **Avoid:**
|
|
519
|
+
```python
|
|
520
|
+
class Item(Timestamped, Table):
|
|
521
|
+
__tablename__ = "items"
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### 8) Never call `db.flush()` or `db.commit()`
|
|
525
|
+
|
|
526
|
+
**Why:** The hook lifecycle owns transactional boundaries. Manual flush or
|
|
527
|
+
commit short-circuits phase guards and can corrupt the request lifecycle.
|
|
528
|
+
|
|
529
|
+
✅ **Preferred:**
|
|
530
|
+
```python
|
|
531
|
+
@hook_ctx(ops="create", phase="HANDLER")
|
|
532
|
+
async def handler(ctx):
|
|
533
|
+
await Item.handlers.create(ctx["request"].payload, ctx=ctx)
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
🚫 **Avoid:**
|
|
537
|
+
```python
|
|
538
|
+
db.flush()
|
|
539
|
+
db.commit()
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### 9) Use ops for new REST/RPC methods—never add ad-hoc framework routes
|
|
543
|
+
|
|
544
|
+
**Why:** Ops keep routing, schemas, hooks, and policies unified. Custom
|
|
545
|
+
custom framework routes bypass these guarantees.
|
|
546
|
+
|
|
547
|
+
✅ **Preferred:**
|
|
548
|
+
```python
|
|
549
|
+
from tigrbl import op_ctx
|
|
550
|
+
|
|
551
|
+
@op_ctx(name="rotate_keys", method="POST", path="/keys/rotate")
|
|
552
|
+
async def rotate_keys(payload, *, ctx):
|
|
553
|
+
return await Key.handlers.rotate(payload, ctx=ctx)
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
🚫 **Avoid:**
|
|
557
|
+
```python
|
|
558
|
+
from some_framework import APIRouter
|
|
559
|
+
|
|
560
|
+
router = APIRouter()
|
|
561
|
+
|
|
562
|
+
@router.post("/keys/rotate")
|
|
563
|
+
async def rotate_keys(payload):
|
|
564
|
+
...
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### 10) Use context decorators where appropriate
|
|
568
|
+
|
|
569
|
+
**Why:** Context decorators (`engine_ctx`, `schema_ctx`, `op_ctx`,
|
|
570
|
+
`hook_ctx`) provide explicit, declarative binding of behavior and are
|
|
571
|
+
resolved deterministically by the runtime.
|
|
572
|
+
|
|
573
|
+
✅ **Preferred:**
|
|
574
|
+
```python
|
|
575
|
+
from tigrbl import hook_ctx, op_ctx, schema_ctx
|
|
576
|
+
from tigrbl.engine.decorators import engine_ctx
|
|
577
|
+
|
|
578
|
+
@engine_ctx(kind="sqlite", mode="memory")
|
|
579
|
+
class Item(Table):
|
|
580
|
+
__tablename__ = "items"
|
|
581
|
+
|
|
582
|
+
@schema_ctx(ops="create", cfg={"exclude": {"id"}})
|
|
583
|
+
class ItemCreateSchema:
|
|
584
|
+
model = Item
|
|
585
|
+
|
|
586
|
+
@op_ctx(name="export", method="GET", path="/items/export")
|
|
587
|
+
async def export_items(payload, *, ctx):
|
|
588
|
+
return await Item.handlers.list(payload, ctx=ctx)
|
|
589
|
+
|
|
590
|
+
@hook_ctx(ops="create", phase="PRE_HANDLER")
|
|
591
|
+
async def validate(ctx):
|
|
592
|
+
...
|
|
593
|
+
```
|
|
369
594
|
|
|
370
595
|
### Engine & Provider examples 🛠️
|
|
371
596
|
|
|
@@ -462,6 +687,30 @@ async def decorated_create(payload, *, db=None):
|
|
|
462
687
|
...
|
|
463
688
|
```
|
|
464
689
|
|
|
690
|
+
### Swarmauri class + Tigrbl lifecycle integration 🧬
|
|
691
|
+
|
|
692
|
+
If you need to run concrete Swarmauri classes inside Tigrbl's runtime, see:
|
|
693
|
+
|
|
694
|
+
* [`examples/swarmauri_tigrbl_bridge.py`](./examples/swarmauri_tigrbl_bridge.py)
|
|
695
|
+
* [`examples/swarmauri_tigrbl_bridge_smooth.py`](./examples/swarmauri_tigrbl_bridge_smooth.py)
|
|
696
|
+
|
|
697
|
+
The bridge examples cover two integration styles:
|
|
698
|
+
|
|
699
|
+
* **Factory + schema-rich envelope** (`swarmauri_tigrbl_bridge.py`)
|
|
700
|
+
* Swarmauri Pydantic JSON workflows (`model_validate_json`, `model_dump_json`,
|
|
701
|
+
`model_json_schema`) with `HumanMessage`.
|
|
702
|
+
* A Swarmauri `Factory` invocation during `PRE_HANDLER` via `hook_ctx`.
|
|
703
|
+
* Tigrbl default verbs (`create`, `get`, `list`, `update`, `delete`) plus a custom op.
|
|
704
|
+
* `engine_ctx` at model and operation scope.
|
|
705
|
+
* Generated OpenAPI and OpenRPC documents mounted from the same model bindings.
|
|
706
|
+
|
|
707
|
+
* **Smoother direct-model flow** (`swarmauri_tigrbl_bridge_smooth.py`)
|
|
708
|
+
* Uses hooks + default `create` persistence to normalize Swarmauri payloads.
|
|
709
|
+
* Adds a `Conversation` table with a persisted one-to-many relationship to messages.
|
|
710
|
+
* Avoids extra `json_schema` fields in request/response payload contracts.
|
|
711
|
+
* Returns `HumanMessage.model_validate_json(...)` directly from a custom op.
|
|
712
|
+
* Uses the concrete model classes themselves to derive input/output schema docs.
|
|
713
|
+
|
|
465
714
|
## Glossary 📖
|
|
466
715
|
|
|
467
716
|
1. Tables
|
|
@@ -474,5 +723,3 @@ async def decorated_create(payload, *, db=None):
|
|
|
474
723
|
8. Default Flush
|
|
475
724
|
9. Core
|
|
476
725
|
10. Core\_Raw
|
|
477
|
-
|
|
478
|
-
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tigrbl"
|
|
3
|
-
version = "0.3.
|
|
4
|
-
description = "
|
|
3
|
+
version = "0.3.5"
|
|
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"
|
|
7
7
|
repository = "http://github.com/swarmauri/swarmauri-sdk"
|
|
@@ -16,12 +16,8 @@ classifiers = [
|
|
|
16
16
|
"Programming Language :: Python :: 3",
|
|
17
17
|
"Programming Language :: Python :: 3 :: Only",
|
|
18
18
|
]
|
|
19
|
-
authors = [{ name = "
|
|
19
|
+
authors = [{ name = "Jacob Stewart", email = "jacob@swarmauri.com" }]
|
|
20
20
|
dependencies = [
|
|
21
|
-
"swarmauri_core",
|
|
22
|
-
"swarmauri_base",
|
|
23
|
-
"swarmauri_standard",
|
|
24
|
-
"fastapi>=0.100.0",
|
|
25
21
|
"pydantic>=2.0.0",
|
|
26
22
|
"sqlalchemy>=2.0",
|
|
27
23
|
"aiosqlite>=0.19.0",
|
|
@@ -33,6 +29,9 @@ keywords = [
|
|
|
33
29
|
'tigrbl',
|
|
34
30
|
'sdk',
|
|
35
31
|
'standards',
|
|
32
|
+
'asgi',
|
|
33
|
+
'rest',
|
|
34
|
+
'rpc',
|
|
36
35
|
]
|
|
37
36
|
|
|
38
37
|
[project.optional-dependencies]
|
|
@@ -48,9 +47,6 @@ tests = [
|
|
|
48
47
|
]
|
|
49
48
|
|
|
50
49
|
[tool.uv.sources]
|
|
51
|
-
swarmauri_core = { workspace = true }
|
|
52
|
-
swarmauri_base = { workspace = true }
|
|
53
|
-
swarmauri_standard = { workspace = true }
|
|
54
50
|
tigrbl-tests = { workspace = true }
|
|
55
51
|
|
|
56
52
|
[tool.pytest.ini_options]
|
|
@@ -9,7 +9,7 @@ Quick start:
|
|
|
9
9
|
from tigrbl import include_model, build_jsonrpc_router, mount_diagnostics
|
|
10
10
|
from tigrbl import OpSpec, hook_ctx, op_ctx, alias_ctx, schema_ctx, SchemaRef
|
|
11
11
|
|
|
12
|
-
include_model(api, User, app=
|
|
12
|
+
include_model(api, User, app=asgi_app)
|
|
13
13
|
app.include_router(build_jsonrpc_router(api), prefix="/rpc")
|
|
14
14
|
app.include_router(mount_diagnostics(api), prefix="/system")
|
|
15
15
|
|
|
@@ -80,12 +80,23 @@ from .api import Api, TigrblApi
|
|
|
80
80
|
|
|
81
81
|
from .table import Base
|
|
82
82
|
from .op import Op
|
|
83
|
-
from .
|
|
83
|
+
from .security import APIKey, HTTPBearer, MutualTLS, OAuth2, OpenIdConnect
|
|
84
84
|
|
|
85
85
|
|
|
86
86
|
__all__: list[str] = []
|
|
87
87
|
|
|
88
|
-
__all__ += [
|
|
88
|
+
__all__ += [
|
|
89
|
+
"TigrblApp",
|
|
90
|
+
"TigrblApi",
|
|
91
|
+
"Api",
|
|
92
|
+
"Base",
|
|
93
|
+
"Op",
|
|
94
|
+
"HTTPBearer",
|
|
95
|
+
"APIKey",
|
|
96
|
+
"OAuth2",
|
|
97
|
+
"OpenIdConnect",
|
|
98
|
+
"MutualTLS",
|
|
99
|
+
]
|
|
89
100
|
|
|
90
101
|
__all__ += [
|
|
91
102
|
# OpSpec core
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Core API surfaces for the Tigrbl package."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
__all__ = ["Api", "TigrblApi"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def __getattr__(name: str) -> Any:
|
|
11
|
+
if name == "Api":
|
|
12
|
+
from ._api import Api
|
|
13
|
+
|
|
14
|
+
return Api
|
|
15
|
+
if name == "TigrblApi":
|
|
16
|
+
from .tigrbl_api import TigrblApi
|
|
17
|
+
|
|
18
|
+
return TigrblApi
|
|
19
|
+
raise AttributeError(name)
|