Applications and Routes¶
When it comes to Python and the web, the world speaks WSGI (Web
Server Gateway Interface). And a Clastic provides
exactly that: A WSGI Application
.
Clastic Applications are composed using Python code, plain and
simple. No decorators, no settings.py
, no special configuration
file. Just constructed objects, used to construct other objects.
Specifically, Applications consist of Routes, Resources, Middleware, and Error Handlers.
The Application¶
-
class
clastic.
Application
(routes=None, resources=None, middlewares=None, render_factory=None, error_handler=None, **kwargs)[source]¶ The central object around which Clastic revolves.
The Application initializer checks that all endpoints, render functions, and middlewares have their dependencies satisfied before completing construction. If the signatures don’t line up, an
NameError
will be raised.Parameters: - routes (list) – A list of Route instances, SubApplications, or
tuples. Defaults to
[]
. Add more withadd()
. - resources (dict) – A dict which will be injectabled to Routes and
middlewares in this Application. Keys must all be strings,
values can be any Python object. Defaults to
{}
. - middlewares (list) – A list of Middleware objects.
Defaults to
[]
. - render_factory (callable) – An optional callable to convert
render arguments into callables, such as
AshesRenderFactory
. - debug (bool) – Set to
True
to enable certain debug behavior in the application. - error_handler – Advanced: An optional ErrorHandler instance.
Defaults to
ErrorHandler
. If debug isTrue
, defaults toContextualErrorHandler
. - slash_mode (str) – Advanced: Controls how the Application handles trailing slashes.
One of
clastic.S_REDIRECT
,S_STRICT
,S_REWRITE
. Defaults toS_REDIRECT
.
In addition to arguments, certain advanced behaviors can be customized by inheriting from
Application
and overriding attributes:request_type
,response_type
,default_error_handler_type
, anddefault_debug_error_handler_type
.-
add
(entry, index=None, **kwargs)[source]¶ Add a
Route
orSubApplication
. A tuple may also be passed, which will be converted accordingly.Note that as each Route is bound, the Application checks whether the Route’s dependencies can be satisfied by the Application.
-
default_debug_error_handler_type
¶
-
default_error_handler_type
¶ alias of
clastic.errors.ErrorHandler
-
get_local_client
()[source]¶ Get a simple local client suitable for using in tests. See Werkzeug’s test Client for more info.
-
request_type
¶ alias of
werkzeug.wrappers.request.Request
-
response_type
¶ alias of
werkzeug.wrappers.response.Response
-
serve
(address='0.0.0.0', port=5000, use_meta=True, use_lint=True, use_reloader=True, use_debugger=True, use_static=True, static_prefix='static', static_path=None, processes=None, **kw)[source]¶ Serve the Application locally, suitable for development purposes.
Parameters: - address (str) – IP address to bind to (defaults to
"0.0.0.0"
, which works for all IPs) - port (int) – Port to bind on (defaults to
5000
) - use_meta (bool) – Whether to automatically add the
MetaApplication to
/_meta/
. Defaults toTrue
. - use_reloader (bool) – Whether to automatically reload the application when changes
to the source code are saved. Defaults to
True
. - use_debugger (bool) – Whether to wrap the Application in werkzeug’s debug middleware for interactive debugging. (Note that a PIN will be output on stdout and must be used to interact with the error pages.)
- use_static (bool) – Whether to automatically serve
static_path under static_prefix. Defaults to
True
. - static_prefix (str) – The URL path where static assets will be served. Defaults to /static/.
- static_path (str) – The filesystem path to static assets to
serve if use_static is
True
. Defaults to a path named “static” in the current directory ("./static/"
). - processes (int) – Number of processes to serve (not recommended for use with use_debugger). (Use sparingly; not for production.)
Warning
The server provided by this method is not intended for production traffic use.
- address (str) – IP address to bind to (defaults to
-
set_error_handler
(error_handler=None)[source]¶ Sets the ErrorHandler instance. Call without arguments to reset the error handler to default.
Note
This method does not reset error handlers in Routes which have already been bound.
- routes (list) – A list of Route instances, SubApplications, or
tuples. Defaults to
Route Types¶
-
class
clastic.
Route
(pattern, endpoint, render=None, render_error=None, **kwargs)[source]¶ While Clastic may revolve around the
Application
, Applications would be nothing without the Routes they contain.The
Route
object is basically a combination of three things:- A path pattern
- An endpoint function
- A render function or argument
Put simply, when a request matches a Route’s pattern, Clastic calls the Route’s endpoint function, and the result of this is passed to the Route’s render function.
In reality, a Route has many other levers to enable more routing features.
Parameters: - pattern (str) – A Pattern Mini-Language-formatted string.
- endpoint (callable) – A function to call with Injectables, which returns a Response or a render context which will be passed to the Route’s render function.
- render (callable) – An optional function which converts the output of endpoint into a Response. Can also be an argument which is passed to an Application’s render_factory to generate a render function. For instance, a template name or path.
- middlewares (list) – An optional list of middlewares specific to this Route.
- resources (dict) – An optional dict of resources specific to this Route.
- methods (list) – A list of text names of HTTP methods which a request’s method must match for this Route to match.
- render_error (callable) – Advanced: A function which converts
an
HTTPException
into a Response. Defaults to the Application’s error handler.
Note
Method-specific subtypes have identical signatures to Route
.
The only steps necessary to make a Route method-specific is to import the type and add it to the tuple:
Application(routes=[("/home/", home_ep, render_func)])
Becomes:
from clastic import GET
...
Application(routes=[GET("/home/", home_ep, render_func)])
If an Application contains Routes which match the path pattern, but
none of the Routes match the method, Clastic will automatically raise
a MethodNotAllowed
exception for you, which results
in a 405
HTTP error response to client.
SubApplications¶
Clastic features strong composability using straightforward Python
constructs. An Application
contains Route
instances,
and those Routes can come from other Applications, using
SubApplication
.
-
class
clastic.
SubApplication
(prefix, app, rebind_render=False, inherit_slashes=True)[source]¶ Enables
Application
instances to be embedded in other Applications.Note that Routes are copied into the embedding Application, and further modifications to the Application after embedding may not be visible in the root Application.
Parameters: - prefix (str) – The path prefix under which the embedded Application’s routes
will appear.
/
is valid, and will merge the routes in at the root level of the parent application. - app (Application) – The Application instance being embedded.
- rebind_render (bool) – Advanced: Whether render arguments
should be reinterpreted by the embedding application’s render
factory. Defaults to
False
. - inherit_slashes (bool) – Advanced: Whether to inherit the
embedding application’s handling of trailing slashes. Defaults
to
True
.
Note
This object rarely needs to be constructed manually, because this behavior is built in to the default Application routes argument handling.
Application(routes=[('/prefix', other_app)])
automatically creates a SubApplication and embeds it.- prefix (str) – The path prefix under which the embedded Application’s routes
will appear.
Injectables¶
Clastic automatically provides dependencies to middlewares and endpoint/render functions. These dependencies can come from one of four sets:
- Route path pattern
- Application resources - Arguments which
are valid for the lifespan of the
Application
, like configuration variables. - Middleware provides - Arguments provided by an Application’s middleware. See Middleware for more information.
- Clastic built-ins - Special arguments that are always made available by Clastic. These arguments are also reserved, and conflicting names will raise an exception. A list of these arguments and their meanings is below.
Clastic provides a small, but powerful set of built-in arguments for every occasion. These arguments are reserved by Clastic, so know them well.
Note
Advanced and primarily-internal built-ins are prefixed with an underscore.
Built-in injectables
request¶
Probably the most commonly used built-in,request
is the currentRequest
object being handled by the Application. It has the URL arguments, POST parameters, cookies, user agent, other HTTP headers, and everything from the WSGI environ. request
next¶
next
is only for use by Middleware, and represents the next function in the execution chain. It is called with the arguments the middleware class declared that it would provide. If the middleware does not provide any arguments, then it is called with no arguments.
next
allows a middleware to not worry about what middleware or function comes after it in the chain. All the middleware knows is that the result of (or exception raised by) thenext
function is the Response that a client would receive.Middleware functions must accept
next
as the first argument. If a middleware function does not accept thenext
argument, or if a non-middleware function accepts thenext
argument, an exception is raised at Application initialization.
context¶
context
is the output of the endpoint side of the middleware chain. By convention, it is almost always a dictionary of values meant to be used in templating or other sorts of Response serialization.Accepting the
context
built-in outside of the render branch of middleware will cause an exception to be raised at Application initialization. context
_application¶
TheApplication
instance in which this middleware or endpoint is currently embedded. The Application has access to all routes, endpoints, middlewares, and other fun stuff, which makes_application
useful for introspective activities, like those provided by Clastic’s built-inMetaApplication
.
_route¶
The Route which was matched by the URL and is currently being executed. Also mostly introspective in nature._route
has a lot of useful attributes, such asendpoint
, which can be used to shortcut execution in an extreme case.
_error¶
Only available to therender_error
functions/methods configured, this built-in is available when anHTTPException
has been raised or returned.
_dispatch_state¶
An internally-managed variable used by Clastic’s routing machinery to generate useful errors. SeeDispatchState
for more info.
And, that’s it! All other argument names are unreserved and yours for the binding.
Clastic Routing in a Nutshell¶
- Routes are always checked in the same order they were added to the Application. Some frameworks reorder routes, but not Clastic.
- Route methods must also match, or a
MethodNotAllowed
is raised. - If a Route pattern matches, except for a trailing slash, the
Application may redirect or rewrite the request, depending on the
Application/Route’s
slash_mode
.
Pattern Mini-Language¶
Route patterns use a minilanguage designed to minimize errors and maximize readability, while compiling to Python regular expressions remaining powerful and performant.
- Route patterns are a subset of regular expressions designed to match URL paths, and is thus aware of slashes. Slashes separate “segments”, which can be one of three types: string, int, float.
- By default a pattern segment matches one URL path segment, but clastic also supports matching multiples of segments at once: (“:” matches one segment, “?” matches zero or one segment, “*” matches 0 or more segments, and “+” matches 1 or more segments).
- Segments are always named, and the names are checked against other injectables for conflicts.
- Be careful when getting too fancy with URL patterns. If your pattern doesn’t match, by default users will see a relatively plain 404 page that does not offer much help as to why their URL is incorrect.
Advanced Routing¶
- Unlike Werkzeug/Flask’s default routing, clastic does not reorder routes. Routes are matched in order.
- Applications can choose whether to redirect on trailing slashes
- Clastic’s one-of-a-kind routing system allows endpoint functionsand middlewares to participate in routing by raising certain standard errors, telling clastic to continue to check other routes
- It’s even possible to route to a separate WSGI application (i.e., an application not written in Clastic)
- NullRoute (configurable)
-
class
clastic.
RerouteWSGI
(wsgi_app)[source]¶ Raise or use as a route endpoint to route to a different WSGI app.
Note that this will have unintended consequences if you have done stateful operations to the environ (such as reading the body of the request) or already called start_response or something similar.
It’s safest to put this high in the routing table (and middleware stack).
-
class
clastic.application.
DispatchState
[source]¶ The every request handled by an
Application
creates aDispatchState
, which is used to track relevant state in the routing progress, including which routes were attempted and what exceptions were raised, if any.Note
Objects of this type are constructed internally and are not really part of the Clastic API, except that they are one of the built-in injectables.