CHANGELOG¶
v0.9.0 (2021/06/07)¶
fix security bundle salt configuration for itsdangerous 2.0+
fix security bundle redirect vulnerability
add shell readline completion (from Flask PR 3960)
fix
BundleBlueprint.registerto work with Flask 2.0+fix compatibility with click 8.0+
bump required flask-sqlalchemy-unchained version
API bundle fixes and improvements
v0.8.1 (2021/01/17)¶
Features¶
upgrade Flask-Admin templates to bootstrap4
add Admin-specific post login/logout redirect endpoints
add default Model Admins for the User and Role models
Bug Fixes¶
fix default config settings for
ADMIN_LOGIN_ENDPOINTandADMIN_LOGOUT_ENDPOINTdefer initialization of the Admin extension to fix template overriding
do not register duplicate templates folder for single-module app bundle
Breaking Changes¶
rename
User.activetoUser.is_activefor compatibility with Flask-Login v0.5
v0.8.0 (2020/12/20)¶
Features¶
major improvements to
AppFactoryandAppFactoryHooksupport single-file app bundles (just export the app bundle as
UNCHAINED)support using a custom subclass of
FlaskUnchainedusingAppFactory.APP_CLASSsupport using a custom subclass of
AppFactorysupport passing all kwargs to
Flaskby setting the same names upper-cased inunchained_configsupport automatic defaults for the Flask app kwargs
root_path,template_folder,static_folder, andstatic_url_pathsupport extending and overriding hooks with the same consistent object-oriented patterns
support using a custom module name for
unchained_configby setting theUNCHAINEDenvironment variablemake it possible to define multiple modules hooks should load from (excluding config and routes, as those only make sense to live inside a single module within bundles)
very experimental: add
Bundle.default_load_from_module_nameto ease migration from single-file app bundles to individual modules for different types (ie grouped by base class)
set up automatic dependency injection on commands (use
from flask_unchained.cli import cli, clickand define command groups for your commands using@cli.group())add
flask unchained configcommand for listing the current config (optionally filtered by bundle)add
flask unchained extensionscommand for listing extensions discovered by the appadd
flask unchaiend servicescommand for listing services discovered by the appalias
flask.abort(werkzeug.exceptions.abort) asflask_unchained.abortalias
flask_wtf.csrf.generate_csrfasflask_unchained.generate_csrfalias
flask.Requestandflask.Responseintoflask_unchainedsupport
Acceptheaders for handling responses in the API bundleallow customizing the endpoint prefix for controllers using
Controller.Meta.endpoint_prefix
General Improvements¶
document the rest of SQLAlchemy’s config options
automatically discover services in the
servicesandmanagersmodules of bundlesbump sqlalchemy-unchained to v0.11.0
add compatibility with pytest 5
Bug Fixes¶
fix grouping routes by which bundle they’re from
fix registration of resource method routes so the order is deterministic
fix
ConfigureAppHookto load configs from every bundle in the hierarchy, not just the top-most onefix resolving extension initiation order to only happen once instead of twice
fix passing explicit rule overrides to
routes.resourcefix automatic endpoint names for resource routes using the default implementations for create/list/get/delete/patch/put
fix using default url rule from view function when no explicit rule passed to
funcfix
flask urlscommand when no URLs foundmake sure hooks don’t resolve local proxies
fix
ModelResource.Meta.url_prefixto useMeta.model.__name__instead of the resource’s class nameallow using
AnonymousUseras if it were a SQLAlchemy model in queries
Breaking Changes¶
rename
flask_unchained.BaseServicetoflask_unchained.Servicerename
PROJECT_ROOTtoROOT_PATHfor consistency with upstreamFlaskrename
Bundle.foldertoBundle.root_pathfor consistency withFlaskrename
Controller.Meta.template_folder_nametoController.Meta.template_folderfor consistency withFlaskAppFactoryis now aSingletonthat must be instantiated (ie changeAppFactory.create_app(env)toAppFactory().create_app(env)inwsgi.py)no longer automatically set up dependency injection on all the methods from classes (you can still decorate them manually with
unchained.inject(), but the preferred approach is to use class attributes to define what to inject into classes)default endpoint name for simple view functions is now just the function name
rename Resource method name constants to reduce confusion with HTTP method names
remove
AppBundleConfig.ROOT_PATHandAppBundleConfig.APP_ROOTas they didn’t always work correctly (useBundleConfig.current_app.root_pathinstead)moved
flask_unchained.commands.utils.print_tabletoflask_unchained.cli.print_tableif using the API bundle, require
marshmallow>=3.0,marshmallow-sqlalchemy>=0.23, andflask-marshmallow>=0.12if using the SQLAlchemy bundle, require
sqlalchemy-unchained>=0.10CSRF protection is no longer enabled by default. To re-enable it:
from flask_unchained import BundleConfig, unchained, generate_csrf
class Config(BundleConfig):
SECRET_KEY = 'some-secret-key'
WTF_CSRF_ENABLED = True
class TestConfig(Config):
WTF_CSRF_ENABLED = False
@unchained.after_request
def set_csrf_token_cookie(response):
if response:
response.set_cookie('csrf_token', generate_csrf())
return response
customizing bundle module locations changed:
class YourBundle(Bundle):
extensions_module_name = 'custom' # before
extensions_module_names = ['custom'] # after
services_module_name = 'custom' # before
services_module_names = ['custom'] # after
commands_module_name = 'custom' # before
commands_module_names = ['custom'] # after
blueprints_module_name = 'custom' # before
blueprints_module_names = ['custom'] # after
models_module_name = 'custom' # before
models_module_names = ['custom'] # after
admins_module_name = 'custom' # before
admins_module_names = ['custom'] # after
resources_module_name = 'custom' # before
model_resources_module_names = ['custom'] # after
serializers_module_name = 'custom' # before
model_serializers_module_names = ['custom'] # after
celery_tasks_module_name = 'custom' # before
celery_tasks_module_names = ['custom'] # after
graphene_queries_module_name = 'custom' # before
graphene_queries_module_names = ['custom'] # after
graphene_mutations_module_name = 'custom' # before
graphene_mutations_module_names = ['custom'] # after
graphene_types_module_name = 'custom' # before
graphene_types_module_names = ['custom'] # after
Internals¶
move
BundleandAppBundleinto theflask_unchained.bundlesmodulemove
BundleBlueprintinto theflask_unchained.bundles.controller.bundle_blueprintmodulemove
_DeferredBundleFunctionsintoflask_unchained.unchained, rename it toDeferredBundleFunctionsmake a bunch more protected internal classes public
make
_has_views,_blueprint_names,_static_folders,is_top_bundleand_has_hierarchy_name_conflictsmethods onBundlepropertiesrename double-negative
reverse_mroparameter forBundle._iter_class_hierarchytomrowarn when identical routes are registered
make
AppFactorymethodsload_bundles,load_bundleandis_bundleclassmethodsadd a noop
ViewsHookto consolidate logic for defining and loadingviews_module_namesmove
param_converterinto the controller bundle
v0.7.9 (2019/05/19)¶
compatibility with
sqlalchemy-unchained >= 0.7.6
v0.7.8 (2019/04/21)¶
bump required
alembicversion to 1.0.9, fixesimmutabledict is not definederror
v0.7.7 (2019/04/11)¶
bump requirements
change behavior of
flask new projectcommand to use defaults unless--promptis givenNOTE: broken with sqlalchemy bundle, must install alembic using:
pip install git+https://github.com/sqlalchemy/alembic.git@d46de05b8b3281a85e6b107ef3f3407e232eb9e9#egg=alembic
v0.7.6 (2019/03/24)¶
NOTE: broken with sqlalchemy bundle, must install alembic using:
pip install git+https://github.com/sqlalchemy/alembic.git@d46de05b8b3281a85e6b107ef3f3407e232eb9e9#egg=alembic
v0.7.5 (2019/03/24)¶
NOTE: broken with sqlalchemy bundle, must install alembic using:
pip install git+https://github.com/sqlalchemy/alembic.git@d46de05b8b3281a85e6b107ef3f3407e232eb9e9#egg=alembic
v0.7.4 (2019/03/17)¶
support injecting current app config into services
extend the
stringurl parameter converter to supportupper=True/Falseadd
ModelForm.make_instanceconvenience methodfix
ModelForm.nameto returnbytesadd
.gitignoretoflask new projectcommandimprove error message when no
configmodule found in the app bundle
v0.7.3 (2019/02/26)¶
do not generate
celery_app.pyfor new projects without the celery bundle enabledimprove user warnings when mail bundle is enabled but lxml or beautifulsoup isn’t installed
bump required versions of py-meta-utils and sqlalchemy-unchained
v0.7.2 (2019/02/25)¶
fix the project’s registered name on PyPI so it doesn’t contain spaces
v0.7.1 (2019/02/04)¶
Bug fixes¶
support multiple routing rules with the same endpoint per view function
fix type error in dependency injection when comparing parameter values with string
v0.7.0 (2019/01/30)¶
Features¶
- fire:OAuth:fire
support with the new OAuth Bundle (many thanks to @chriamue!)
- fire:GraphQL:fire
support with the new Graphene Bundle
add support for specifying parameters to inject into classes as class attributes
when using
unchained.inject()on a class, or subclassing a class that supports automatic dependency injection, all non-dunderscore methods now support having dependencies injectedthe
includefunction used inroutes.pynow supports specifying the url prefix as the first argumentsupport distributing and loading database fixture files with/from bundles
implement proper support for
ModelForm(it now adds fields for columns by default)
Configuration Improvements¶
add a way for bundle configs to get access to the current app-under-construction
make options in
app.configaccessible as attributes, egapp.config.SECRET_KEYis now the same asapp.config['SECRET_KEY']apply any settings from the app bundle config not already present in
app.configas defaults before loading bundles
General¶
improve documentation of how Flask Unchained works
update to py-meta-utils 0.7.4 and sqlalchemy-unchained 0.7.0
update to marshmallow 2.16
update to marshmallow-sqlalchemy 0.15
Breaking Changes¶
move database fixture loading code into the
py_yaml_fixturespackage (which is now a bundle as of v0.4.0)consolidate
unchained.get_extension_local_proxyandunchained.get_service_local_proxyinto a single function,unchained.get_local_proxyrename
AppConfigtoBundleConfigrename the
SQLAlchemyextension class toSQLAlchemyUnchainedrename
flask_unchained.bundles.sqlalchemy.model_formtoflask_unchained.bundles.sqlalchemy.formsrename the Graphene Bundle’s
QueryObjectTypetoQueriesObjectTypeandMutationObjectTypetoMutationsObjectTyperename the Security Bundle’s
SecurityUtilsService.verify_and_update_passwordmethod toverify_password(internal) descriptors, metaclasses, meta options, and meta option factories are now protected
(internal) rename the
flask_unchained.app_configmodule toflask_unchained.config(internal) remove the
Bundle.root_folderdescriptor as it made no sense (Bundle.folderis the bundle package’s root folder)(internal) rename
ConfigPropertyMetatoConfigPropertyMetaclass
Bug fixes¶
fix the
Apiextension so it only generates docs for model resources that are registered with the appfix setting of
Route._controller_clswhen controllers extend another concrete controller with routesfix
Bundle.static_url_pathdescriptorspecify required minimum package versions in
setup.py, and pin versions inrequirements.txtfix the
UnchainedModelRegistry.resetmethod so it allows using factory_boy fromconftest.pyfix the
flask celerycommands so that they gracefully terminate instead of leaving zombie processes runningfix
param_converterto allowing converting models from optional query parametersadd support to graphene for working with SQLAlchemy BigInteger columns
v0.6.6 (2018/10/09)¶
ship
_templatesfolder with the distribution so that theflask new <tempate>command works when Flask Unchained gets installed viapip
v0.6.0 - v0.6.5 (2018/10/09)¶
IMPORTANT: these releases are broken, use v0.6.6
export
get_boolean_envfrom coreflask_unchainedpackageexport
param_converterfrom coreflask_unchainedpackagefix discovery of user-app
tests._unchained_configimprove the output of commands that display their information in a table
improve the output of custom sqlalchemy types in generated migrations files
improve the output of the Views column from the
flask urlscommandimprove the
--order-byoption of theflask urlscommandrename command
flask db import_fixturestoflask db import-fixturesadd a
FlaskFormbase class extendingFlaskFormthat adds support for specifying the rendered field orderautomatically set the
csrf_tokencookie on responsesoverride the
clickmodule to also support documenting arguments withhelpalso make the default help options
-hand--helpinstead of just--help
refactor the hook store to be a class attribute of the bundle the hook(s) belong to
add an
envattribute on theFlaskUnchainedapp instancemake the
bundlesattribute on theUnchainedextension anAttrDictbundles are now instantiated instead of passing the classes around directly
add default config options, making
DEBUGandTESTINGunnecessary to set manuallyadd a
_nameattribute toFlaskFormto automatically name forms when rendering them programmaticallyadd
get_extension_local_proxyandget_service_local_proxymethods to theUnchainedextensionadd support for overriding static files from bundles
minor refactor of the declarative routing for
ControllerandResourceclassesconsolidate default route rule generation into the
Routeclassmake it possible to override the
member_paramof aResourcewith theresourceroutes function
add a
TEMPLATE_FILE_EXTENSIONoption toAppConfigthat controllers will respect by default. Controllers can still set theirtemplate_file_extensionattribute to override the application-wide default.implement missing
deleterouting functionpreliminary support for customizing the generated unique member param
fix setting of
Route._controller_clsto automatically always happenrefactor the SQLAlchemy Bundle to split most of it out into its own package, so that it can be used on its own (without Flask).
fix the resource url prefix descriptor to convert to kebab-case instead of snake-case
rename
Controller.template_foldertoController.template_folder_nameadd
Controller.make_responseas an alias forflask.make_responseconvert attributes on
Controller,Resource, andModelResourceto beclass Metaoptionsrename
_metatoMetaper py-meta-utils v0.3rename
ModelManager.find_alltoModelManager.allandModelManager.find_bytoModelManager.filter_byfor consistency with theQueryapimove instantiation of the
CSRFProtectextension from the security bundle into the controller bundle, where it belongs, so that it always gets usedimprove registration of request cycle functions meant to run only for a specific bundle blueprint
update
BaseServiceto use a MetaOptionsFactorymake the
ModelManager.modelclass attribute a meta optionrename the
flask db drop --dropoption toflask db drop --forceto skip promptingrename the
flask db reset --resetoption toflask db reset --forceto skip promptingadd
no_autoflushtoSessionManager
v0.5.1 (2018/07/25)¶
include html templates in the distribution
add bundles to the shell context
v0.5.0 (2018/07/25)¶
export
FlaskUnchainedfrom the root packageexport Flask’s
current_appfrom the root packagenever register static assets routes with babel bundle
integrate the admin bundle into the
flask_unchainedpackageintegrate the api bundle into the
flask_unchainedpackageintegrate the celery bundle into the
flask_unchainedpackageintegrate the mail bundle into the
flask_unchainedpackageintegrate the sqlalchemy bundle into the
flask_unchainedpackageintegrate the webpack bundle into the
flask_unchainedpackage
v0.4.2 (2018/07/21)¶
fix tests when babel_bundle isn’t loaded
v0.4.1 (2018/07/20)¶
fix infinite recursion error when registering urls and blueprints with babel
v0.4.0 (2018/07/20)¶
make
tests._unchained_configoptional ifunchained_configexistsfix discovery of bundle views to include any bundle in the hierarchy with views
subclass Flask to improve handling of adding blueprints and url rules in conjunction with the babel bundle
rename
unchained.BUNDLEStounchained.bundles
v0.3.2 (2018/07/16)¶
fix naming of bundle static endpoints
v0.3.1 (2018/07/16)¶
support loading bundles as the app bundle for development
refactor the babel commands to work with both app and regular bundles
fix discovery of tests._unchained_config module
v0.3.0 (2018/07/14)¶
add
flask qtconsolecommandrename Bundle.iter_bundles to Bundle.iter_class_hierarchy
add
cli_runnerpytest fixture for testing click commandsfix register commands hook to support overriding groups and commands
support registering request hooks, template tags/filters/tests, and context processors via deferred decorators on the Unchained and Bundle classes
ship the controller bundle, session bundle, and babel bundles as part of core
the babel and controller bundles are now mandatory, and will be included automatically
v0.2.2 (2018/04/08)¶
bugfix: Bundle.static_url_prefix renamed to Bundle.static_url_path
v0.2.1 (2018/04/08)¶
bugfix: check for
FunctionTypeinset_up_class_dependency_injection
v0.2.0 (2018/04/06)¶
rename
BaseConfigtoConfigadd utilities for dealing with optional dependencies:
OptionalClass: generic base class that can also be used as a substitute for extensions that have base classes defined as attributes on themoptional_pytest_fixture: allows to conditionally register test fixtures
hooks now declare their dependencies by hook name, as opposed to using an integer priority
v0.1.x¶
early releases