Controller Bundle

class flask_unchained.bundles.controller.ControllerBundle[source]

The Bundle subclass for the controller bundle.

endpoints = None

Lookup of routes by endpoint name.

controller_endpoints = None

Lookup of routes by keys: f’{ControllerClassName}.{view_method_name}’

bundle_routes = None

Lookup of routes belonging to each bundle by bundle name.

other_routes = None

List of routes not associated with any bundles.

before_init_app(app: flask_unchained.flask_unchained.FlaskUnchained)[source]

Configure the Jinja environment and template loader.

Config

class flask_unchained.bundles.controller.config.Config[source]

Default configuration options for the controller bundle.

FLASH_MESSAGES = True

Whether or not to enable flash messages.

NOTE: This only works for messages flashed using the flask_unchained.Controller.flash() method; using the flask.flash() function directly will not respect this setting.

TEMPLATE_FILE_EXTENSION = '.html'

The default file extension to use for templates.

WTF_CSRF_ENABLED = False

Whether or not to enable CSRF protection.

Controller

class flask_unchained.Controller[source]

Base class for class-based views in Flask Unchained.

Concrete controllers should subclass this and their public methods will used as the views. By default view methods will be assigned routing defaults with the HTTP method GET and paths as the kebab-cased method name. For example:

from flask_unchained import Controller, injectable, route, no_route
from flask_unchained.bundles.sqlalchemy import SessionManager

class SiteController(Controller):
    class Meta:
        abstract = False  # this is the default; no need to set explicitly
        decorators = ()  # a list of decorators to apply to all view methods
                         # on the controller (defaults to an empty tuple)
        template_folder = 'site'  # defaults to the snake-cased class name,
                                       # minus any Controller/View suffix
        template_file_extension = app.config.TEMPLATE_FILE_EXTENSION = '.html'
        url_prefix = None  # optional url prefix to use for all routes
        endpoint_prefix = 'site_controller'

    # dependency injection works automatically on controllers
    session_manager: SessionManager = injectable

    @route('/')  # change the default path of '/index' to '/'
    def index():
        return self.render('index')

    # use the defaults, equivalent to @route('/about-us', methods=['GET'])
    def about_us():
        return self.render('about_us')

    # change the path, HTTP methods, and the endpoint
    @route('/contact', methods=['GET', 'POST'], endpoint='site_controller.contact')
    def contact_us():
        # ...
        return self.render('contact.html.j2')  # use an explicit filename

    @no_route
    def public_utility_method():
        return 'not a view'

    def _protected_utility_method():
        return 'not a view'

How do the calls to render know which template to use? They look in Bundle.template_folder for a folder with the controller’s Meta.template_folder and a file with the passed name and Meta.template_file_extension. For example:

class SiteController(Controller):
    # these defaults are automatically determined, unless you override them
    class Meta:
        template_folder = 'site'  # snake_cased class name (minus Controller suffix)
        template_file_extension = '.html'  # from Config.TEMPLATE_FILE_EXTENSION

    def about_us():
        return self.render('about_us')  # site/about_us.html

    def contact():
        return self.render('contact')  # site/contact.html

    def index():
        return self.render('index')  # site/index.html

# your bundle root
├── __init__.py
├── templates
│   └── site
│       ├── about_us.html
│       ├── contact.html
│       └── index.html
└── views
    └── site_controller.py
flash(msg: str, category: Optional[str] = None)[source]

Convenience method for flashing messages.

Parameters:
  • msg – The message to flash.
  • category – The category of the message.
render(template_name: str, **ctx)[source]

Convenience method for rendering a template.

Parameters:
  • template_name – The template’s name. Can either be a full path, or a filename in the controller’s template folder. (The file extension can be omitted.)
  • ctx – Context variables to pass into the template.
redirect(where: Optional[str] = None, default: Optional[str] = None, override: Optional[str] = None, **url_kwargs)[source]

Convenience method for returning redirect responses.

