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.register
to 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_ENDPOINT
andADMIN_LOGOUT_ENDPOINT
defer initialization of the Admin extension to fix template overriding
do not register duplicate templates folder for single-module app bundle
Breaking Changes¶
rename
User.active
toUser.is_active
for compatibility with Flask-Login v0.5
v0.8.0 (2020/12/20)¶
Features¶
major improvements to
AppFactory
andAppFactoryHook
support single-file app bundles (just export the app bundle as
UNCHAINED
)support using a custom subclass of
FlaskUnchained
usingAppFactory.APP_CLASS
support using a custom subclass of
AppFactory
support passing all kwargs to
Flask
by setting the same names upper-cased inunchained_config
support automatic defaults for the Flask app kwargs
root_path
,template_folder
,static_folder
, andstatic_url_path
support extending and overriding hooks with the same consistent object-oriented patterns
support using a custom module name for
unchained_config
by setting theUNCHAINED
environment 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_name
to 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, click
and define command groups for your commands using@cli.group()
)add
flask unchained config
command for listing the current config (optionally filtered by bundle)add
flask unchained extensions
command for listing extensions discovered by the appadd
flask unchaiend services
command for listing services discovered by the appalias
flask.abort
(werkzeug.exceptions.abort
) asflask_unchained.abort
alias
flask_wtf.csrf.generate_csrf
asflask_unchained.generate_csrf
alias
flask.Request
andflask.Response
intoflask_unchained
support
Accept
headers 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
services
andmanagers
modules 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
ConfigureAppHook
to 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.resource
fix 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
func
fix
flask urls
command when no URLs foundmake sure hooks don’t resolve local proxies
fix
ModelResource.Meta.url_prefix
to useMeta.model.__name__
instead of the resource’s class nameallow using
AnonymousUser
as if it were a SQLAlchemy model in queries
Breaking Changes¶
rename
flask_unchained.BaseService
toflask_unchained.Service
rename
PROJECT_ROOT
toROOT_PATH
for consistency with upstreamFlask
rename
Bundle.folder
toBundle.root_path
for consistency withFlask
rename
Controller.Meta.template_folder_name
toController.Meta.template_folder
for consistency withFlask
AppFactory
is now aSingleton
that 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_PATH
andAppBundleConfig.APP_ROOT
as they didn’t always work correctly (useBundleConfig.current_app.root_path
instead)moved
flask_unchained.commands.utils.print_table
toflask_unchained.cli.print_table
if using the API bundle, require
marshmallow>=3.0
,marshmallow-sqlalchemy>=0.23
, andflask-marshmallow>=0.12
if using the SQLAlchemy bundle, require
sqlalchemy-unchained>=0.10
CSRF 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
Bundle
andAppBundle
into theflask_unchained.bundles
modulemove
BundleBlueprint
into theflask_unchained.bundles.controller.bundle_blueprint
modulemove
_DeferredBundleFunctions
intoflask_unchained.unchained
, rename it toDeferredBundleFunctions
make a bunch more protected internal classes public
make
_has_views
,_blueprint_names
,_static_folders
,is_top_bundle
and_has_hierarchy_name_conflicts
methods onBundle
propertiesrename double-negative
reverse_mro
parameter forBundle._iter_class_hierarchy
tomro
warn when identical routes are registered
make
AppFactory
methodsload_bundles
,load_bundle
andis_bundle
classmethodsadd a noop
ViewsHook
to consolidate logic for defining and loadingviews_module_names
move
param_converter
into the controller bundle
v0.7.9 (2019/05/19)¶
compatibility with
sqlalchemy-unchained >= 0.7.6
v0.7.8 (2019/04/21)¶
bump required
alembic
version to 1.0.9, fixesimmutabledict is not defined
error
v0.7.7 (2019/04/11)¶
bump requirements
change behavior of
flask new project
command to use defaults unless--prompt
is 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
string
url parameter converter to supportupper=True/False
add
ModelForm.make_instance
convenience methodfix
ModelForm.name
to returnbytes
add
.gitignore
toflask new project
commandimprove error message when no
config
module found in the app bundle
v0.7.3 (2019/02/26)¶
do not generate
celery_app.py
for 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
include
function used inroutes.py
now 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.config
accessible as attributes, egapp.config.SECRET_KEY
is now the same asapp.config['SECRET_KEY']
apply any settings from the app bundle config not already present in
app.config
as 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_fixtures
package (which is now a bundle as of v0.4.0)consolidate
unchained.get_extension_local_proxy
andunchained.get_service_local_proxy
into a single function,unchained.get_local_proxy
rename
AppConfig
toBundleConfig
rename the
SQLAlchemy
extension class toSQLAlchemyUnchained
rename
flask_unchained.bundles.sqlalchemy.model_form
toflask_unchained.bundles.sqlalchemy.forms
rename the Graphene Bundle’s
QueryObjectType
toQueriesObjectType
andMutationObjectType
toMutationsObjectType
rename the Security Bundle’s
SecurityUtilsService.verify_and_update_password
method toverify_password
(internal) descriptors, metaclasses, meta options, and meta option factories are now protected
(internal) rename the
flask_unchained.app_config
module toflask_unchained.config
(internal) remove the
Bundle.root_folder
descriptor as it made no sense (Bundle.folder
is the bundle package’s root folder)(internal) rename
ConfigPropertyMeta
toConfigPropertyMetaclass
Bug fixes¶
fix the
Api
extension so it only generates docs for model resources that are registered with the appfix setting of
Route._controller_cls
when controllers extend another concrete controller with routesfix
Bundle.static_url_path
descriptorspecify required minimum package versions in
setup.py
, and pin versions inrequirements.txt
fix the
UnchainedModelRegistry.reset
method so it allows using factory_boy fromconftest.py
fix the
flask celery
commands so that they gracefully terminate instead of leaving zombie processes runningfix
param_converter
to allowing converting models from optional query parametersadd support to graphene for working with SQLAlchemy BigInteger columns
v0.6.6 (2018/10/09)¶
ship
_templates
folder 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_env
from coreflask_unchained
packageexport
param_converter
from coreflask_unchained
packagefix discovery of user-app
tests._unchained_config
improve 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 urls
commandimprove the
--order-by
option of theflask urls
commandrename command
flask db import_fixtures
toflask db import-fixtures
add a
FlaskForm
base class extendingFlaskForm
that adds support for specifying the rendered field orderautomatically set the
csrf_token
cookie on responsesoverride the
click
module to also support documenting arguments withhelp
also make the default help options
-h
and--help
instead of just--help
refactor the hook store to be a class attribute of the bundle the hook(s) belong to
add an
env
attribute on theFlaskUnchained
app instancemake the
bundles
attribute on theUnchained
extension anAttrDict
bundles are now instantiated instead of passing the classes around directly
add default config options, making
DEBUG
andTESTING
unnecessary to set manuallyadd a
_name
attribute toFlaskForm
to automatically name forms when rendering them programmaticallyadd
get_extension_local_proxy
andget_service_local_proxy
methods to theUnchained
extensionadd support for overriding static files from bundles
minor refactor of the declarative routing for
Controller
andResource
classesconsolidate default route rule generation into the
Route
classmake it possible to override the
member_param
of aResource
with theresource
routes function
add a
TEMPLATE_FILE_EXTENSION
option toAppConfig
that controllers will respect by default. Controllers can still set theirtemplate_file_extension
attribute to override the application-wide default.implement missing
delete
routing functionpreliminary support for customizing the generated unique member param
fix setting of
Route._controller_cls
to 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_folder
toController.template_folder_name
add
Controller.make_response
as an alias forflask.make_response
convert attributes on
Controller
,Resource
, andModelResource
to beclass Meta
optionsrename
_meta
toMeta
per py-meta-utils v0.3rename
ModelManager.find_all
toModelManager.all
andModelManager.find_by
toModelManager.filter_by
for consistency with theQuery
apimove instantiation of the
CSRFProtect
extension 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
BaseService
to use a MetaOptionsFactorymake the
ModelManager.model
class attribute a meta optionrename the
flask db drop --drop
option toflask db drop --force
to skip promptingrename the
flask db reset --reset
option toflask db reset --force
to skip promptingadd
no_autoflush
toSessionManager
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
FlaskUnchained
from the root packageexport Flask’s
current_app
from the root packagenever register static assets routes with babel bundle
integrate the admin bundle into the
flask_unchained
packageintegrate the api bundle into the
flask_unchained
packageintegrate the celery bundle into the
flask_unchained
packageintegrate the mail bundle into the
flask_unchained
packageintegrate the sqlalchemy bundle into the
flask_unchained
packageintegrate the webpack bundle into the
flask_unchained
package
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_config
optional ifunchained_config
existsfix 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.BUNDLES
tounchained.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 qtconsole
commandrename Bundle.iter_bundles to Bundle.iter_class_hierarchy
add
cli_runner
pytest 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
FunctionType
inset_up_class_dependency_injection
v0.2.0 (2018/04/06)¶
rename
BaseConfig
toConfig
add 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