Flask-Exts 0.2.8__tar.gz → 0.3.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.
- flask_exts-0.3.1/.editorconfig +69 -0
- flask_exts-0.3.1/.github/workflows/docs.yml +49 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/.gitignore +4 -4
- flask_exts-0.3.1/.vscode/settings.json +16 -0
- flask_exts-0.3.1/CHANGES.rst +39 -0
- flask_exts-0.3.1/Makefile +31 -0
- flask_exts-0.3.1/PKG-INFO +111 -0
- flask_exts-0.3.1/README.rst +69 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/babel/messages.pot +79 -83
- flask_exts-0.3.1/docs/advanced/database.rst +123 -0
- flask_exts-0.3.1/docs/advanced/index.rst +13 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/api.rst +2 -2
- {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/conf.py +10 -9
- flask_exts-0.3.1/docs/configure.rst +53 -0
- flask_exts-0.3.1/docs/develop.rst +81 -0
- flask_exts-0.3.1/docs/examples.rst +11 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/index.rst +14 -5
- flask_exts-0.3.1/docs/quickstart.rst +52 -0
- flask_exts-0.3.1/examples/README.rst +51 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/admin_views.py +3 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/build_sample.py +42 -38
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/make_app.py +3 -14
- flask_exts-0.3.1/examples/demo/models/__init__.py +9 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/author.py +14 -17
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/post.py +7 -8
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/post_tag.py +2 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/tag.py +4 -4
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/models/tree.py +6 -8
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/views/author_view.py +8 -7
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/views/post_view.py +10 -10
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/views/tag_view.py +3 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/views/tree_view.py +3 -6
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/simple/__init__.py +4 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/package.json +5 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/pyproject.toml +42 -16
- flask_exts-0.3.1/requirements/develop.in +1 -0
- flask_exts-0.3.1/scripts/copy-vendor.js +195 -0
- flask_exts-0.3.1/src/flask_exts/__about__.py +1 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/__init__.py +0 -1
- flask_exts-0.3.1/src/flask_exts/admin/__init__.py +10 -0
- flask_exts-0.2.8/src/flask_exts/web/admin.py → flask_exts-0.3.1/src/flask_exts/admin/base.py +40 -37
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/exposer.py +12 -10
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/menu.py +31 -32
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/__init__.py +23 -26
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/actions_mixin.py +3 -2
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/ajax.py +13 -10
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/base.py +22 -57
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/__init__.py +7 -7
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/columns.py +26 -25
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/forms.py +26 -23
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/pagination.py +45 -39
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/sorting.py +13 -24
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/core/values.py +25 -19
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/filter.py +24 -18
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/filter_mixin.py +17 -13
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/__init__.py +7 -7
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/create.py +3 -3
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/export.py +14 -17
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/read.py +9 -9
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/update.py +5 -4
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/row_actions.py +2 -8
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/type_formatters.py +22 -15
- flask_exts-0.3.1/src/flask_exts/admin/model/types.py +5 -0
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/view.py +34 -40
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/ajax.py +22 -19
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/filter/filter_converter.py +43 -55
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/filter/filters.py +14 -14
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/field_converters.py +8 -6
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/inline_form.py +6 -4
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/inline_model_convert.py +57 -98
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/model_field_convert.py +9 -8
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/utils.py +22 -14
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/__init__.py +6 -6
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/type_formatters.py +1 -2
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/view.py +270 -59
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/view.py +51 -47
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/__init__.py +8 -9
- flask_exts-0.2.8/src/flask_exts/builtin_extensions/web_ext.py → flask_exts-0.3.1/src/flask_exts/builtin_extensions/admin_ext.py +2 -6
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/babel_ext.py +34 -37
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/database_ext.py +4 -5
- flask_exts-0.3.1/src/flask_exts/builtin_extensions/emailer_ext.py +15 -0
- flask_exts-0.2.8/src/flask_exts/builtin_extensions/html_ext.py → flask_exts-0.3.1/src/flask_exts/builtin_extensions/frontend_ext.py +7 -7
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/login_ext.py +55 -28
- flask_exts-0.3.1/src/flask_exts/builtin_extensions/portal_ext.py +14 -0
- flask_exts-0.3.1/src/flask_exts/builtin_extensions/security_ext.py +24 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/usercenter_ext.py +4 -8
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/builtin_extensions/userstore_ext.py +1 -5
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/commands.py +17 -5
- flask_exts-0.3.1/src/flask_exts/datastore/sqla/__init__.py +4 -0
- flask_exts-0.3.1/src/flask_exts/datastore/sqla/_db.py +45 -0
- flask_exts-0.3.1/src/flask_exts/datastore/sqla/database.py +154 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query.py +20 -13
- flask_exts-0.3.1/src/flask_exts/datastore/sqla/utils/__init__.py +8 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/utils/model_mapper.py +4 -4
- flask_exts-0.3.1/src/flask_exts/datastore/sqla/utils/orm.py +32 -0
- {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/base.py +9 -3
- {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/smtp.py +15 -5
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/extension_core/base.py +11 -53
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/extension_core/manager.py +43 -26
- flask_exts-0.3.1/src/flask_exts/extension_core/registry.py +219 -0
- flask_exts-0.3.1/src/flask_exts/forms/fields/__init__.py +5 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/ajax_select.py +6 -7
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/datetime.py +24 -21
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/file.py +38 -28
- flask_exts-0.3.1/src/flask_exts/forms/fields/inline.py +51 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/json.py +1 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/select.py +14 -32
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/sqla.py +3 -146
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/__init__.py +2 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/base_form.py +2 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/csrf.py +7 -10
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/meta.py +8 -12
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/session_csrf.py +7 -10
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/validators/field_list.py +4 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/validators/file.py +20 -21
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/validators/recaptcha.py +5 -5
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/validators/sqla.py +7 -6
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/__init__.py +1 -1
- flask_exts-0.3.1/src/flask_exts/forms/widgets/checkbox.py +30 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/editable.py +21 -17
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/file.py +1 -0
- flask_exts-0.3.1/src/flask_exts/forms/widgets/inline.py +8 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/recaptcha.py +4 -3
- flask_exts-0.3.1/src/flask_exts/forms/widgets/select.py +75 -0
- flask_exts-0.3.1/src/flask_exts/frontend/plugin_base.py +24 -0
- flask_exts-0.3.1/src/flask_exts/frontend/plugin_manager.py +117 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_detail_filter_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_filters_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_form_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_list_action_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/admin_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/bootstrap5_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/clipboard_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/copybutton_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/dayjs_plugin.py +8 -8
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/editable_plugin.py +3 -3
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/flatpickr_plugin.py +10 -7
- flask_exts-0.3.1/src/flask_exts/frontend/plugins/modal_plugin.py +41 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/qrcode_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/rediscli_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/sphinx_copybutton_plugin.py +1 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/plugins/tom_select_plugin.py +4 -3
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/template.py +0 -5
- {flask_exts-0.2.8/src/flask_exts/web/default_views → flask_exts-0.3.1/src/flask_exts/portal}/index_view.py +1 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/proxies.py +3 -2
- flask_exts-0.3.1/src/flask_exts/security/__init__.py +3 -0
- flask_exts-0.3.1/src/flask_exts/security/authorizer/base.py +8 -0
- flask_exts-0.3.1/src/flask_exts/security/authorizer/simple_authorizer.py +56 -0
- flask_exts-0.3.1/src/flask_exts/security/core.py +39 -0
- flask_exts-0.3.1/src/flask_exts/security/exceptions.py +24 -0
- flask_exts-0.3.1/src/flask_exts/security/keys.py +23 -0
- flask_exts-0.3.1/src/flask_exts/security/plugins/email_change.py +92 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/plugins/email_verification.py +8 -4
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/plugins/reset_password.py +13 -7
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/plugins/two_factor_authentication.py +1 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/registry.py +7 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/serializer.py +19 -13
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/token_action.py +60 -33
- flask_exts-0.3.1/src/flask_exts/security/urls.py +28 -0
- flask_exts-0.3.1/src/flask_exts/security/user_mixin.py +10 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/css/admin.css +2 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/copybutton.js +4 -4
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/detail_filter.js +13 -9
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/editable.js +2 -2
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/field-registry.js +0 -2
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/filters.js +5 -23
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/form.js +167 -121
- flask_exts-0.3.1/src/flask_exts/static/js/modal.js +621 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/rediscli.js +2 -6
- flask_exts-0.3.1/src/flask_exts/static/vendor/bootstrap5/bootstrap.bundle.min.js +7 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/bootstrap5/bootstrap.min.css +6 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/clipboard/clipboard.min.js +7 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/dayjs/dayjs.min.js +1 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/dayjs/timezone.js +1 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/dayjs/utc.js +1 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/flatpickr/flatpickr.min.css +13 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/flatpickr/flatpickr.min.js +2 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/tom-select/tom-select.bootstrap5.min.css +2 -0
- flask_exts-0.3.1/src/flask_exts/static/vendor/tom-select/tom-select.complete.min.js +454 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/master.html +7 -7
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/model/create.html +3 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/model/details.html +1 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/model/edit.html +1 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/model/list.html +34 -45
- flask_exts-0.3.1/src/flask_exts/templates/base.html +19 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/index.html +0 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/layout.html +2 -2
- flask_exts-0.3.1/src/flask_exts/templates/macro/form.html +137 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/layout.html +10 -7
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/menu.html +7 -7
- flask_exts-0.3.1/src/flask_exts/templates/macro/message.html +22 -0
- flask_exts-0.3.1/src/flask_exts/templates/macro/modal.html +15 -0
- flask_exts-0.3.1/src/flask_exts/templates/user/email_change.html +22 -0
- flask_exts-0.3.1/src/flask_exts/templates/user/index.html +42 -0
- flask_exts-0.3.1/src/flask_exts/templates/user/list.html +5 -0
- flask_exts-0.3.1/src/flask_exts/templates/user/profile.html +96 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/recovery_codes.html +4 -6
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/setup_tfa.html +18 -7
- flask_exts-0.3.1/src/flask_exts/templates/user/show_tfa.html +26 -0
- flask_exts-0.3.1/src/flask_exts/templates/user/verify_email.html +26 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/verify_tfa.html +1 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/translations/en/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/translations/en/LC_MESSAGES/messages.po +139 -83
- flask_exts-0.3.1/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.po +159 -102
- flask_exts-0.3.1/src/flask_exts/usercenter/auth_requires.py +34 -0
- flask_exts-0.3.1/src/flask_exts/usercenter/forms/email_change.py +29 -0
- flask_exts-0.3.1/src/flask_exts/usercenter/forms/forgot_password.py +12 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/register.py +8 -6
- flask_exts-0.3.1/src/flask_exts/usercenter/forms/resend_verification.py +7 -0
- flask_exts-0.3.1/src/flask_exts/usercenter/user_view.py +410 -0
- flask_exts-0.2.8/src/flask_exts/userstore/store.py → flask_exts-0.3.1/src/flask_exts/userstore/base.py +1 -3
- flask_exts-0.3.1/src/flask_exts/userstore/exceptions.py +15 -0
- flask_exts-0.3.1/src/flask_exts/userstore/sqla/__init__.py +4 -0
- flask_exts-0.3.1/src/flask_exts/userstore/sqla/models/__init__.py +6 -0
- {flask_exts-0.2.8/src/flask_exts/userstore → flask_exts-0.3.1/src/flask_exts/userstore/sqla}/models/role.py +5 -5
- {flask_exts-0.2.8/src/flask_exts/userstore → flask_exts-0.3.1/src/flask_exts/userstore/sqla}/models/user.py +25 -21
- {flask_exts-0.2.8/src/flask_exts/userstore → flask_exts-0.3.1/src/flask_exts/userstore/sqla}/models/user_profile.py +13 -12
- {flask_exts-0.2.8/src/flask_exts/userstore → flask_exts-0.3.1/src/flask_exts/userstore/sqla}/models/user_role.py +3 -4
- flask_exts-0.2.8/src/flask_exts/userstore/sqla_user_store.py → flask_exts-0.3.1/src/flask_exts/userstore/sqla/userstore.py +18 -14
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/model/core/test_columns.py +1 -1
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/model/test_action_mixin.py +2 -4
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/model/test_model_view.py +25 -91
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/model/test_model_view_csrf.py +17 -14
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/custom_sqla_model_view.py +1 -1
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_basic.py +41 -49
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_filter.py +2 -3
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_form.py +11 -5
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_inline_model.py +219 -48
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_multi_pk.py +30 -3
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_primary_string.py +3 -3
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/test_translation.py +5 -5
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/test_admin.py +3 -25
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/test_view.py +1 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/conftest.py +7 -4
- flask_exts-0.3.1/tests/datastore/sqla/test_db.py +171 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/datastore/sqla/test_query.py +5 -3
- {flask_exts-0.2.8/tests/email → flask_exts-0.3.1/tests/emailer}/test_base.py +1 -0
- {flask_exts-0.2.8/tests/email → flask_exts-0.3.1/tests/emailer}/test_smtp.py +2 -1
- flask_exts-0.3.1/tests/extension_core/test_manager.py +89 -0
- flask_exts-0.3.1/tests/extension_core/test_registry.py +199 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_datetime.py +2 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_filefield.py +4 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_json.py +4 -4
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_uploadfile.py +5 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_wtforms.py +3 -2
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/form/test_form.py +19 -1
- flask_exts-0.3.1/tests/frontend/__init__.py +0 -0
- {flask_exts-0.2.8/tests/html → flask_exts-0.3.1/tests/frontend}/conftest.py +2 -1
- flask_exts-0.3.1/tests/frontend/test_base.py +23 -0
- flask_exts-0.3.1/tests/frontend/test_plugin_manager.py +95 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/demo.py +37 -32
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/multpk.py +1 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/primary_string_model.py +2 -4
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/relations.py +5 -7
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/simple.py +1 -3
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/tree.py +4 -9
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/unique.py +2 -3
- flask_exts-0.3.1/tests/security/test_authorizer.py +94 -0
- flask_exts-0.3.1/tests/security/test_core.py +118 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/security/test_tfa.py +3 -1
- flask_exts-0.3.1/tests/security/test_urls.py +23 -0
- flask_exts-0.3.1/tests/test_builtin_exts.py +55 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/test_login.py +23 -14
- {flask_exts-0.2.8/tests/views → flask_exts-0.3.1/tests/usercenter}/test_user_view.py +309 -59
- flask_exts-0.3.1/tests/userstore/test_sqla_userstore.py +72 -0
- flask_exts-0.2.8/.djlintrc +0 -8
- flask_exts-0.2.8/CHANGES.rst +0 -147
- flask_exts-0.2.8/PKG-INFO +0 -95
- flask_exts-0.2.8/README.rst +0 -40
- flask_exts-0.2.8/docs/advanced/bootstrap5.rst +0 -429
- flask_exts-0.2.8/docs/advanced/custom_fields.rst +0 -384
- flask_exts-0.2.8/docs/advanced/custom_plugins.rst +0 -247
- flask_exts-0.2.8/docs/advanced/custom_validators.rst +0 -4
- flask_exts-0.2.8/docs/advanced/index.rst +0 -16
- flask_exts-0.2.8/docs/advanced/modelview.rst +0 -337
- flask_exts-0.2.8/docs/advanced/performance.rst +0 -493
- flask_exts-0.2.8/docs/advanced/security.rst +0 -498
- flask_exts-0.2.8/docs/advanced/theming.rst +0 -401
- flask_exts-0.2.8/docs/configure.rst +0 -25
- flask_exts-0.2.8/docs/develop.rst +0 -65
- flask_exts-0.2.8/docs/examples.rst +0 -6
- flask_exts-0.2.8/docs/quickstart.rst +0 -264
- flask_exts-0.2.8/examples/README.rst +0 -38
- flask_exts-0.2.8/examples/demo/models/__init__.py +0 -9
- flask_exts-0.2.8/src/flask_exts/__about__.py +0 -1
- flask_exts-0.2.8/src/flask_exts/builtin_extensions/email_ext.py +0 -16
- flask_exts-0.2.8/src/flask_exts/builtin_extensions/security_ext.py +0 -23
- flask_exts-0.2.8/src/flask_exts/builtin_extensions/startup_ext.py +0 -41
- flask_exts-0.2.8/src/flask_exts/datastore/sqla/__init__.py +0 -3
- flask_exts-0.2.8/src/flask_exts/datastore/sqla/sqla_db.py +0 -82
- flask_exts-0.2.8/src/flask_exts/datastore/sqla/utils/__init__.py +0 -6
- flask_exts-0.2.8/src/flask_exts/datastore/sqla/utils/orm.py +0 -40
- flask_exts-0.2.8/src/flask_exts/datastore/sqla/utils/paginate.py +0 -74
- flask_exts-0.2.8/src/flask_exts/extension_core/registry.py +0 -263
- flask_exts-0.2.8/src/flask_exts/forms/fields/__init__.py +0 -6
- flask_exts-0.2.8/src/flask_exts/forms/fields/inline.py +0 -90
- flask_exts-0.2.8/src/flask_exts/forms/fields/sqla_fields/__init__.py +0 -39
- flask_exts-0.2.8/src/flask_exts/forms/fields/sqla_fields/checkbox_fields.py +0 -9
- flask_exts-0.2.8/src/flask_exts/forms/fields/sqla_fields/inline_fields.py +0 -10
- flask_exts-0.2.8/src/flask_exts/forms/fields/sqla_fields/query_fields.py +0 -11
- flask_exts-0.2.8/src/flask_exts/forms/validators/__init__.py +0 -1
- flask_exts-0.2.8/src/flask_exts/forms/widgets/checkbox.py +0 -32
- flask_exts-0.2.8/src/flask_exts/forms/widgets/inline.py +0 -14
- flask_exts-0.2.8/src/flask_exts/forms/widgets/select.py +0 -81
- flask_exts-0.2.8/src/flask_exts/html/plugin_base.py +0 -32
- flask_exts-0.2.8/src/flask_exts/html/plugin_manager.py +0 -85
- flask_exts-0.2.8/src/flask_exts/html/plugins/admin_modal_plugin.py +0 -11
- flask_exts-0.2.8/src/flask_exts/html/plugins/bootstrap4_plugin.py +0 -19
- flask_exts-0.2.8/src/flask_exts/security/authorizer/base.py +0 -17
- flask_exts-0.2.8/src/flask_exts/security/authorizer/simple_authorizer.py +0 -21
- flask_exts-0.2.8/src/flask_exts/security/core.py +0 -54
- flask_exts-0.2.8/src/flask_exts/static/js/modal.js +0 -49
- flask_exts-0.2.8/src/flask_exts/templates/admin/model/modals/create.html +0 -5
- flask_exts-0.2.8/src/flask_exts/templates/admin/model/modals/details.html +0 -37
- flask_exts-0.2.8/src/flask_exts/templates/admin/model/modals/edit.html +0 -5
- flask_exts-0.2.8/src/flask_exts/templates/base.html +0 -19
- flask_exts-0.2.8/src/flask_exts/templates/macro/form.html +0 -83
- flask_exts-0.2.8/src/flask_exts/templates/macro/inline.html +0 -44
- flask_exts-0.2.8/src/flask_exts/templates/macro/message.html +0 -22
- flask_exts-0.2.8/src/flask_exts/templates/macro/modal.html +0 -13
- flask_exts-0.2.8/src/flask_exts/templates/user/index.html +0 -53
- flask_exts-0.2.8/src/flask_exts/templates/user/list.html +0 -5
- flask_exts-0.2.8/src/flask_exts/templates/user/show_tfa.html +0 -23
- flask_exts-0.2.8/src/flask_exts/templates/user/verify_email.html +0 -5
- flask_exts-0.2.8/src/flask_exts/templates/user/verify_tfa_modal.html +0 -13
- flask_exts-0.2.8/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
- flask_exts-0.2.8/src/flask_exts/usercenter/auth_requires.py +0 -39
- flask_exts-0.2.8/src/flask_exts/usercenter/forms/forgot_password.py +0 -19
- flask_exts-0.2.8/src/flask_exts/usercenter/forms/profile.py +0 -11
- flask_exts-0.2.8/src/flask_exts/usercenter/user.py +0 -14
- flask_exts-0.2.8/src/flask_exts/usercenter/user_view.py +0 -291
- flask_exts-0.2.8/src/flask_exts/userstore/models/__init__.py +0 -1
- flask_exts-0.2.8/src/flask_exts/web/__init__.py +0 -3
- flask_exts-0.2.8/src/flask_exts/web/model/types.py +0 -4
- flask_exts-0.2.8/tests/datastore/sqla/test_db.py +0 -82
- flask_exts-0.2.8/tests/html/test_base.py +0 -28
- flask_exts-0.2.8/tests/security/test_authorizer.py +0 -116
- flask_exts-0.2.8/tests/security/test_core.py +0 -51
- flask_exts-0.2.8/tests/test_base.py +0 -9
- flask_exts-0.2.8/tests/test_db.py +0 -19
- flask_exts-0.2.8/tests/test_exts_base.py +0 -38
- flask_exts-0.2.8/tests/usercenter/test_sqla_usercenter.py +0 -50
- {flask_exts-0.2.8 → flask_exts-0.3.1}/.github/workflows/release.yml +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/.readthedocs.yaml +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/LICENSE.rst +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/babel/babel.cfg +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/babel/babel.sh +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/Makefile +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/_static/logo.png +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/changes.rst +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/make.bat +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/docs/requirements.txt +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/file_op.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/static/favicon.ico +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/templates/field_list.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/templates/locations.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/examples/demo/templates/tree_list.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/requirements/build.in +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/requirements/test.in +0 -0
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/model/operations/delete.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/datastore → flask_exts-0.3.1/src/flask_exts/admin/sqla}/__init__.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/filter/__init__.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/form/__init__.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/pagination_handler.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/query_handler.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/relationships_handler.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/web → flask_exts-0.3.1/src/flask_exts/admin}/sqla/sqla_view/sorting_handler.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/constants.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/datastore}/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/filter_builder.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/join_builder.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/pagination_builder.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/datastore/sqla/query_builders/sort_builder.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/extension_core → flask_exts-0.3.1/src/flask_exts/emailer}/__init__.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/reset_password_sender.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/sender.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/email → flask_exts-0.3.1/src/flask_exts/emailer}/verify_email_sender.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/extension_core}/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/recaptcha.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/switch.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/fields/taglist.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/flask_form.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/form/utils.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/html/plugins → flask_exts-0.3.1/src/flask_exts/forms/validators}/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/forms/widgets/datetime.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/security → flask_exts-0.3.1/src/flask_exts/frontend}/__init__.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/security/authorizer → flask_exts-0.3.1/src/flask_exts/frontend/plugins}/__init__.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/html → flask_exts-0.3.1/src/flask_exts/frontend}/theme.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/translations → flask_exts-0.3.1/src/flask_exts/portal}/__init__.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/usercenter → flask_exts-0.3.1/src/flask_exts/security/authorizer}/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/security/hasher.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/signals.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/css/editable.css +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/css/rediscli.css +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/list_action.js +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/qrcode.js +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/security/base64.js +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/security/webauthn.js +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/js/ui-factory.js +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/logo.png +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/vendor/sphinx-copybutton/sphinx-copybutton.css +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/static/vendor/sphinx-copybutton/sphinx-copybutton.js +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/admin/index.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/icon.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/nav.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/macro/pagination.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/change_password.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/forgot_password.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/login.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/recovery.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/register.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/templates/user/reset_password.html +0 -0
- {flask_exts-0.2.8/src/flask_exts/web/default_views → flask_exts-0.3.1/src/flask_exts/translations}/__init__.py +0 -0
- {flask_exts-0.2.8/src/flask_exts/web/sqla → flask_exts-0.3.1/src/flask_exts/usercenter}/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/core.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/change_password.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/login.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/recovery.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/reset_password.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/src/flask_exts/usercenter/forms/two_factor.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/__init__.py +0 -0
- {flask_exts-0.2.8/tests/html → flask_exts-0.3.1/tests/admin}/__init__.py +0 -0
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/__init__.py +0 -0
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/templates/another_macro.html +0 -0
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/admin}/sqla/templates/macro.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.gif +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.jpeg +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.jpg +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.png +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/data/copyleft.tiff +0 -0
- {flask_exts-0.2.8/tests/web → flask_exts-0.3.1/tests/extension_core}/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/common.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/forms/fields/test_inline.py +0 -0
- {flask_exts-0.2.8/tests/html → flask_exts-0.3.1/tests/frontend}/macros/test_render_breadcrumb_item.py +0 -0
- {flask_exts-0.2.8/tests/html → flask_exts-0.3.1/tests/frontend}/macros/test_render_nav_item.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/helper.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/models/__init__.py +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/templates/method.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/templates/mock.html +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/test_babel.py +1 -1
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/en/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/en/LC_MESSAGES/messages.po +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/messages.pot +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.2.8 → flask_exts-0.3.1}/tests/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# EditorConfig is awesome: https://EditorConfig.org
|
|
2
|
+
# Team style guide blending Google and Microsoft conventions
|
|
3
|
+
|
|
4
|
+
# Mark as root so EditorConfig stops searching parent directories
|
|
5
|
+
root = true
|
|
6
|
+
|
|
7
|
+
# ============================================================
|
|
8
|
+
# General defaults (common to Google and Microsoft)
|
|
9
|
+
# ============================================================
|
|
10
|
+
[*]
|
|
11
|
+
charset = utf-8
|
|
12
|
+
end_of_line = lf
|
|
13
|
+
insert_final_newline = true
|
|
14
|
+
trim_trailing_whitespace = true
|
|
15
|
+
indent_style = space
|
|
16
|
+
indent_size = 4
|
|
17
|
+
|
|
18
|
+
# ============================================================
|
|
19
|
+
# JavaScript / TypeScript (Google style: 2 spaces)
|
|
20
|
+
# Ref: Google JavaScript Style Guide - Block indentation
|
|
21
|
+
# ============================================================
|
|
22
|
+
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}]
|
|
23
|
+
indent_size = 2
|
|
24
|
+
|
|
25
|
+
# ============================================================
|
|
26
|
+
# JSON / YAML / HTML / CSS (industry common: 2 spaces)
|
|
27
|
+
# ============================================================
|
|
28
|
+
[*.{json,jsonc,yml,yaml,html,css,scss,less,vue,svelte}]
|
|
29
|
+
indent_size = 2
|
|
30
|
+
|
|
31
|
+
# ============================================================
|
|
32
|
+
# Python (Google style: 4 spaces, never tabs)
|
|
33
|
+
# Ref: Google Python Style Guide - Indentation
|
|
34
|
+
# ============================================================
|
|
35
|
+
[*.py]
|
|
36
|
+
indent_size = 4
|
|
37
|
+
|
|
38
|
+
# ============================================================
|
|
39
|
+
# Go (gofmt enforces tabs)
|
|
40
|
+
# Ref: gofmt specification
|
|
41
|
+
# ============================================================
|
|
42
|
+
[*.go]
|
|
43
|
+
indent_style = tab
|
|
44
|
+
|
|
45
|
+
# ============================================================
|
|
46
|
+
# C# / .NET (Microsoft style: 4 spaces, UTF-8 BOM)
|
|
47
|
+
# Ref: dotnet/roslyn .editorconfig
|
|
48
|
+
# ============================================================
|
|
49
|
+
[*.{cs,csx,vb,vbx}]
|
|
50
|
+
indent_size = 4
|
|
51
|
+
charset = utf-8-bom
|
|
52
|
+
|
|
53
|
+
# ============================================================
|
|
54
|
+
# Shell scripts
|
|
55
|
+
# ============================================================
|
|
56
|
+
[*.sh]
|
|
57
|
+
indent_size = 2
|
|
58
|
+
|
|
59
|
+
# ============================================================
|
|
60
|
+
# Markdown (do not trim trailing whitespace; preserves line breaks)
|
|
61
|
+
# ============================================================
|
|
62
|
+
[*.md]
|
|
63
|
+
trim_trailing_whitespace = false
|
|
64
|
+
|
|
65
|
+
# ============================================================
|
|
66
|
+
# Makefile (must use tabs)
|
|
67
|
+
# ============================================================
|
|
68
|
+
[Makefile]
|
|
69
|
+
indent_style = tab
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
paths:
|
|
6
|
+
- "docs/**"
|
|
7
|
+
- "src/**"
|
|
8
|
+
- "examples/**"
|
|
9
|
+
- "CHANGES.rst"
|
|
10
|
+
- "pyproject.toml"
|
|
11
|
+
- ".github/workflows/docs.yml"
|
|
12
|
+
pull_request:
|
|
13
|
+
paths:
|
|
14
|
+
- "docs/**"
|
|
15
|
+
- "src/**"
|
|
16
|
+
- "examples/**"
|
|
17
|
+
- "CHANGES.rst"
|
|
18
|
+
- "pyproject.toml"
|
|
19
|
+
- ".github/workflows/docs.yml"
|
|
20
|
+
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
build-docs:
|
|
26
|
+
name: Build Sphinx documentation
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
|
|
29
|
+
steps:
|
|
30
|
+
- name: Check out repository
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
|
|
33
|
+
- name: Set up Python
|
|
34
|
+
uses: actions/setup-python@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: "3.13"
|
|
37
|
+
cache: pip
|
|
38
|
+
cache-dependency-path: |
|
|
39
|
+
pyproject.toml
|
|
40
|
+
docs/requirements.txt
|
|
41
|
+
|
|
42
|
+
- name: Install project and documentation dependencies
|
|
43
|
+
run: |
|
|
44
|
+
python -m pip install --upgrade pip
|
|
45
|
+
python -m pip install -e .
|
|
46
|
+
python -m pip install -r docs/requirements.txt
|
|
47
|
+
|
|
48
|
+
- name: Build documentation
|
|
49
|
+
run: python -m sphinx -b html docs docs/_build/html -W -n --keep-going
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
### vscode
|
|
2
|
-
.vscode
|
|
3
|
-
|
|
4
1
|
### JupyterNotebooks ###
|
|
5
2
|
.ipynb_checkpoints
|
|
6
3
|
*/.ipynb_checkpoints/*
|
|
@@ -24,6 +21,9 @@ build/
|
|
|
24
21
|
.coverage
|
|
25
22
|
htmlcov/
|
|
26
23
|
|
|
24
|
+
# djlint
|
|
25
|
+
.djlint_cache/
|
|
26
|
+
|
|
27
27
|
# Translations
|
|
28
28
|
# *.mo
|
|
29
29
|
|
|
@@ -33,7 +33,7 @@ docs/_build/
|
|
|
33
33
|
# sqlite db
|
|
34
34
|
*.sqlite
|
|
35
35
|
|
|
36
|
-
# npm front-end deps
|
|
36
|
+
# npm front-end deps
|
|
37
37
|
node_modules/
|
|
38
38
|
package-lock.json
|
|
39
39
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files.eol": "\n",
|
|
3
|
+
"files.associations": {
|
|
4
|
+
"**/templates/**/*.html": "jinja-html"
|
|
5
|
+
},
|
|
6
|
+
"[jinja-html]": {
|
|
7
|
+
"editor.defaultFormatter": "monosans.djlint",
|
|
8
|
+
"editor.formatOnSave": true
|
|
9
|
+
},
|
|
10
|
+
"djlint.useEditorIndentation": false,
|
|
11
|
+
"python.testing.unittestEnabled": false,
|
|
12
|
+
"python.testing.pytestEnabled": true,
|
|
13
|
+
"python.testing.pytestArgs": [
|
|
14
|
+
"tests"
|
|
15
|
+
],
|
|
16
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
v0.3.1
|
|
2
|
+
------
|
|
3
|
+
|
|
4
|
+
Released 2026-10-11
|
|
5
|
+
|
|
6
|
+
- Improve SQLAlchemy lifecycle management, session configuration, and in-memory SQLite support.
|
|
7
|
+
- Add reusable modal form flows and improve two-factor authentication setup.
|
|
8
|
+
- Allow extensions to provide admin views for automatic registration, and clarify duplicate extension-name errors.
|
|
9
|
+
|
|
10
|
+
v0.3.0
|
|
11
|
+
------
|
|
12
|
+
|
|
13
|
+
Released 2026-10-07
|
|
14
|
+
|
|
15
|
+
- Add user registration, login, logout, profile management, and user-center views.
|
|
16
|
+
- Add email verification, email change, password reset, and recovery workflows.
|
|
17
|
+
- Add a SQLAlchemy-backed user store with user profiles and role management.
|
|
18
|
+
- Add authentication and role-based authorization.
|
|
19
|
+
- Add TOTP-based two-factor authentication and recovery codes.
|
|
20
|
+
|
|
21
|
+
v0.2.0
|
|
22
|
+
------
|
|
23
|
+
|
|
24
|
+
Released 2026-01-07
|
|
25
|
+
|
|
26
|
+
- Add an extension system with registration, dependency management, and lifecycle hooks.
|
|
27
|
+
- Add an admin interface with model views, CRUD operations, filtering, sorting, pagination, and data export.
|
|
28
|
+
- Add SQLAlchemy integration for database access, model forms, relationships, and queries.
|
|
29
|
+
- Add form fields, widgets, validators, and CSRF protection.
|
|
30
|
+
- Add email delivery and notification support.
|
|
31
|
+
- Add frontend plugin management and Bootstrap-based components.
|
|
32
|
+
- Add Babel integration for localization.
|
|
33
|
+
|
|
34
|
+
v0.1.0
|
|
35
|
+
------
|
|
36
|
+
|
|
37
|
+
Released 2024-03-20
|
|
38
|
+
|
|
39
|
+
- Initial release of the Flask-Exts package and documentation.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
.PHONY: docs-build docs-serve docs-clean
|
|
2
|
+
|
|
3
|
+
docs-build:
|
|
4
|
+
python -m sphinx -b html docs docs/_build/html -W -n --keep-going
|
|
5
|
+
|
|
6
|
+
docs-serve:
|
|
7
|
+
python -m http.server -d docs/_build/html 8000
|
|
8
|
+
|
|
9
|
+
docs-clean:
|
|
10
|
+
rm -rf docs/_build
|
|
11
|
+
|
|
12
|
+
test:
|
|
13
|
+
pytest
|
|
14
|
+
|
|
15
|
+
pytest-last:
|
|
16
|
+
pytest --lf --last-failed-no-failures=none
|
|
17
|
+
|
|
18
|
+
pytest-clean:
|
|
19
|
+
rm -rf .pytest_cache
|
|
20
|
+
|
|
21
|
+
pytest-warn:
|
|
22
|
+
pytest -W error
|
|
23
|
+
|
|
24
|
+
pytest-print:
|
|
25
|
+
pytest -s
|
|
26
|
+
|
|
27
|
+
coverage:
|
|
28
|
+
coverage run -m pytest
|
|
29
|
+
|
|
30
|
+
coverage-report:
|
|
31
|
+
coverage report -m
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: Flask-Exts
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Flask extensions with admin, SQLAlchemy, Babel, forms, fields, widgets, and more.
|
|
5
|
+
Project-URL: Documentation, https://flask-exts.readthedocs.io
|
|
6
|
+
Project-URL: Source, https://github.com/ojso/flask-exts
|
|
7
|
+
Project-URL: Homepage, https://github.com/ojso/flask-exts
|
|
8
|
+
Project-URL: Issues, https://github.com/ojso/flask-exts/issues
|
|
9
|
+
Project-URL: Changelog, https://flask-exts.readthedocs.io/en/latest/changes.html
|
|
10
|
+
Author-email: David Hua <david.dong.hua@gmail.com>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE.rst
|
|
13
|
+
Keywords: admin,babel,flask,form,sqlalchemy,widget
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Environment :: Web Environment
|
|
16
|
+
Classifier: Framework :: Flask
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
|
26
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Requires-Dist: email-validator>=2.0
|
|
29
|
+
Requires-Dist: flask-babel>=4.0
|
|
30
|
+
Requires-Dist: flask-login>=0.6
|
|
31
|
+
Requires-Dist: flask>=3.0
|
|
32
|
+
Requires-Dist: pyjwt>=2.0
|
|
33
|
+
Requires-Dist: pyotp>=2.0
|
|
34
|
+
Requires-Dist: sqlalchemy>=2.0
|
|
35
|
+
Requires-Dist: tablib>=3.0
|
|
36
|
+
Requires-Dist: wtforms>=3.0
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: djlint; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
40
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
41
|
+
Description-Content-Type: text/x-rst
|
|
42
|
+
|
|
43
|
+
Flask-Exts
|
|
44
|
+
==========
|
|
45
|
+
|
|
46
|
+
Flask-Exts is a toolkit for building Flask applications with an integrated
|
|
47
|
+
admin interface, SQLAlchemy support, forms, localization, and user-account
|
|
48
|
+
features. It brings common application components together behind a
|
|
49
|
+
dependency-aware extension system. The project is inspired by
|
|
50
|
+
`Flask-Admin <https://github.com/pallets-eco/flask-admin/>`_ and
|
|
51
|
+
`Bootstrap <https://getbootstrap.com/>`_.
|
|
52
|
+
|
|
53
|
+
Highlights
|
|
54
|
+
----------
|
|
55
|
+
|
|
56
|
+
- **Modern frontend:** Uses Bootstrap 5 and native browser APIs, with no
|
|
57
|
+
jQuery dependency or Bootstrap 4 frontend.
|
|
58
|
+
- **Composable extensions:** Initializes extensions in dependency order and
|
|
59
|
+
lets extensions contribute views to the admin interface.
|
|
60
|
+
- **Built-in account features:** Provides authentication, email verification
|
|
61
|
+
and recovery flows, TOTP-based two-factor authentication, and recovery
|
|
62
|
+
codes.
|
|
63
|
+
- **Integrated admin and data tools:** Includes SQLAlchemy integration,
|
|
64
|
+
model management, forms, filtering, and data export.
|
|
65
|
+
- **Localization support:** Integrates Babel for translating application
|
|
66
|
+
interfaces.
|
|
67
|
+
|
|
68
|
+
Installation
|
|
69
|
+
------------
|
|
70
|
+
|
|
71
|
+
Flask-Exts requires Python 3.10 or later. Install it with pip:
|
|
72
|
+
|
|
73
|
+
.. code-block:: console
|
|
74
|
+
|
|
75
|
+
pip install flask-exts
|
|
76
|
+
|
|
77
|
+
Quick start
|
|
78
|
+
-----------
|
|
79
|
+
|
|
80
|
+
Create a Flask application and initialize the extension manager:
|
|
81
|
+
|
|
82
|
+
.. code-block:: python
|
|
83
|
+
|
|
84
|
+
from flask import Flask
|
|
85
|
+
from flask_exts import ExtensionManager
|
|
86
|
+
|
|
87
|
+
app = Flask(__name__)
|
|
88
|
+
app.config["SECRET_KEY"] = "change-this-for-local-development"
|
|
89
|
+
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.sqlite"
|
|
90
|
+
|
|
91
|
+
extensions = ExtensionManager()
|
|
92
|
+
extensions.init_app(app)
|
|
93
|
+
|
|
94
|
+
if __name__ == "__main__":
|
|
95
|
+
app.run(debug=True)
|
|
96
|
+
|
|
97
|
+
For a complete example with a custom admin view and database setup, see
|
|
98
|
+
``examples/simple``.
|
|
99
|
+
|
|
100
|
+
Documentation
|
|
101
|
+
-------------
|
|
102
|
+
|
|
103
|
+
- `Documentation <https://flask-exts.readthedocs.io/>`_
|
|
104
|
+
- `Runnable examples <https://github.com/ojso/flask-exts/tree/main/examples>`_
|
|
105
|
+
- `Changelog <https://flask-exts.readthedocs.io/en/latest/changes.html>`_
|
|
106
|
+
|
|
107
|
+
License
|
|
108
|
+
-------
|
|
109
|
+
|
|
110
|
+
Flask-Exts is distributed under the terms of the
|
|
111
|
+
`MIT License <https://opensource.org/licenses/MIT>`_.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Flask-Exts
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
Flask-Exts is a toolkit for building Flask applications with an integrated
|
|
5
|
+
admin interface, SQLAlchemy support, forms, localization, and user-account
|
|
6
|
+
features. It brings common application components together behind a
|
|
7
|
+
dependency-aware extension system. The project is inspired by
|
|
8
|
+
`Flask-Admin <https://github.com/pallets-eco/flask-admin/>`_ and
|
|
9
|
+
`Bootstrap <https://getbootstrap.com/>`_.
|
|
10
|
+
|
|
11
|
+
Highlights
|
|
12
|
+
----------
|
|
13
|
+
|
|
14
|
+
- **Modern frontend:** Uses Bootstrap 5 and native browser APIs, with no
|
|
15
|
+
jQuery dependency or Bootstrap 4 frontend.
|
|
16
|
+
- **Composable extensions:** Initializes extensions in dependency order and
|
|
17
|
+
lets extensions contribute views to the admin interface.
|
|
18
|
+
- **Built-in account features:** Provides authentication, email verification
|
|
19
|
+
and recovery flows, TOTP-based two-factor authentication, and recovery
|
|
20
|
+
codes.
|
|
21
|
+
- **Integrated admin and data tools:** Includes SQLAlchemy integration,
|
|
22
|
+
model management, forms, filtering, and data export.
|
|
23
|
+
- **Localization support:** Integrates Babel for translating application
|
|
24
|
+
interfaces.
|
|
25
|
+
|
|
26
|
+
Installation
|
|
27
|
+
------------
|
|
28
|
+
|
|
29
|
+
Flask-Exts requires Python 3.10 or later. Install it with pip:
|
|
30
|
+
|
|
31
|
+
.. code-block:: console
|
|
32
|
+
|
|
33
|
+
pip install flask-exts
|
|
34
|
+
|
|
35
|
+
Quick start
|
|
36
|
+
-----------
|
|
37
|
+
|
|
38
|
+
Create a Flask application and initialize the extension manager:
|
|
39
|
+
|
|
40
|
+
.. code-block:: python
|
|
41
|
+
|
|
42
|
+
from flask import Flask
|
|
43
|
+
from flask_exts import ExtensionManager
|
|
44
|
+
|
|
45
|
+
app = Flask(__name__)
|
|
46
|
+
app.config["SECRET_KEY"] = "change-this-for-local-development"
|
|
47
|
+
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.sqlite"
|
|
48
|
+
|
|
49
|
+
extensions = ExtensionManager()
|
|
50
|
+
extensions.init_app(app)
|
|
51
|
+
|
|
52
|
+
if __name__ == "__main__":
|
|
53
|
+
app.run(debug=True)
|
|
54
|
+
|
|
55
|
+
For a complete example with a custom admin view and database setup, see
|
|
56
|
+
``examples/simple``.
|
|
57
|
+
|
|
58
|
+
Documentation
|
|
59
|
+
-------------
|
|
60
|
+
|
|
61
|
+
- `Documentation <https://flask-exts.readthedocs.io/>`_
|
|
62
|
+
- `Runnable examples <https://github.com/ojso/flask-exts/tree/main/examples>`_
|
|
63
|
+
- `Changelog <https://flask-exts.readthedocs.io/en/latest/changes.html>`_
|
|
64
|
+
|
|
65
|
+
License
|
|
66
|
+
-------
|
|
67
|
+
|
|
68
|
+
Flask-Exts is distributed under the terms of the
|
|
69
|
+
`MIT License <https://opensource.org/licenses/MIT>`_.
|