Parameters:
  • where – A method name from this controller, a URL, an endpoint, or a config key name to redirect to.
  • default – A method name from this controller, a URL, an endpoint, or a config key name to redirect to if where is invalid.
  • override – Explicitly redirect to a method name from this controller, a URL, an endpoint, or a config key name (takes precedence over the next value in query strings or forms)
  • url_kwargs – the variable arguments of the URL rule
  • _anchor – if provided this is added as anchor to the URL.
  • _external – if set to True, an absolute URL is generated. Server address can be changed via SERVER_NAME configuration variable which defaults to localhost.
  • _external_host – if specified, the host of an external server to generate urls for (eg https://example.com or localhost:8888)
  • _method – if provided this explicitly specifies an HTTP method.
  • _scheme – a string specifying the desired URL scheme. The _external parameter must be set to True or a ValueError is raised. The default behavior uses the same scheme as the current request, or PREFERRED_URL_SCHEME from the app configuration if no request context is available. As of Werkzeug 0.10, this also can be set to an empty string to build protocol-relative URLs.
jsonify(data: Any, code: Union[int, Tuple[int, str, str]] = <HTTPStatus.OK: 200>, headers: Optional[Dict[str, str]] = None)[source]

Convenience method to return json responses.

Parameters:
  • data – The python data to jsonify.
  • code – The HTTP status code to return.
  • headers – Any optional headers.
errors(errors: List[str], code: Union[int, Tuple[int, str, str]] = <HTTPStatus.BAD_REQUEST: 400>, key: str = 'errors', headers: Optional[Dict[str, str]] = None)[source]

Convenience method to return errors as json.

Parameters:
  • errors – The list of errors.
  • code – The HTTP status code.
  • key – The key to return the errors under.
  • headers – Any optional headers.
after_this_request(fn)[source]

Register a function to run after this request.

Parameters:fn – The function to run. It should accept one argument, the response, which it should also return

Decorators

flask_unchained.route(rule=None, blueprint=None, defaults=None, endpoint=None, is_member=False, methods=None, only_if=<py_meta_utils._missing object>, **rule_options)[source]

Decorator to set default route rules for a view function. The arguments this function accepts are very similar to Flask’s route(), however, the is_member perhaps deserves an example:

class UserResource(ModelResource):
    class Meta:
        model = User
        member_param = '<int:id>'
        include_methods = ['list', 'get']

    @route(is_member=True, methods=['POST'])
    def set_profile_pic(user):
        # do stuff

# registered like so in your ``app_bundle/routes.py``:
routes = lambda: [
    resource(UserResource),
]

# results in the following routes:
# UserResource.list             => GET  /users
# UserResource.get              => GET  /users/<int:id>
# UserResource.set_profile_pic  => POST /users/<int:id>/set-profile-pic
Parameters:
  • rule – The URL rule.
  • defaults – Any default values for parameters in the URL rule.
  • endpoint – The endpoint name of this view. Determined automatically if left unspecified.
  • is_member – Whether or not this view is for a Resource member method.
  • methods – A list of HTTP methods supported by this view. Defaults to ['GET'].
  • only_if – A boolean or callable to dynamically determine whether or not to register this route with the app.
  • rule_options – Other kwargs passed on to Rule.
flask_unchained.no_route(arg=None)[source]

Decorator to mark a Controller or Resource method as not a route. For example:

class SiteController(Controller):
    @route('/')
    def index():
        return self.render('index')

    def about():
        return self.render('about', stuff=self.utility_method())

    @no_route
    def utility_method():
        return 'stuff'

# registered like so in ``your_app_bundle/routes.py``
routes = lambda: [
    controller(SiteController),
]

# results in the following routes
SiteController.index            => GET /
SiteController.about            => GET /about

# but without the @no_route decorator, it would have also added this route:
SiteController.utility_method   => GET /utility-method

NOTE: The perhaps more Pythonic way to accomplish is simply to make all non-route methods protected by prefixing them with an underscore, eg _utility_method.

Hooks

class flask_unchained.bundles.controller.hooks.RegisterBlueprintsHook(unchained: flask_unchained.unchained.Unchained, bundle: Optional[flask_unchained.bundles.Bundle] = None)[source]

Registers legacy Flask blueprints with the app.

process_objects(app: flask_unchained.flask_unchained.FlaskUnchained, blueprints: List[flask.blueprints.Blueprint])[source]

Implement to do stuff with discovered objects (eg, registering them with the app instance).

collect_from_bundles(bundles: List[flask_unchained.bundles.Bundle]) → List[flask.blueprints.Blueprint][source]

Collect objects where type_check() returns True from bundles. Names (keys) are expected to be unique across bundles, except for the app bundle, which can override anything from other bundles.

collect_from_bundle(bundle: flask_unchained.bundles.Bundle) → Iterable[flask.blueprints.Blueprint][source]

Collect objects where type_check() returns True from bundles. Bundle subclasses can override objects discovered in superclass bundles.

type_check(obj)[source]

Implement to determine which objects in a module should be processed by this hook.

class flask_unchained.bundles.controller.hooks.RegisterBundleBlueprintsHook(unchained: flask_unchained.unchained.Unchained, bundle: Optional[flask_unchained.bundles.Bundle] = None)[source]

Registers a bundle blueprint for each bundle with views and/or template/static folders.

run_hook(app: flask_unchained.flask_unchained.FlaskUnchained, bundles: List[flask_unchained.bundles.Bundle])[source]

Hook entry point. Override to disable standard behavior of iterating over bundles to discover objects and processing them.

class flask_unchained.bundles.controller.hooks.RegisterRoutesHook(unchained: flask_unchained.unchained.Unchained, bundle: Optional[flask_unchained.bundles.Bundle] = None)[source]

Registers routes.

run_hook(app: flask_unchained.flask_unchained.FlaskUnchained, bundles: List[flask_unchained.bundles.Bundle])[source]

Hook entry point. Override to disable standard behavior of iterating over bundles to discover objects and processing them.

process_objects(app: flask_unchained.flask_unchained.FlaskUnchained, routes: Iterable[flask_unchained.bundles.controller.route.Route])[source]

Implement to do stuff with discovered objects (eg, registering them with the app instance).

collect_from_bundle(bundle: flask_unchained.bundles.Bundle)[source]

Collect objects where type_check() returns True from bundles. Bundle subclasses can override objects discovered in superclass bundles.

type_check(obj)[source]

Implement to determine which objects in a module should be processed by this hook.

Resource

class flask_unchained.Resource[source]

Base class for resources. This is intended for building RESTful APIs. Following the rules shown below, if the given class method is defined, this class will automatically set up the shown routing rule for it.

HTTP Method Resource class method name URL Rule
GET list /
POST create /
GET get /<cls.Meta.member_param>
PATCH patch /<cls.Meta.member_param>
PUT put /<cls.Meta.member_param>
DELETE delete /<cls.Meta.member_param>

So, for example:

from flask_unchained import Resource, injectable, param_converter
from flask_unchained.bundles.security import User, UserManager


class UserResource(Resource):
    class Meta:
        member_param: '<string:username>'

    def __init__(self, user_manager: UserManager = injectable):
        super().__init__()
        self.user_manager = user_manager

    def list():
        return self.jsonify(dict(users=User.query.all()))

    def create():
        user = self.user_manager.create(**data, commit=True)
        return self.jsonify(dict(user=user), code=201)

    @param_converter(username=User)
    def get(user):
        return self.jsonify(dict( user=user)

    @param_converter(username=User)
    def patch(user):
        user = self.user_manager.update(user, **data, commit=True)
        return self.jsonify(dict(user=user))

    @param_converter(username=User)
    def put(user):
        user = self.user_manager.update(user, **data, commit=True)
        return self.jsonify(dict(user=user))

    @param_converter(username=User)
    def delete(user):
        self.user_manager.delete(user, commit=True)
        return self.make_response('', code=204)

Registered like so:

routes = lambda: [
    resource('/users', UserResource),
]

Would register the following routes:

GET     /users                      UserResource.list
POST    /users                      UserResource.create
GET     /users/<string:username>    UserResource.get
PATCH   /users/<string:username>    UserResource.patch
PUT     /users/<string:username>    UserResource.put
DELETE  /users/<string:username>    UserResource.delete

See also ModelResource from the API bundle.

Route

class flask_unchained.bundles.controller.route.Route(rule: str, view_func: Union[str, function], blueprint: Optional[flask.blueprints.Blueprint] = None, defaults: Optional[Dict[str, Any]] = None, endpoint: Optional[str] = None, is_member: bool = False, methods: Union[List[str], Tuple[str, ...], None] = None, only_if: Union[bool, function, None] = <py_meta_utils._missing object>, **rule_options)[source]

This is a semi-private class that you most likely shouldn’t use directly. Instead, you should use the public functions in api/bundles/controller:Routes, and the route() and no_route() decorators.

This class is used to store an intermediate representation of route details as an attribute on view functions and class view methods. Most notably, this class’s rule and full_rule attributes may not represent the final url rule that gets registered with Flask.

Further gotchas with Controller and Resource routes include that their view_func must be finalized from the outside using TheControllerClass.method_as_view.

should_register(app: flask_unchained.flask_unchained.FlaskUnchained) → bool[source]

Determines whether or not this route should be registered with the app, based on only_if.

defaults

The URL defaults for this route.

endpoint

The endpoint for this route.

is_member

Whether or not this route is for a resource member route.

method_name

The string name of this route’s view function.

methods

The HTTP methods supported by this route.

module_name[source]

The module where this route’s view function was defined.

rule

The (partial) url rule for this route.

full_rule

The full url rule for this route, including any blueprint prefix.

full_name

The full name of this route’s view function, including the module path and controller name, if any.

Routes

flask_unchained.controller(url_prefix_or_controller_cls: Union[str, Type[flask_unchained.bundles.controller.controller.Controller]], controller_cls: Optional[Type[flask_unchained.bundles.controller.controller.Controller]] = None, *, rules: Optional[Iterable[Union[flask_unchained.bundles.controller.route.Route, Iterable[flask_unchained.bundles.controller.route.Route]]]] = None) → Iterable[flask_unchained.bundles.controller.route.Route][source]

This function is used to register a controller class’s routes.

Example usage:

routes = lambda: [
    controller(SiteController),
]

Or with the optional prefix argument:

routes = lambda: [
    controller('/products', ProductController),
]

Specify rules to only include those routes from the controller:

routes = lambda: [
    controller(SecurityController, rules=[
       rule('/login', SecurityController.login),
       rule('/logout', SecurityController.logout),
       rule('/sign-up', SecurityController.register),
    ]),
]
Parameters:
  • url_prefix_or_controller_cls – The controller class, or a url prefix for all of the rules from the controller class passed as the second argument
  • controller_cls – If a url prefix was given as the first argument, then the controller class must be passed as the second argument
  • rules – An optional list of rules to limit/customize the routes included from the controller
flask_unchained.delete(rule: str, cls_method_name_or_view_fn: Union[str, Callable, None] = None, *, defaults: Optional[Dict[str, Any]] = <py_meta_utils._missing object>, endpoint: Optional[str] = <py_meta_utils._missing object>, is_member: Optional[bool] = <py_meta_utils._missing object>, only_if: Union[bool, Callable[flask_unchained.flask_unchained.FlaskUnchained, bool], None] = <py_meta_utils._missing object>, **rule_options) → Iterable[flask_unchained.bundles.controller.route.Route][source]

Like rule(), except specifically for HTTP DELETE requests.

Parameters:
  • rule – The url rule for this route.
  • cls_method_name_or_view_fn – The view function for this route.
  • is_member – Whether or not this route is a member function.
  • only_if – An optional function to decide at runtime whether or not to register the route with Flask. It gets passed the configured app as a single argument, and should return a boolean.
  • rule_options – Keyword arguments that ultimately end up getting passed on to Rule
flask_unchained.func(rule_or_view_func: Union[str, Callable], view_func: Optional[Callable] = <py_meta_utils._missing object>, blueprint: Optional[flask.blueprints.Blueprint] = <py_meta_utils._missing object>, defaults: Optional[Dict[str, Any]] = <py_meta_utils._missing object>, endpoint: Optional[str] = <py_meta_utils._missing object>, methods: Union[List[str], Tuple[str], Set[str], None] = <py_meta_utils._missing object>, only_if: Union[bool, Callable[flask_unchained.flask_unchained.FlaskUnchained, bool], None] = <py_meta_utils._missing object>, **rule_options) → Iterable[flask_unchained.bundles.controller.route.Route][source]

This function allows to register legacy view functions as routes, eg:

@route('/')
def index():
    return render_template('site/index.html')

routes = lambda: [
    func(index),
]

It accepts an optional url rule argument:

routes = lambda: [
    func('/products', product_list_view),
]

As well as supporting the same kwargs as Werkzeug’s Rule, eg:

routes = lambda: [
    func('/', index, endpoint='home', methods=['GET', 'POST']),
]
Parameters:
  • rule_or_view_func – The view function, or an optional url rule for the view function given as the second argument
  • view_func – The view function if passed a url rule as the first argument
  • only_if – An optional function to decide at runtime whether or not to register the route with Flask. It gets passed the configured app as a single argument, and should return a boolean.
  • rule_options – Keyword arguments that ultimately end up getting passed on to Rule
flask_unchained.get(rule: str, cls_method_name_or_view_fn: Union[str, Callable, None] = None, *, defaults: Optional[Dict[str, Any]] = <py_meta_utils._missing object>, endpoint: Optional[str] = <py_meta_utils._missing object>, is_member: Optional[bool] = <py_meta_utils._missing object>, only_if: Union[bool, Callable[flask_unchained.flask_unchained.FlaskUnchained, bool], None] = <py_meta_utils._missing object>, **rule_options) → Iterable[flask_unchained.bundles.controller.route.Route][source]

Like rule(), except specifically for HTTP GET requests.

Parameters:
  • rule – The url rule for this route.
  • cls_method_name_or_view_fn – The view function for this route.
  • is_member – Whether or not this route is a member function.
  • only_if – An optional function to decide at runtime whether or not to register the route with Flask. It gets passed the configured app as a single argument, and should return a boolean.
  • rule_options – Keyword arguments that ultimately end up getting passed on to Rule
flask_unchained.include(url_prefix_or_module_name: str, module_name: Optional[str] = None, *, attr: str = 'routes', exclude: Union[List[str], Tuple[str], Set[str], None] = None, only: Union[List[str], Tuple[str], Set[str], None] = None) → Iterable[flask_unchained.bundles.controller.route.Route][source]

Include the routes from another module at that point in the tree. For example:

# project-root/bundles/primes/routes.py
routes = lambda: [
    controller('/two', TwoController),
    controller('/three', ThreeController),
    controller('/five', FiveController),
]


# project-root/bundles/blog/routes.py
routes = lambda: [
    func('/', index),
    controller('/authors', AuthorController),
    controller('/posts', PostController),
]


# project-root/your_app_bundle/routes.py
routes = lambda: [
    include('some_bundle.routes'),

    # these last two are equivalent
    include('/blog', 'bundles.blog.routes'),
    prefix('/blog', [
        include('bundles.blog.routes'),
    ]),
]
Parameters:
  • url_prefix_or_module_name – The module name, or a url prefix for all of the included routes in the module name passed as the second argument.
  • module_name – The module name of the routes to include if a url prefix was given as the first argument.
  • attr – The attribute name in the module, if different from routes.
  • exclude – An optional list of endpoints to exclude.
  • only – An optional list of endpoints to only include.
flask_unchained.patch(rule: str, cls_method_name_or_view_fn: Union[str, Callable, None] = None, *, defaults: Optional[Dict[str, Any]] = <py_meta_utils._missing object>, endpoint: Optional[str] = <py_meta_utils._missing object>, is_member: Optional[bool] = <py_meta_utils._missing object>, only_if: Union[bool, Callable[flask_unchained.flask_unchained.FlaskUnchained, bool], None] = <py_meta_utils._missing object>, **rule_options) → Iterable[flask_unchained.bundles.controller.route.Route][source]

Like rule(), except specifically for HTTP PATCH requests.

Parameters:
  • rule – The url rule for this route.
  • cls_method_name_or_view_fn – The view function for this route.
  • is_member – Whether or not this route is a member function.
  • only_if – An optional function to decide at runtime whether or not to register the route with Flask. It gets passed the configured app as a single argument, and should return a boolean.
  • rule_options – Keyword arguments that ultimately end up getting passed on to Rule
flask_unchained.post(rule: str, cls_method_name_or_view_fn: Union[str, Callable, None] = None, *, defaults: Optional[Dict[str, Any]] = <py_meta_utils._missing object>, endpoint: Optional[str] = <py_meta_utils._missing object>, is_member: Optional[bool] = <py_meta_utils._missing object>, only_if: Union[bool, Callable[flask_unchained.flask_unchained.FlaskUnchained, bool], None] = <py_meta_utils._missing object>, **rule_options) → Iterable[flask_unchained.bundles.controller.route.Route][source]

Like rule(), except specifically for HTTP POST requests.

Parameters:
  • rule – The url rule for this route.
  • cls_method_name_or_view_fn – The view function for this route.
  • is_member – Whether or not this route is a member function.
  • only_if – An optional function to decide at runtime whether or not to register the route with Flask. It gets passed the configured app as a single argument, and should return a boolean.
  • rule_options – Keyword arguments that ultimately end up getting passed on to Rule
flask_unchained.prefix(url_prefix: str, children: Iterable[Union[flask_unchained.bundles.controller.route.Route, Iterable[flask_unchained.bundles.controller.route.Route]]]) → Iterable[flask_unchained.bundles.controller.route.Route][source]

Sets a prefix on all of the child routes passed to it. It also supports nesting, eg:

routes = lambda: [
    prefix('/foobar', [
        controller('/one', OneController),
        controller('/two', TwoController),
        prefix('/baz', [
            controller('/three', ThreeController),
            controller('/four', FourController),
        ])
    ])
]
Parameters:
  • url_prefix – The url prefix to set on the child routes
  • children
flask_unchained.put(rule: str, cls_method_name_or_view_fn: Union[str, Callable, None] = None, *, defaults: Optional[Dict[str, Any]] = <py_meta_utils._missing object>, endpoint: Optional[str] = <py_meta_utils._missing object>, is_member: Optional[bool] = <py_meta_utils._missing object>, only_if: Union[bool, Callable[flask_unchained.flask_unchained.FlaskUnchained, bool], None] = <py_meta_utils._missing object>, **rule_options) → Iterable[flask_unchained.bundles.controller.route.Route][source]

Like rule(), except specifically for HTTP PUT requests.

Parameters:
  • rule – The url rule for this route.
  • cls_method_name_or_view_fn – The view function for this route.
  • is_member – Whether or not this route is a member function.
  • only_if – An optional function to decide at runtime whether or not to register the route with Flask. It gets passed the configured app as a single argument, and should return a boolean.
  • rule_options – Keyword arguments that ultimately end up getting passed on to Rule
flask_unchained.resource(url_prefix_or_resource_cls: Union[str, Type[flask_unchained.bundles.controller.resource.Resource]], resource_cls: Optional[Type[flask_unchained.bundles.controller.resource.Resource]] = None, *, member_param: Optional[str] = None, unique_member_param: Optional[str] = None, rules: Optional[Iterable[Union[flask_unchained.bundles.controller.route.Route, Iterable[flask_unchained.bundles.controller.route.Route]]]] = None, subresources: Optional[Iterable[Iterable[flask_unchained.bundles.controller.route.Route]]] = None) → Iterable[flask_unchained.bundles.controller.route.Route][source]

This function is used to register a Resource’s routes.

Example usage:

routes = lambda: [
    prefix('/api/v1', [
        resource('/products', ProductResource),
    ])
]

Or with the optional prefix argument:

routes = lambda: [
    resource('/products', ProductResource),
]

Specify rules to only include those routes from the resource:

routes = lambda: [
    resource('/users', UserResource, rules=[
       get('/', UserResource.list),
       get('/<int:id>', UserResource.get),
    ]),
]

Specify subresources to nest resource routes:

routes = lambda: [
    resource('/users', UserResource, subresources=[
       resource('/roles', RoleResource)
    ]),
]

Subresources can be nested as deeply as you want, however it’s not recommended to go more than two or three levels deep at the most, otherwise your URLs will become unwieldy.

Parameters:
  • url_prefix_or_resource_cls – The resource class, or a url prefix for all of the rules from the resource class passed as the second argument.
  • resource_cls – If a url prefix was given as the first argument, then the resource class must be passed as the second argument.
  • member_param – Optionally override the controller’s member_param attribute.
  • rules – An optional list of rules to limit/customize the routes included from the resource.
  • subresources – An optional list of subresources.
flask_unchained.rule(rule: str, cls_method_name_or_view_fn: Union[str, Callable, None] = None, *, defaults: Optional[Dict[str, Any]] = <py_meta_utils._missing object>, endpoint: Optional[str] = <py_meta_utils._missing object>, is_member: Optional[bool] = <py_meta_utils._missing object>, methods: Union[List[str], Tuple[str], Set[str], None] = <py_meta_utils._missing object>, only_if: Union[bool, Callable[flask_unchained.flask_unchained.FlaskUnchained, bool], None] = <py_meta_utils._missing object>, **rule_options) → Iterable[flask_unchained.bundles.controller.route.Route][source]

Used to specify customizations to the route settings of class-based view function. For example:

routes = lambda: [
    prefix('/api/v1', [
        controller(SecurityController, rules=[
           rule('/login', SecurityController.login,
                endpoint='security_api.login'),
           rule('/logout', SecurityController.logout,
                endpoint='security_api.logout'),
           rule('/sign-up', SecurityController.register,
                endpoint='security_api.register'),
        ]),
    ],
]
Parameters:
  • rule – The URL rule.
  • cls_method_name_or_view_fn – The view function.
  • defaults – Any default values for parameters in the URL rule.
  • endpoint – The endpoint name of this view. Determined automatically if left unspecified.
  • is_member – Whether or not this view is for a Resource member method.
  • methods – A list of HTTP methods supported by this view. Defaults to ['GET'].
  • only_if – A boolean or callable to dynamically determine whether or not to register this route with the app.
  • rule_options – Other kwargs passed on to Rule.

Utils

flask_unchained.redirect(where: Optional[str] = None, default: Optional[str] = None, override: Optional[str] = None, _anchor: Optional[str] = None, _cls: object = None, _external: Optional[bool] = False, _external_host: Optional[str] = None, _method: Optional[str] = None, _scheme: Optional[str] = None, **values) → flask.wrappers.Response[source]

An improved version of flask’s redirect function

Parameters:
  • where – A URL, endpoint, or config key name to redirect to
  • default – A URL, endpoint, or config key name to redirect to if where is invalid
  • override – explicitly redirect to a URL, endpoint, or config key name (takes precedence over the next value in query strings or forms)
  • values – the variable arguments of the URL rule
  • _anchor – if provided this is added as anchor to the URL.
  • _cls – if specified, allows a method name to be passed to where, default, and/or override
  • _external – if set to True, an absolute URL is generated. Server address can be changed via SERVER_NAME configuration variable which defaults to localhost.
  • _external_host – if specified, the host of an external server to generate urls for (eg https://example.com or localhost:8888)
  • _method – if provided this explicitly specifies an HTTP method.
  • _scheme – a string specifying the desired URL scheme. The _external parameter must be set to True or a ValueError is raised. The default behavior uses the same scheme as the current request, or PREFERRED_URL_SCHEME from the app configuration if no request context is available. As of Werkzeug 0.10, this also can be set to an empty string to build protocol-relative URLs.
flask_unchained.url_for(endpoint_or_url_or_config_key: str, _anchor: Optional[str] = None, _cls: object = None, _external: Optional[bool] = False, _external_host: Optional[str] = None, _method: Optional[str] = None, _scheme: Optional[str] = None, **values) → Optional[str][source]

An improved version of flask’s url_for function

Parameters:
  • endpoint_or_url_or_config_key – what to lookup. it can be an endpoint name, an app config key, or an already-formed url. if _cls is specified, it also accepts a method name.
  • values – the variable arguments of the URL rule
  • _anchor – if provided this is added as anchor to the URL.
  • _cls – if specified, can also pass a method name as the first argument
  • _external – if set to True, an absolute URL is generated. Server address can be changed via SERVER_NAME configuration variable which defaults to localhost.
  • _external_host – if specified, the host of an external server to generate urls for (eg https://example.com or localhost:8888)
  • _method – if provided this explicitly specifies an HTTP method.
  • _scheme – a string specifying the desired URL scheme. The _external parameter must be set to True or a ValueError is raised. The default behavior uses the same scheme as the current request, or PREFERRED_URL_SCHEME from the app configuration if no request context is available. As of Werkzeug 0.10, this also can be set to an empty string to build protocol-relative URLs.
flask_unchained.bundles.controller.utils.controller_name(cls, _remove_suffixes=None) → str[source]

Returns the snake_cased name for a controller/resource class. Automatically strips Controller, View, and MethodView suffixes, eg:

SiteController -> site
FooBarBazView -> foo_bar_baz
UsersMethodView -> users
flask_unchained.bundles.controller.utils.get_param_tuples(url_rule) → List[Tuple[str, str]][source]

Returns a list of parameter tuples in a URL rule, eg:

url_rule = '/users/<string:username>/roles/<int:id>'
param_tuples = get_param_tuples(url_rule)
assert param_tuples == [('string', 'username'), ('int', 'id')]
flask_unchained.bundles.controller.utils.get_last_param_name(url_rule) → Optional[str][source]

Returns the name of the last parameter in a URL rule, eg:

assert get_last_param_name('/foo/<int:id>/roles') is None

url_rule = '/foo/<int:id>/bar/<any:something>/baz/<string:spam>'
assert get_last_param_name(url_rule) == 'spam'
flask_unchained.bundles.controller.utils.join(*args, trailing_slash=False)[source]

Return a url path joined from the arguments. It correctly handles blank/None arguments, and removes back-to-back slashes, eg:

assert join('/', 'foo', None, 'bar', '', 'baz') == '/foo/bar/baz'
assert join('/', '/foo', '/', '/bar/') == '/foo/bar'

Note that it removes trailing slashes by default, so if you want to keep those, then you need to pass the trailing_slash keyword argument:

assert join('/foo', 'baz', None, trailing_slash=True) == '/foo/baz/'
flask_unchained.bundles.controller.utils.method_name_to_url(method_name) → str[source]

Converts a method name to a url.