fastapi-admin-kit 0.2.0__tar.gz → 0.2.1__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.
- fastapi_admin_kit-0.2.1/CHANGELOG.md +51 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/LICENSE +1 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/PKG-INFO +106 -24
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/README.md +98 -20
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/__init__.py +1 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/admin_database.py +27 -6
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/admin_template.py +6 -3
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/builtin_models.py +78 -111
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/core.py +6 -4
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/api/auth.py +4 -2
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/listener.py +41 -12
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/backend.py +0 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/csrf.py +44 -8
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/identity.py +8 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/mixins.py +65 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/models.py +11 -8
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/permissions.py +6 -2
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/ratelimit.py +17 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/session.py +29 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/views.py +18 -6
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/cli/__init__.py +1 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/cli/helpers.py +71 -2
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/cli/migrate.py +41 -22
- fastapi_admin_kit-0.2.1/fastapi_admin_kit/cli/permissions.py +324 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/cli/user.py +44 -33
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/auth.py +1 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/flash.py +2 -2
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/modeladmin.py +1 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/static/js/admin.js +15 -43
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/users/form.html +16 -66
- fastapi_admin_kit-0.2.1/fastapi_admin_kit/templates/partials/permission_widget.html +65 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/topbar.html +5 -5
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/types.py +12 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/__init__.py +0 -14
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/audit.py +13 -12
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/class_views.py +70 -4
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/profile.py +1 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/roles.py +4 -4
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/sidebar.py +13 -8
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/mkdocs.yml +9 -1
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/pyproject.toml +14 -9
- fastapi_admin_kit-0.2.0/fastapi_admin_kit/admin.py +0 -716
- fastapi_admin_kit-0.2.0/fastapi_admin_kit/cli/permissions.py +0 -184
- fastapi_admin_kit-0.2.0/fastapi_admin_kit/templates/partials/permission_widget.html +0 -113
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/.gitignore +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/actions/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/actions/base.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/actions/registry.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/admin_config.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/admin_router.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/decorators.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/state.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/api/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/api/crud.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/api/deps.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/api/roles.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/api/schema_generator.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/api/schemas.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/api/search.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/context.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/diff.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/event_bus.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/events.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/logger.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/middleware.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/models.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/audit/sqlalchemy_logger.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/dependencies.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/hasher.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/password.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/protocol.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/router.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/auth/totp.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/cli/__main__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/cli/scaffold.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/audit.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/behavior.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/database.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/nav.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/storage.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/theme.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/config/ui.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/dashboard/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/db.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/exceptions.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/field_types.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/filters/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/filters/base.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/filters/registry.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/form/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/form/pipeline.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/inspection/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/inspection/registry.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/inspection.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/models/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/models/base.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/nav.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/pagination/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/pagination/base.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/pagination/cursor.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/pagination/dynamic.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/pagination/offset.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/plugins/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/py.typed +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/registry/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/registry/core.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/registry/validation.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/registry.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/router.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/search_utils.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/static/css/admin.css +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/static/css/presets.css +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/static/css/tokens.css +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/static/css/variables.css +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/static/icons/heroicons.svg +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/static/js/htmx-config.js +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/storage/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/storage/base.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/storage/local.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/base.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/macros/form_fields.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/macros/icons.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/macros/table.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/macros/widgets.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/2fa/setup.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/2fa/verify.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/403.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/audit_detail.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/audit_log.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/dashboard.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/detail.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/form.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/list.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/login.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/profile/password.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/profile/profile.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/role_form.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/roles/form.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/roles/list.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/roles.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/search.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/settings/theme.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/pages/users/list.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/_inline_edit_row.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/command_palette.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/field_wrapper.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/flash_messages.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/head.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/head_minimal.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/inline_edit_form.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/list_table.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/mobile_backdrop.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/pagination.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/perm_select_widget.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/scripts.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/templates/partials/sidebar.html +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/validation.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/bulk.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/context.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/dashboard.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/delete.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/extra.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/factory.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/form.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/list.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/protocols.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/renderers.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/search.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/settings.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/totp.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views/users.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/views.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/widgets/__init__.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/widgets/base.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/widgets/inputs.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/widgets/registry.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/widgets/relation.py +0 -0
- {fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/widgets/resolver.py +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.1] - 2026-07-20
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Zero-config auto-discovery of SQLAlchemy models
|
|
12
|
+
- Built-in authentication with session-based cookies
|
|
13
|
+
- Role-based access control (RBAC) with per-model permissions
|
|
14
|
+
- Direct per-user permission overrides
|
|
15
|
+
- Audit logging with full change diffs
|
|
16
|
+
- Modern UI with Tailwind CSS, HTMX, and Alpine.js
|
|
17
|
+
- Global search / command palette (`Cmd+K` / `Ctrl+K`)
|
|
18
|
+
- Inline editing from list view with 3-dot action menu
|
|
19
|
+
- CLI tools (`fak-admin` / `fak`) for user management
|
|
20
|
+
- Async-first architecture with PostgreSQL, MySQL, and SQLite support
|
|
21
|
+
- SQLModel support via optional extra
|
|
22
|
+
- Custom widgets, themes, and templates
|
|
23
|
+
- Search and filtering with relation field lookups
|
|
24
|
+
- Bulk operations
|
|
25
|
+
- Dark mode with theme presets
|
|
26
|
+
- Pagination strategies (offset, cursor, dynamic)
|
|
27
|
+
- File uploads with local storage backend
|
|
28
|
+
- Plugin system for extensibility
|
|
29
|
+
- CSRF protection on all state-changing requests
|
|
30
|
+
- Rate limiting on authentication endpoints
|
|
31
|
+
- Environment badge for staging/production identification
|
|
32
|
+
|
|
33
|
+
### Security
|
|
34
|
+
- SQL injection prevention via identifier validation in CLI migrate and auto-migrate
|
|
35
|
+
- Secure session cookies with `SameSite=Strict` and `Secure` by default
|
|
36
|
+
- CSRF protection on all state-changing requests
|
|
37
|
+
- Rate limiting on authentication endpoints
|
|
38
|
+
- bcrypt password hashing
|
|
39
|
+
- Secret key validated to be >= 32 characters at startup
|
|
40
|
+
- Removed weak default credentials from examples
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
- `uvicorn` and `pyjwt` moved to optional `[full]` extra (no longer hard dependencies)
|
|
44
|
+
- All library code uses `logging` instead of `print()` statements
|
|
45
|
+
- Silent exception blocks now log at debug level instead of silently swallowing
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
- `__all__` in `views/__init__.py` no longer references undefined symbols
|
|
49
|
+
- Debug print statement removed from `cli/helpers.py`
|
|
50
|
+
- Line length violations in `admin/builtin_models.py`
|
|
51
|
+
- Import sorting in `admin/admin_database.py` and `cli/migrate.py`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastapi-admin-kit
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Drop-in admin panel for FastAPI + SQLAlchemy + SQLModel apps
|
|
5
5
|
Project-URL: Homepage, https://github.com/borhanst/fastapi-admin-kit
|
|
6
6
|
Project-URL: Documentation, https://borhanst.github.io/fastapi-admin-kit/
|
|
@@ -10,7 +10,7 @@ Author-email: Borhan <mdborhan.st@gmail.com>
|
|
|
10
10
|
License: MIT
|
|
11
11
|
License-File: LICENSE
|
|
12
12
|
Keywords: admin,admin-panel,async,crud,dashboard,fastapi,rbac,sqlalchemy,sqlmodel
|
|
13
|
-
Classifier: Development Status ::
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
14
|
Classifier: Framework :: AsyncIO
|
|
15
15
|
Classifier: Framework :: FastAPI
|
|
16
16
|
Classifier: Intended Audience :: Developers
|
|
@@ -28,21 +28,25 @@ Requires-Dist: bcrypt>=4.0.0
|
|
|
28
28
|
Requires-Dist: fastapi>=0.100.0
|
|
29
29
|
Requires-Dist: itsdangerous>=2.2.0
|
|
30
30
|
Requires-Dist: jinja2>=3.1.0
|
|
31
|
-
Requires-Dist:
|
|
31
|
+
Requires-Dist: pre-commit>=4.6.0
|
|
32
32
|
Requires-Dist: python-multipart>=0.0.9
|
|
33
33
|
Requires-Dist: sqlalchemy>=2.0.0
|
|
34
|
-
Requires-Dist: uvicorn>=0.30.0
|
|
35
34
|
Provides-Extra: dev
|
|
36
35
|
Requires-Dist: hatch>=1.13.0; extra == 'dev'
|
|
37
36
|
Requires-Dist: httpx>=0.27.0; extra == 'dev'
|
|
38
37
|
Requires-Dist: pre-commit>=3.5.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pyjwt>=2.13.0; extra == 'dev'
|
|
39
39
|
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
40
41
|
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
41
42
|
Requires-Dist: ruff>=0.5.0; extra == 'dev'
|
|
42
43
|
Provides-Extra: docs
|
|
43
44
|
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
|
|
44
45
|
Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
|
|
45
46
|
Requires-Dist: mkdocstrings[python]>=0.25.0; extra == 'docs'
|
|
47
|
+
Provides-Extra: full
|
|
48
|
+
Requires-Dist: pyjwt>=2.13.0; extra == 'full'
|
|
49
|
+
Requires-Dist: uvicorn>=0.30.0; extra == 'full'
|
|
46
50
|
Provides-Extra: mysql
|
|
47
51
|
Requires-Dist: aiomysql>=0.2.0; extra == 'mysql'
|
|
48
52
|
Provides-Extra: postgres
|
|
@@ -56,40 +60,74 @@ Description-Content-Type: text/markdown
|
|
|
56
60
|
[](https://pypi.org/project/fastapi-admin-kit/)
|
|
57
61
|
[](https://pypi.org/project/fastapi-admin-kit/)
|
|
58
62
|
[](https://github.com/borhanst/fastapi-admin-kit/blob/main/LICENSE)
|
|
63
|
+
[](https://github.com/borhanst/fastapi-admin-kit/actions/workflows/tests.yml)
|
|
59
64
|
|
|
60
|
-
A drop-in admin panel for FastAPI + SQLAlchemy apps, inspired by Django Unfold.
|
|
65
|
+
A drop-in admin panel for FastAPI + SQLAlchemy + SQLModel apps, inspired by Django Unfold.
|
|
61
66
|
|
|
62
|
-
|
|
67
|
+

|
|
63
68
|
|
|
64
69
|
📖 **[Documentation](https://borhanst.github.io/fastapi-admin-kit/)** | 🚀 **[Quick Start](#quick-start)** | 📦 **[PyPI](https://pypi.org/project/fastapi-admin-kit/)**
|
|
65
70
|
|
|
66
71
|
## Features
|
|
67
72
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
73
|
+
> See the **[Full Features List](https://borhanst.github.io/fastapi-admin-kit/guide/features/)** for every feature with detailed docs links.
|
|
74
|
+
|
|
75
|
+
- **Zero-Config Auto-Discovery** — Register a model, get full CRUD UI automatically
|
|
76
|
+
- **SQLAlchemy & SQLModel** — Works with both ORMs out of the box
|
|
77
|
+
- **Built-in Auth & RBAC** — Session-based auth with role-based permissions per model
|
|
78
|
+
- **Audit Logging** — Every create, update, and delete is recorded with full diffs
|
|
79
|
+
- **Modern UI** — Tailwind CSS, HTMX, and Alpine.js with dark mode
|
|
80
|
+
- **17 Built-in Widgets** — TextInput, Toggle, DatePicker, FileUpload, Wysiwyg, and more
|
|
81
|
+
- **Inline Editing** — Edit records directly from list view with 3-dot action menu
|
|
82
|
+
- **Command Palette** — `Cmd+K` / `Ctrl+K` global search across models and fields
|
|
83
|
+
- **JSON API** — REST endpoints with JWT token auth for external frontends
|
|
84
|
+
- **Dashboard** — Configurable stat cards, charts, tables, and progress bars
|
|
85
|
+
- **CLI Tools** — `fak-admin` / `fak` for superuser management and project scaffolding
|
|
86
|
+
- **Pagination** — Offset, cursor, or dynamic strategies per model
|
|
87
|
+
- **Filters** — Text, boolean, relation, and enum sidebar filters
|
|
88
|
+
- **File Uploads** — Built-in local storage backend with upload widgets
|
|
89
|
+
- **Async-First** — PostgreSQL, MySQL, and SQLite with auto URL normalization
|
|
90
|
+
- **CSRF & Rate Limiting** — Security built-in out of the box
|
|
75
91
|
|
|
76
92
|
## Installation
|
|
77
93
|
|
|
78
94
|
```bash
|
|
95
|
+
# pip
|
|
79
96
|
pip install fastapi-admin-kit
|
|
97
|
+
|
|
98
|
+
# uv
|
|
99
|
+
uv add fastapi-admin-kit
|
|
80
100
|
```
|
|
81
101
|
|
|
82
102
|
For database-specific async drivers:
|
|
83
103
|
|
|
84
104
|
```bash
|
|
105
|
+
# pip
|
|
85
106
|
pip install fastapi-admin-kit[postgres] # PostgreSQL via asyncpg
|
|
86
107
|
pip install fastapi-admin-kit[mysql] # MySQL via aiomysql
|
|
108
|
+
|
|
109
|
+
# uv
|
|
110
|
+
uv add fastapi-admin-kit[postgres] # PostgreSQL via asyncpg
|
|
111
|
+
uv add fastapi-admin-kit[mysql] # MySQL via aiomysql
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
For the full experience with uvicorn and JWT support:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# pip
|
|
118
|
+
pip install fastapi-admin-kit[full]
|
|
119
|
+
|
|
120
|
+
# uv
|
|
121
|
+
uv add fastapi-admin-kit[full]
|
|
87
122
|
```
|
|
88
123
|
|
|
89
124
|
## Quick Start
|
|
90
125
|
|
|
91
126
|
```python
|
|
127
|
+
import os
|
|
128
|
+
import secrets
|
|
92
129
|
from contextlib import asynccontextmanager
|
|
130
|
+
|
|
93
131
|
from fastapi import FastAPI
|
|
94
132
|
from sqlalchemy import Column, Float, Integer, String
|
|
95
133
|
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
|
@@ -123,8 +161,8 @@ class Product(Base):
|
|
|
123
161
|
price = Column(Float, nullable=False)
|
|
124
162
|
|
|
125
163
|
|
|
126
|
-
DATABASE_URL = "sqlite+aiosqlite:///./app.db"
|
|
127
|
-
SECRET_KEY = "
|
|
164
|
+
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite+aiosqlite:///./app.db")
|
|
165
|
+
SECRET_KEY = os.getenv("SECRET_KEY", secrets.token_urlsafe(32))
|
|
128
166
|
|
|
129
167
|
engine = create_async_engine(DATABASE_URL)
|
|
130
168
|
async_session = sessionmaker(engine, class_=AsyncSession)
|
|
@@ -151,6 +189,21 @@ admin = Admin(
|
|
|
151
189
|
admin.register(Product)
|
|
152
190
|
```
|
|
153
191
|
|
|
192
|
+
Run with:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
pip install fastapi-admin-kit[full]
|
|
196
|
+
uvicorn main:app --reload
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Open [http://localhost:8000/admin/](http://localhost:8000/admin/) and log in with:
|
|
200
|
+
|
|
201
|
+
- **Email:** `admin@example.com`
|
|
202
|
+
- **Password:** `admin`
|
|
203
|
+
|
|
204
|
+
!!! warning
|
|
205
|
+
Change the default password immediately in production!
|
|
206
|
+
|
|
154
207
|
## CLI Usage
|
|
155
208
|
|
|
156
209
|
Both the full name and the short alias work interchangeably:
|
|
@@ -167,6 +220,13 @@ fak users
|
|
|
167
220
|
# Change a user's password
|
|
168
221
|
fak-admin changepassword -e admin@example.com -p newpassword
|
|
169
222
|
fak changepassword -e admin@example.com -p newpassword
|
|
223
|
+
|
|
224
|
+
# Scaffold a new fastapi project
|
|
225
|
+
fak init myproject
|
|
226
|
+
|
|
227
|
+
# Permission management
|
|
228
|
+
fak createpermissions --base myapp.models.Base
|
|
229
|
+
fak createpermissions myapp.models.User myapp.models.Product
|
|
170
230
|
```
|
|
171
231
|
|
|
172
232
|
All commands accept `-d DATABASE_URL` or read the `DATABASE_URL` environment variable.
|
|
@@ -178,11 +238,14 @@ All commands accept `-d DATABASE_URL` or read the `DATABASE_URL` environment var
|
|
|
178
238
|
| Variable | Description | Default |
|
|
179
239
|
|---|---|---|
|
|
180
240
|
| `DATABASE_URL` | Async database connection string | `sqlite+aiosqlite:///./app.db` |
|
|
181
|
-
| `SECRET_KEY` | Signing key for sessions/CSRF/JWT (min 32 chars) |
|
|
241
|
+
| `SECRET_KEY` | Signing key for sessions/CSRF/JWT (min 32 chars) | Auto-generated if unset |
|
|
182
242
|
|
|
183
243
|
### Admin Options
|
|
184
244
|
|
|
185
245
|
```python
|
|
246
|
+
from fastapi_admin_kit import Admin
|
|
247
|
+
from fastapi_admin_kit.config import ThemeConfig
|
|
248
|
+
|
|
186
249
|
admin = Admin(
|
|
187
250
|
app=app,
|
|
188
251
|
engine=engine,
|
|
@@ -191,8 +254,6 @@ admin = Admin(
|
|
|
191
254
|
title="My Admin", # Admin panel title
|
|
192
255
|
admin_path="/admin", # URL prefix
|
|
193
256
|
dark_mode_default=False, # Dark mode on by default
|
|
194
|
-
# Theme
|
|
195
|
-
theme=ThemeConfig(preset="modern", primary_color="#6366F1"),
|
|
196
257
|
# Auth
|
|
197
258
|
auth_backend=BuiltinAuthBackend(),
|
|
198
259
|
# Environment badge
|
|
@@ -207,21 +268,42 @@ admin = Admin(
|
|
|
207
268
|
- **PostgreSQL**: `pip install fastapi-admin-kit[postgres]` + set `DATABASE_URL=postgresql+asyncpg://...`
|
|
208
269
|
- **MySQL**: `pip install fastapi-admin-kit[mysql]` + set `DATABASE_URL=mysql+aiomysql://...`
|
|
209
270
|
|
|
271
|
+
### Optional Dependencies
|
|
272
|
+
|
|
273
|
+
| Extra | Packages | When to use |
|
|
274
|
+
|---|---|---|
|
|
275
|
+
| `full` | `uvicorn`, `pyjwt` | Running the dev server or using JWT API auth |
|
|
276
|
+
| `postgres` | `asyncpg` | PostgreSQL databases |
|
|
277
|
+
| `mysql` | `aiomysql` | MySQL databases |
|
|
278
|
+
| `sqlmodel` | `sqlmodel` | Using SQLModel models |
|
|
279
|
+
| `docs` | `mkdocs`, `mkdocs-material` | Building documentation |
|
|
280
|
+
|
|
281
|
+
## Security
|
|
282
|
+
|
|
283
|
+
- Session cookies use `SameSite=Strict` and `Secure` by default
|
|
284
|
+
- CSRF protection on all state-changing requests
|
|
285
|
+
- Rate limiting on authentication endpoints
|
|
286
|
+
- Passwords hashed with bcrypt
|
|
287
|
+
- SQL injection prevention via identifier validation
|
|
288
|
+
- Secret key validated to be >= 32 characters at startup
|
|
289
|
+
|
|
210
290
|
## Development
|
|
211
291
|
|
|
212
292
|
```bash
|
|
213
293
|
# Install with dev dependencies
|
|
214
|
-
|
|
294
|
+
uv sync
|
|
215
295
|
|
|
216
|
-
# Run tests
|
|
217
|
-
pytest
|
|
296
|
+
# Run tests with coverage
|
|
297
|
+
uv run pytest --cov=fastapi_admin_kit
|
|
218
298
|
|
|
219
299
|
# Lint
|
|
220
|
-
ruff check fastapi_admin_kit/
|
|
300
|
+
uv run ruff check fastapi_admin_kit/
|
|
301
|
+
|
|
302
|
+
# Format
|
|
303
|
+
uv run ruff format fastapi_admin_kit/
|
|
221
304
|
|
|
222
305
|
# Build distribution
|
|
223
|
-
|
|
224
|
-
hatch build
|
|
306
|
+
uv build
|
|
225
307
|
```
|
|
226
308
|
|
|
227
309
|
## License
|
|
@@ -3,40 +3,74 @@
|
|
|
3
3
|
[](https://pypi.org/project/fastapi-admin-kit/)
|
|
4
4
|
[](https://pypi.org/project/fastapi-admin-kit/)
|
|
5
5
|
[](https://github.com/borhanst/fastapi-admin-kit/blob/main/LICENSE)
|
|
6
|
+
[](https://github.com/borhanst/fastapi-admin-kit/actions/workflows/tests.yml)
|
|
6
7
|
|
|
7
|
-
A drop-in admin panel for FastAPI + SQLAlchemy apps, inspired by Django Unfold.
|
|
8
|
+
A drop-in admin panel for FastAPI + SQLAlchemy + SQLModel apps, inspired by Django Unfold.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+

|
|
10
11
|
|
|
11
12
|
📖 **[Documentation](https://borhanst.github.io/fastapi-admin-kit/)** | 🚀 **[Quick Start](#quick-start)** | 📦 **[PyPI](https://pypi.org/project/fastapi-admin-kit/)**
|
|
12
13
|
|
|
13
14
|
## Features
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
16
|
+
> See the **[Full Features List](https://borhanst.github.io/fastapi-admin-kit/guide/features/)** for every feature with detailed docs links.
|
|
17
|
+
|
|
18
|
+
- **Zero-Config Auto-Discovery** — Register a model, get full CRUD UI automatically
|
|
19
|
+
- **SQLAlchemy & SQLModel** — Works with both ORMs out of the box
|
|
20
|
+
- **Built-in Auth & RBAC** — Session-based auth with role-based permissions per model
|
|
21
|
+
- **Audit Logging** — Every create, update, and delete is recorded with full diffs
|
|
22
|
+
- **Modern UI** — Tailwind CSS, HTMX, and Alpine.js with dark mode
|
|
23
|
+
- **17 Built-in Widgets** — TextInput, Toggle, DatePicker, FileUpload, Wysiwyg, and more
|
|
24
|
+
- **Inline Editing** — Edit records directly from list view with 3-dot action menu
|
|
25
|
+
- **Command Palette** — `Cmd+K` / `Ctrl+K` global search across models and fields
|
|
26
|
+
- **JSON API** — REST endpoints with JWT token auth for external frontends
|
|
27
|
+
- **Dashboard** — Configurable stat cards, charts, tables, and progress bars
|
|
28
|
+
- **CLI Tools** — `fak-admin` / `fak` for superuser management and project scaffolding
|
|
29
|
+
- **Pagination** — Offset, cursor, or dynamic strategies per model
|
|
30
|
+
- **Filters** — Text, boolean, relation, and enum sidebar filters
|
|
31
|
+
- **File Uploads** — Built-in local storage backend with upload widgets
|
|
32
|
+
- **Async-First** — PostgreSQL, MySQL, and SQLite with auto URL normalization
|
|
33
|
+
- **CSRF & Rate Limiting** — Security built-in out of the box
|
|
22
34
|
|
|
23
35
|
## Installation
|
|
24
36
|
|
|
25
37
|
```bash
|
|
38
|
+
# pip
|
|
26
39
|
pip install fastapi-admin-kit
|
|
40
|
+
|
|
41
|
+
# uv
|
|
42
|
+
uv add fastapi-admin-kit
|
|
27
43
|
```
|
|
28
44
|
|
|
29
45
|
For database-specific async drivers:
|
|
30
46
|
|
|
31
47
|
```bash
|
|
48
|
+
# pip
|
|
32
49
|
pip install fastapi-admin-kit[postgres] # PostgreSQL via asyncpg
|
|
33
50
|
pip install fastapi-admin-kit[mysql] # MySQL via aiomysql
|
|
51
|
+
|
|
52
|
+
# uv
|
|
53
|
+
uv add fastapi-admin-kit[postgres] # PostgreSQL via asyncpg
|
|
54
|
+
uv add fastapi-admin-kit[mysql] # MySQL via aiomysql
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For the full experience with uvicorn and JWT support:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# pip
|
|
61
|
+
pip install fastapi-admin-kit[full]
|
|
62
|
+
|
|
63
|
+
# uv
|
|
64
|
+
uv add fastapi-admin-kit[full]
|
|
34
65
|
```
|
|
35
66
|
|
|
36
67
|
## Quick Start
|
|
37
68
|
|
|
38
69
|
```python
|
|
70
|
+
import os
|
|
71
|
+
import secrets
|
|
39
72
|
from contextlib import asynccontextmanager
|
|
73
|
+
|
|
40
74
|
from fastapi import FastAPI
|
|
41
75
|
from sqlalchemy import Column, Float, Integer, String
|
|
42
76
|
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
|
@@ -70,8 +104,8 @@ class Product(Base):
|
|
|
70
104
|
price = Column(Float, nullable=False)
|
|
71
105
|
|
|
72
106
|
|
|
73
|
-
DATABASE_URL = "sqlite+aiosqlite:///./app.db"
|
|
74
|
-
SECRET_KEY = "
|
|
107
|
+
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite+aiosqlite:///./app.db")
|
|
108
|
+
SECRET_KEY = os.getenv("SECRET_KEY", secrets.token_urlsafe(32))
|
|
75
109
|
|
|
76
110
|
engine = create_async_engine(DATABASE_URL)
|
|
77
111
|
async_session = sessionmaker(engine, class_=AsyncSession)
|
|
@@ -98,6 +132,21 @@ admin = Admin(
|
|
|
98
132
|
admin.register(Product)
|
|
99
133
|
```
|
|
100
134
|
|
|
135
|
+
Run with:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
pip install fastapi-admin-kit[full]
|
|
139
|
+
uvicorn main:app --reload
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Open [http://localhost:8000/admin/](http://localhost:8000/admin/) and log in with:
|
|
143
|
+
|
|
144
|
+
- **Email:** `admin@example.com`
|
|
145
|
+
- **Password:** `admin`
|
|
146
|
+
|
|
147
|
+
!!! warning
|
|
148
|
+
Change the default password immediately in production!
|
|
149
|
+
|
|
101
150
|
## CLI Usage
|
|
102
151
|
|
|
103
152
|
Both the full name and the short alias work interchangeably:
|
|
@@ -114,6 +163,13 @@ fak users
|
|
|
114
163
|
# Change a user's password
|
|
115
164
|
fak-admin changepassword -e admin@example.com -p newpassword
|
|
116
165
|
fak changepassword -e admin@example.com -p newpassword
|
|
166
|
+
|
|
167
|
+
# Scaffold a new fastapi project
|
|
168
|
+
fak init myproject
|
|
169
|
+
|
|
170
|
+
# Permission management
|
|
171
|
+
fak createpermissions --base myapp.models.Base
|
|
172
|
+
fak createpermissions myapp.models.User myapp.models.Product
|
|
117
173
|
```
|
|
118
174
|
|
|
119
175
|
All commands accept `-d DATABASE_URL` or read the `DATABASE_URL` environment variable.
|
|
@@ -125,11 +181,14 @@ All commands accept `-d DATABASE_URL` or read the `DATABASE_URL` environment var
|
|
|
125
181
|
| Variable | Description | Default |
|
|
126
182
|
|---|---|---|
|
|
127
183
|
| `DATABASE_URL` | Async database connection string | `sqlite+aiosqlite:///./app.db` |
|
|
128
|
-
| `SECRET_KEY` | Signing key for sessions/CSRF/JWT (min 32 chars) |
|
|
184
|
+
| `SECRET_KEY` | Signing key for sessions/CSRF/JWT (min 32 chars) | Auto-generated if unset |
|
|
129
185
|
|
|
130
186
|
### Admin Options
|
|
131
187
|
|
|
132
188
|
```python
|
|
189
|
+
from fastapi_admin_kit import Admin
|
|
190
|
+
from fastapi_admin_kit.config import ThemeConfig
|
|
191
|
+
|
|
133
192
|
admin = Admin(
|
|
134
193
|
app=app,
|
|
135
194
|
engine=engine,
|
|
@@ -138,8 +197,6 @@ admin = Admin(
|
|
|
138
197
|
title="My Admin", # Admin panel title
|
|
139
198
|
admin_path="/admin", # URL prefix
|
|
140
199
|
dark_mode_default=False, # Dark mode on by default
|
|
141
|
-
# Theme
|
|
142
|
-
theme=ThemeConfig(preset="modern", primary_color="#6366F1"),
|
|
143
200
|
# Auth
|
|
144
201
|
auth_backend=BuiltinAuthBackend(),
|
|
145
202
|
# Environment badge
|
|
@@ -154,21 +211,42 @@ admin = Admin(
|
|
|
154
211
|
- **PostgreSQL**: `pip install fastapi-admin-kit[postgres]` + set `DATABASE_URL=postgresql+asyncpg://...`
|
|
155
212
|
- **MySQL**: `pip install fastapi-admin-kit[mysql]` + set `DATABASE_URL=mysql+aiomysql://...`
|
|
156
213
|
|
|
214
|
+
### Optional Dependencies
|
|
215
|
+
|
|
216
|
+
| Extra | Packages | When to use |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `full` | `uvicorn`, `pyjwt` | Running the dev server or using JWT API auth |
|
|
219
|
+
| `postgres` | `asyncpg` | PostgreSQL databases |
|
|
220
|
+
| `mysql` | `aiomysql` | MySQL databases |
|
|
221
|
+
| `sqlmodel` | `sqlmodel` | Using SQLModel models |
|
|
222
|
+
| `docs` | `mkdocs`, `mkdocs-material` | Building documentation |
|
|
223
|
+
|
|
224
|
+
## Security
|
|
225
|
+
|
|
226
|
+
- Session cookies use `SameSite=Strict` and `Secure` by default
|
|
227
|
+
- CSRF protection on all state-changing requests
|
|
228
|
+
- Rate limiting on authentication endpoints
|
|
229
|
+
- Passwords hashed with bcrypt
|
|
230
|
+
- SQL injection prevention via identifier validation
|
|
231
|
+
- Secret key validated to be >= 32 characters at startup
|
|
232
|
+
|
|
157
233
|
## Development
|
|
158
234
|
|
|
159
235
|
```bash
|
|
160
236
|
# Install with dev dependencies
|
|
161
|
-
|
|
237
|
+
uv sync
|
|
162
238
|
|
|
163
|
-
# Run tests
|
|
164
|
-
pytest
|
|
239
|
+
# Run tests with coverage
|
|
240
|
+
uv run pytest --cov=fastapi_admin_kit
|
|
165
241
|
|
|
166
242
|
# Lint
|
|
167
|
-
ruff check fastapi_admin_kit/
|
|
243
|
+
uv run ruff check fastapi_admin_kit/
|
|
244
|
+
|
|
245
|
+
# Format
|
|
246
|
+
uv run ruff format fastapi_admin_kit/
|
|
168
247
|
|
|
169
248
|
# Build distribution
|
|
170
|
-
|
|
171
|
-
hatch build
|
|
249
|
+
uv build
|
|
172
250
|
```
|
|
173
251
|
|
|
174
252
|
## License
|
{fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/admin_database.py
RENAMED
|
@@ -2,10 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import logging
|
|
6
|
+
import re
|
|
5
7
|
from typing import Any
|
|
6
8
|
|
|
7
9
|
from fastapi_admin_kit.config.database import DatabaseConfig
|
|
8
10
|
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
_TABLE_NAME_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _validate_identifier(name: str, kind: str = "table") -> str:
|
|
17
|
+
"""Validate a SQL identifier to prevent injection."""
|
|
18
|
+
if not _TABLE_NAME_RE.match(name):
|
|
19
|
+
raise ValueError(f"Invalid {kind} name: {name!r}")
|
|
20
|
+
return name
|
|
21
|
+
|
|
9
22
|
|
|
10
23
|
class AdminDatabase:
|
|
11
24
|
"""Handles database setup, table creation, and role seeding."""
|
|
@@ -71,9 +84,11 @@ class AdminDatabase:
|
|
|
71
84
|
for table_name, table in metadata.tables.items():
|
|
72
85
|
if not inspector.has_table(table_name):
|
|
73
86
|
continue
|
|
87
|
+
safe_table = _validate_identifier(table_name)
|
|
74
88
|
existing_cols = {c["name"] for c in inspector.get_columns(table_name)}
|
|
75
89
|
for col in table.columns:
|
|
76
90
|
if col.name not in existing_cols:
|
|
91
|
+
safe_col = _validate_identifier(col.name, "column")
|
|
77
92
|
col_type = col.type.compile(self.engine.dialect)
|
|
78
93
|
nullable = "NULL" if col.nullable else "NOT NULL"
|
|
79
94
|
default = ""
|
|
@@ -85,8 +100,8 @@ class AdminDatabase:
|
|
|
85
100
|
elif col.default is not None and col.default.is_seq:
|
|
86
101
|
pass
|
|
87
102
|
sql = text(
|
|
88
|
-
f"""ALTER TABLE {
|
|
89
|
-
ADD COLUMN {
|
|
103
|
+
f"""ALTER TABLE {safe_table}
|
|
104
|
+
ADD COLUMN {safe_col} {col_type}
|
|
90
105
|
{nullable}{default}"""
|
|
91
106
|
)
|
|
92
107
|
with self.engine.begin() as conn:
|
|
@@ -107,9 +122,11 @@ class AdminDatabase:
|
|
|
107
122
|
for table_name, table in metadata.tables.items():
|
|
108
123
|
if not inspector.has_table(table_name):
|
|
109
124
|
continue
|
|
125
|
+
safe_table = _validate_identifier(table_name)
|
|
110
126
|
existing_cols = {c["name"] for c in inspector.get_columns(table_name)}
|
|
111
127
|
for col in table.columns:
|
|
112
128
|
if col.name not in existing_cols:
|
|
129
|
+
safe_col = _validate_identifier(col.name, "column")
|
|
113
130
|
col_type = col.type.compile(dialect)
|
|
114
131
|
nullable = "NULL" if col.nullable else "NOT NULL"
|
|
115
132
|
default = ""
|
|
@@ -121,16 +138,20 @@ class AdminDatabase:
|
|
|
121
138
|
elif not col.nullable:
|
|
122
139
|
# SQLite requires a default for NOT NULL columns being added
|
|
123
140
|
type_defaults = {
|
|
124
|
-
"VARCHAR": "''",
|
|
125
|
-
"
|
|
141
|
+
"VARCHAR": "''",
|
|
142
|
+
"TEXT": "''",
|
|
143
|
+
"INTEGER": "0",
|
|
144
|
+
"FLOAT": "0.0",
|
|
145
|
+
"BOOLEAN": "0",
|
|
146
|
+
"DATETIME": "''",
|
|
126
147
|
}
|
|
127
148
|
sql_type = col_type.upper().split("(")[0]
|
|
128
149
|
temp_val = type_defaults.get(sql_type, "''")
|
|
129
150
|
default = f" DEFAULT {temp_val}"
|
|
130
151
|
sql = text(
|
|
131
|
-
f"""ALTER TABLE {
|
|
152
|
+
f"""ALTER TABLE {safe_table}
|
|
132
153
|
ADD COLUMN
|
|
133
|
-
{
|
|
154
|
+
{safe_col} {col_type} {nullable}{default}
|
|
134
155
|
"""
|
|
135
156
|
)
|
|
136
157
|
sync_conn.execute(sql)
|
{fastapi_admin_kit-0.2.0 → fastapi_admin_kit-0.2.1}/fastapi_admin_kit/admin/admin_template.py
RENAMED
|
@@ -65,6 +65,7 @@ class AdminTemplate:
|
|
|
65
65
|
user = getattr(request.state, "admin_user", None)
|
|
66
66
|
|
|
67
67
|
snapshot = getattr(request.state, "admin_user_snapshot", None)
|
|
68
|
+
user_for_template = snapshot if snapshot else user
|
|
68
69
|
is_superuser = (
|
|
69
70
|
(
|
|
70
71
|
bool(snapshot.get("is_superuser", False))
|
|
@@ -120,8 +121,10 @@ class AdminTemplate:
|
|
|
120
121
|
can_edit=perm.can_edit,
|
|
121
122
|
can_delete=perm.can_delete,
|
|
122
123
|
)
|
|
123
|
-
except Exception:
|
|
124
|
-
|
|
124
|
+
except Exception as exc:
|
|
125
|
+
import logging
|
|
126
|
+
|
|
127
|
+
logging.getLogger(__name__).debug("Permission query failed: %s", exc)
|
|
125
128
|
|
|
126
129
|
def _item_visible(item: Any) -> bool:
|
|
127
130
|
return (
|
|
@@ -181,7 +184,7 @@ class AdminTemplate:
|
|
|
181
184
|
return {
|
|
182
185
|
"nav_groups": filtered_groups,
|
|
183
186
|
"permissions_map": permissions_map,
|
|
184
|
-
"current_user":
|
|
187
|
+
"current_user": user_for_template,
|
|
185
188
|
"dashboard_visible": dashboard_visible,
|
|
186
189
|
"settings_visible": settings_visible,
|
|
187
190
|
}
|