Routing¶
Routing determines how URLs are mapped to view functions. When you create a
route, either by calling app.route()
or
by creating a Route
object directly, you have a number
of options for controlling which requests are matched by the route and what
information is extracted from the request and passed to your view.
Some example routes:
app = FrescoApp()
app.route('/', GET, homepage)
app.route('/login', GET, 'myapp.views.auth.login_form')
app.route('/form', [GET, POST], form_handler)
app.route('/contact', POST, send_message)
app.route('/image/<id:int>.jpg', GET, image,
name='image-original')
app.route('/image/<id:int>-thumb.jpg', GET, image, size=(100, 100),
name='image-thumb')
Or using the class-based view syntax:
class Greeter(object):
__routes__ = [
Route('/hello', GET, 'sayhello'),
Route('/bonjour', GET, 'saybonjour'),
]
Routes are tried in the order they are defined.
If you compose routes using
include()
,
it is best to structure your application
so that each set of included routes
has a unique prefix so that it stays clear which URLs resolve to which views.
Constructing Routes¶
Pattern¶
The pattern argument determines which URL paths will be matched and which won’t.
You can match on fixed paths or paths that include parameters:
Route('/blog/archive', ...)
Route('/blog/archive/<year:int>', ...)
The second route will extract an integer value for year
and pass it to the
view function as a keyword argument.
Match values from route paths using any of these keywords:
name |
example |
Matches |
---|---|---|
str |
|
Any string not including the character
|
path |
|
Any string, which may include the
character |
int |
|
Any integer |
any |
|
A string matching one of the listed options |
Method¶
The method parameter tells the route which HTTP methods to respond to. This must be a string or list of strings. You can use the symbolic constants exported by fresco for this:
from fresco import GET, POST
Route('/', GET, show_page)
Route('/', POST, edit_page)
Route('/form', [GET, POST], form_handler)
You can also use keyword arguments to map methods to views:
Route('/login', GET=login_form, POST=login_submit)
View¶
The view
parameter determines the function that will be called to handle
the request.
If your view is a normal function, you can specify the view either by passing the function object:
from myapp.views import auth
Route('/login', GET, auth.login_form)
Or using its fully qualified name as a string:
Route('/login', GET, 'myapp.views.auth.login_form')
If you are using class based views, you can substitute the name of the method here as a string. This allows you to declare routes before the view methods have been defined:
class MyViews(object):
__routes__ = [Route('/', GET, 'myview')]
def myview(self):
return Response(...)
Predicate¶
You can supply a predicate function will be tested before the request is routed to your view:
def auth_cookie_set(request):
return 'auth' in request.cookies
Route('/', GET, myview, predicate=auth_cookie_set)
Predicate functions must accept a single Request
argument
and return either True
or False
(or raise an appropriate
ResponseException
).
Decorators¶
You can supply one or more function decorators that will be wrapped around the view function when it is called from your application:
def with_template(template_file):
def view(*args, **kwargs):
template_data = func(*args, **kwargs)
return templating_engine.render(template_file, template_data)
return view
Route('/', GET, homepage, decorators=[with_template('desktop.html')])
Route('/m', GET, homepage, decorators=[with_template('mobile.html')])
Keyword arguments¶
Your route definition can contain keyword arguments that are passed through to the view function. For example:
# POST /sales/contact → contact(recipient='sales@example.com')
Route('/sales/contact', POST, contact, recipient='sales@example.com')
# POST /support/contact → contact(recipient='sales@example.com')
Route('/support/contact', POST, contact, recipient='support@example.com')
Be careful though, as some keyword arguments are used by the
Route
constructor itself. It’s safer to pass keyword
arguments as a dict, avoiding any risk of clashes:
Route('/take-payment', GET, payment_form,
kwargs={'methods': ['creditcard', 'banktransfer']})
Positional arguments¶
These are similar to keyword arguments as described above. Define them using
the args
argument to the Route
constructor.
This example would cause a positional argument value of 80
to be passed to the
image_thumbnail view function:
Route('/image/<id:int>-thumb.jpg', GET, image_thumbnail, args=(80,))
Response filters¶
The filter()
method lets you supply one or more
functions to postprocess the output of the view function:
def json_response(data):
return Response([json.dumps(data)], content_type='application/json')
Route('/', GET, homepage).filter(json_response)
You can also use filter()
as a decorator:
@Route.filter(render_with_template, 'index.html')
def homepage():
return {'message': 'Welcome to my site!'}
app = FrescoApp()
app.route('/', GET, homepage)
For more flexibility, wrap()
can
wrap the view function inside another function, which can do anything from
modifying the view’s input arguments or output, to substituting an entirely
different view function.
You can also use wrap()
as a function decorator
in the same way as filter()
.
Note that Route.decorate
is an alternative name for this function.
Before hooks¶
before()
registers a function to be run
before the view function. This function must take the same arguments as the
view and may return a response (in which case the view will not be called),
or None
, in which case the view will be called normally:
def check_logged_in(page):
if not context.request.environ.get('REMOTE_USER'):
return Response.forbidden("Please log in to view this content")
def view_page(page):
...
app = FrescoApp()
app.route('/pages/<page:str>', GET, view_page).before(check_permssion)
The above example could also be written using a function decorator style:
@Route.before(check_permssion)
def view_page(page):
...
app = FrescoApp()
app.route('/pages/<page:str>', GET, view_page)
Note that when using before()
the order of execution is:
hooks applied via decorators are run first, in the order the decorators are declared. NB this is the opposite order from which decorator functions are called.
then hooks added to the route are applied, in the order in which they were added.
Passing request data to the view¶
Often you would like keyword arguments to be extracted from form submissions or cookies. For example, to read an argument from the POST or GET form data:
from fresco.routeargs import PostArg
Route('/sales/contact', POST, contact, sender=PostArg())
The advantages of writing views this way are:
Views have meaningful function signatures. The purpose of
def show_bookings(day, user)
is clear at a glance, whereasshow_bookings(request)
requires you to read the implementation to discover how request parameters are used.Views are easier to test. You can usually avoid mocking the full (and potentially slow) request cycle by passing test values directly to the view.
Views are easier to reuse. Views can more easily delegate to each other by passing simple objects as arguments, without needing to modify and reparse the request object at each step.
As well as extracting values from submitted form or querystring data, fresco supports converting values to a specific type:
from fresco.routeargs import GetArg
# Convert value to an int
# GET /details?product_id=42 → view_product(product_id=42)
Route('/details', GET, view_product, product_id=GetArg(int))
# Convert to a list of ints
# GET /bookings?day=2&day=3 → show_bookings(day=[2, 3])
Route('/bookings', GET, show_bookings, day=GetArg([int]))
And supplying default values:
Route('/preferences', POST, set_prefs,
contact_opt_in=PostArg(default=False))
If the user doesn’t provide a value and no default has been
specified, BadRequest
is raised. You can change the
exception class if you want different behaviour:
from fresco.exceptions import NotFound
Route('/details', GET, view_product,
product_id=GetArg(exception=NotFound))
If your form inputs do not match the names you want in your function signature you can extract from an input with a different name:
# GET /details?id=123 → details(product_id=123)
Route('/details', GET, details, product_id=PostArg(key='id'))
PostArg
, GetArg
and
CookieArg
all provide the same interface and allow
you to read from the query string, form data (post or get), or cookies
respectively.
You can also pass the entire POST or GET data form dictionary to your view:
from fresco.routeargs import PostData
Route('/profile', POST, profile_update, data=PostData())
Route('/search', GET, search, query=GetData())
Passing the entire request or form dictionary¶
Routes can be configured to pass the raw request object to view functions as a positional argument:
Route('/set-language', POST, set_language, provide_request=True)
The RRoute
class exists to make it easy to enable this
for all views attached to a route collection:
from fresco.routing import RouteCollection, RRoute
routes = RouteCollection(route_class=RRoute)
routes.route('/', GET=view_homepage)
Other request object parameters¶
routearg()
wraps a custom function to extract
arbitrary information from request. For example:
from fresco.routeargs import routearg
Route('/contact', [GET, POST], contact_form, method=routearg(lambda r: r.method))
Adding custom route converters¶
You can match custom expressions in routes by creating a subclass of
Converter
and decorating it with
register_converter()
:
import collections
from fresco.routing import Converter, register_converter
LatLng = collections.named_tuple('LatLng', 'lat lng')
@register_converter('latlng')
class LatLngConverter(Converter):
"""
Convert latitude-longitude pairs into a ``LatLng`` named tuple.
"""
pattern = r'-?\d+(?:\.\d+)?,\-?d+(?:\.\d+)?'
def from_string(self, s):
latlng = LatLng(map(float, s.split(',')))
if -90 <= latlng.lat <= 90 and -180 <= latlng.lng <= 180:
return latlng
else:
raise ValueError(s)
def to_string(self, latlng):
return '%s,%s' % latlng
Use the name supplied to
register_converter()
in your route definitions:
Route('/map/<location:latlng>', GET, view_map)
With this pattern the route will directly pass a LatLng
object into your
view.
Should from_string
raise a ValueError
the route is deemed not to have matched
and the next route will be tried
or a 404 returned if no other route matches. In this case you could use this
Reverse routing - Generating URLs¶
The urlfor()
function generates valid urls given a route
name or a reference to a routed function:
from myapp.views import product_details
app = FrescoApp()
app.route('/details/<product_id:int>', GET, product_details)
Calling urlfor(product_details, product_id=7)
will now return http://localhost/details/7
.
You can also specify the view function as a string, eg:
urlfor('myapp.views.product_details', product_id=7)
context.view_self
is a globally available handle on the instance of any
class based view, which can simplify URL generation:
urlfor(context.view_self.product_details, product_id=7)
urlfor and view classes¶
If you only have one instance of your class based view, you can pass either the
(unbound) class method or the method name to urlfor()
. For example with a setup
similar to this:
from myapp.views import BlogViews
app = FrescoApp()
app.include('/blog', BlogViews())
Either of the following will work:
# Generate the URL for the `index` method on the `BlogViews` class
urlfor(BlogViews.index)
# Generate the URL for the `index` method on the `BlogViews` class
# defined in myapp.views
urlfor('myapp.views.BlogViews.index')
If you use the same class
view in several routes, you will need a way to distinguish between them when
calling urlfor()
. If you are generating routes for other views in the same class you can use self
or context.view_self
and all will be well:
class BlogViews(object):
def view_post(self, post_id):
...
permalink = urlfor(self.permalink, post_id=post_id)
Or for example from within a template:
<a href="{{ urlfor(context.view_self.blog_index) }}">home</a>
However if you need to generate URLs for other view classes
(ie not the current context.view_self
), you will need a handle on the view
class. One simple pattern is to
to keep a handle on your views when you create them:
freds_blog = BlogViews()
company_blog = BlogViews()
app = FrescoApp()
app.include('/fred/blog', freds_blog)
app.include('/blog', company_blog)
Then you can reference the views directly:
from myapp import freds_blog
# Generate the URL for the `index` method on the `freds_blog` object
urlfor(freds_blog.blog_index)
Or by passing the name as a string:
# Generate the URL for the `index` method on the `freds_blog` object
# located in the module `myapp`
urlfor('myapp.freds_blog.blog_index')
Multiple routes, same view¶
A single view may be routed to multiple URLs. In this case, you must supply a name argument to distinguish them:
from myapp.views import list_users
app = FrescoApp()
app.route('/staff/directory', GET, list_users, role='staff',
name='staff-directory')
app.route('/student/directory', GET, list_users, role='student',
name='student-directory')
Now you can specify which route you want by passing the appropriate name to
urlfor()
:
# Will return '/staff/directory'
urlfor('staff-directory')
# Will return '/student/directory'
urlfor('student-directory')
Note that if you call urlfor()
with the view function
itself, the first configured view will be returned:
# Will return '/staff/directory'
urlfor(list_users)
Default route parameters¶
You can specify default values for routing parameters by passing a _default
argument:
app = FrescoApp()
app.route('/products/<category:str>', GET, user_homepage,
category_default='all')
You can pass a function if you want this to be generated dynamically. The function will be passed the current request object and should return the value to be used in the URL:
def get_username(request):
user = request.environ.get('myapp.logged_in_user', None)
if user:
return user.username
app = FrescoApp()
app.route('/<username:str>/profile', GET, view_user_profile,
username_default=get_username)
Including and delegating routes¶
Fresco currently uses two methods for combining routes together into a single app.
include()
copies the routes from another routable object (eg a FrescoApp instance or a
module/class with a __routes__
attribute):
class Greeter(object):
__routes__ = [
Route('/sayhello', GET, 'sayhello'),
]
def sayhello(self, name):
return Response(['hello ' + name + '!'])
app = FrescoApp()
app.include('/<name:str>', Greeter())
The delegate()
method appears superficially very similar:
app = FrescoApp()
app.delegate('/<name:str>', Greeter())
However instead of including a copy of the object’s routes in your app, it causes a recursive lookup when the base path is matched.
Both of the examples above will respond to URLs like /boris/sayhello
and
/ken/sayhello
, but internally the mechanism is quite different .
If you are not sure whether to use inlcude or delegate,
then use include()
,
this is the simplest and best supported method.
However you should use
delegate()
if you need to:
Use
urlfor()
to generate URLs for the same routable object exposed at multiple paths.Generate routes dynamically (see below)
delegate()
supports a name
argument,
allowing you to distinguish between multiple copies of the same routeable
object:
app.delegate('/london', another_app, name="london")
app.delegate('/paris', another_app, name="paris")
You can then generate URLs using the name as a prefix, eg:
urlfor('london:<route-name>')
urlfor('paris:<route-name>')
It is a limitation of delegate()
that you
cannot use urlfor without specifying a name prefix.
View classes and inheritance¶
When subclassing from a view class it’s a common requirement to modify the views.
To add new routes,
add them to the base class’s __routes__
attribute:
class UserViews(object):
__routes__ = [
Route('/home', GET, 'user_homepage', name='homepage'),
Route('/orders', GET, 'view_orders'),
Route('/preferences', GET, 'view_prefs'),
]
class AdminUserViews(UserViews):
__routes__ = UserViews.__routes__ + [
Route('/dashboard', GET, 'admin_dashboard'),
Route('/all_orders', GET, 'view_all_orders'),
]
This approach is generally not practical
if you need to remove or replace existing routes.
For this use RouteCollection
:
class AdminUserViews(UserViews):
__routes__ = RouteCollection(UserViews)
__routes__.remove(UserViews.view_orders)
__routes__.replace(
'homepage', Route('/dashboard', GET, 'admin_dashboard'))
__routes__ += [Route('/all_orders', GET, 'view_all_orders')]
Dynamic routes¶
delegate()
can also allow routes to be
constructed dynamically:
class Greeter(object):
def __init__(self, lang):
self.lang = lang
@property
def __routes__(self):
if self.lang == 'fr':
return [Route('/bonjour', GET, self.greet_in_french)]
else:
return [Route('/hello', GET, self.greet_in_english)]
def greet_in_english(self):
return Response(['hello'])
def greet_in_french(self):
return Response(['bonjour'])
app = FrescoApp()
app.delegate("/<lang:any('fr', 'en')>", Greeter, dynamic=True)
Two important points to note here:
The argument to
delegate()
must be a factory function that returns the routeable object. You can pass the class object (as in this example) or create a custom factory function.Fresco will call your factory function while traversing routes, passing any arguments parsed from the URL to the factory function.
You can also use route delegation within class based views by using an instance
of DelegateRoute
:
from fresco.routing import Route, DelegateRoute, GET
from myapp.blog import BlogViews
class MyWebApp(object):
__routes__ = [
Route('/', GET, 'homepage'),
DelegateRoute('/blog', BlogViews)
]
Using dynamic views to handle common arguments¶
Very often routes use a similar set of routing args,
for example each of the following routes requires a username
argument:
app.route('/<username:str>/home', GET, user_homepage)
app.route('/<username:str>/orders', GET, view_orders)
app.route('/<username:str>/preferences', GET, view_prefs)
...
Let’s use a view class to factor out the repeated code:
class UserViews(object):
__routes__ = [
Route('/home', GET, 'user_homepage'),
Route('/orders', GET, 'view_orders'),
Route('/preferences', GET, 'view_prefs'),
]
def __init__(self, username):
self.username = username
def user_homepage(self):
return Response(['hello %s' % self.username])
We use this in our application with
delegate()
.
By specifying dynamic=True
the application will construct a new instance of the class for each request:
app.delegate('/<username:str>', UserViews, dynamic=True)
Fallthrough¶
You can tell fresco’s routing system to ignore particular response codes
from routed views, by passing the fallthrough_on
parameter:
app.include('/', SomeThirdParytApp, fallthrough_on=[404])
app.route_wsgi('/', AnotherApp, fallthrough_on=[404])
If a 404 error is returned from either of these routed applications, control will pass to the next matching route, allowing you to easily chain together apps which are not otherwise designed to be cooperative.
API reference: fresco.routing¶
- class fresco.routing.DelegateRoute(prefix, view, dynamic=False, *args, **kwargs)[source]¶
A specialisation of Route that is used to delegate a path prefix to another route collection.
- class fresco.routing.Pattern[source]¶
Patterns are matchable against URL paths using their
match
method. If a path matches, this should return a tuple of(positional_arguments, keyword_arguments)
extracted from the URL path. Otherwise this method should returnNone
.Pattern objects may also be able to take a tuple of
(positional_arguments, keyword_arguments)
and return a corresponding URL path.
- class fresco.routing.Route(pattern: str | Pattern, methods=None, view=None, kwargs=None, args=None, name=None, predicate=None, decorators=None, filters=None, fallthrough_on=None, provide_request: bool | None = None, **_kwargs)[source]¶
Represent a URL routing pattern
- add_prefix(path)[source]¶
Return a copy of the Route object with the given path prepended to the routing pattern.
- before(func, *args, **kwargs)[source]¶
Call a function before passing the request to the view.
Route(‘/view-secret-page’, GET, view_secret_page) .before(check_logged_in)
- Parameters:
func – The function. Must accept the same arguments as the view and may return either
None
or aResponse
object. If a response is returned the view will not be invoked.args – Extra positional args to pass to
func
kwargs – Extra keyword args to pass to
func
- bindto(instance)[source]¶
Return copy of the route bound to a given instance.
Use this when traversing view classes.
- filter(func, *args, **kwargs)[source]¶
Filter the output of the view function through other functions:
Route('/user/<id:int>', GET, edituser) .wrap(require_ssl) .filter(render, 'user.tmpl')
- Parameters:
func – The filter function. Must accept the output of the view and return the filtered response
args – Extra positional args to pass to
func
kwargs – Extra keyword args to pass to
func
- getdecoratedview(view: Callable) Callable [source]¶
Return the view callable decorated with any decorators defined in the route
- path(*args, **kwargs)[source]¶
Build the path corresponding to this route and return a tuple of:
(<path>, <remaining args>, <remaining kwargs>)
remaining args
andremaining kwargs
are any values from*args
and**kwargs
not consumed during path construction.See also
pathfor()
.
- pattern_class¶
The default class to use for URL pattern matching
alias of
ExtensiblePattern
- provide_request = False¶
Always provide an positional
request
argument to views
- routed_args_default: Dict[str, Any]¶
Default values to use for path generation
- viewspecs¶
A mapping of HTTP methods to view specifiers
- class fresco.routing.RouteCollection(routes=None, route_class=None, cache=True)[source]¶
A collection of
Route
objects, RouteCollections:Contain methods to configure routes, including the ability to delegate URLs to other RouteCollections
Can map from a request to a view
- add_prefix(prefix)[source]¶
Return a copy of the RouteCollection with the given path prepended to all routes.
- delegate(path, app, dynamic=False, *args, **kwargs)[source]¶
Delegate all requests under
path
toapp
- Parameters:
path – the path prefix at which the app will be available
app – a FrescoApp instance
- get_route_traversals(path: str, method: str | None, request: Request | None = None) Iterator[RouteTraversal] [source]¶
Generate RouteTraversals for routes matching the given path and method:
for rt in routecollection.get_route_traversals('/foo/bar', GET): print("Route is", rt.route) print("Arguments extracted from the path:", rt.args, rt.kwargs) print("RouteCollections are:", rt.collections_traversed)
- Parameters:
path – the URL path to match (usually this is
PATH_INFO
)method – the HTTP method to match (usually this is
REQUEST_METHOD
). May beNone
, in which case matching will be performed on thepath
argument only.request – a
Request
object
- Returns:
A generator yielding
RouteTraversal
objects
- include(path, views, fallthrough_on=None)[source]¶
Include a view collection at the given path.
The included view collection’s url properties will be modified to generate the prefixed URLs.
- Parameters:
path – Path at which to include the views
views – Any collection of views (must expose a
__routes___
attribute)fallthrough_on – a fallthrough_on argument, passed to :class:~`fresco.routing.Route`
- max_route_cache_size = 500¶
The maximum size for the
(method, path) => route
cache
- min_route_cache_size = 20¶
The minimum size for the
(method, path) => route
cache
- pathfor(viewspec, *args, **kwargs)[source]¶
Return the path component of the url for the given view name/function spec.
- Parameters:
viewspec – a view name, a reference in the form
'package.module.viewfunction'
, or the view callable itself.
- remove(viewspec)[source]¶
Remove the route(s) identified by
viewspec
- Parameters:
viewspec – The routed view callable, or its fully qualified name (‘package.module.view_function’), or the name of a named route
- replace(viewspec, newroute)[source]¶
Replace the route(s) identified by
viewspec
with a new Route.- Parameters:
viewspec – The routed view callable, or its fully qualified name (‘package.module.view_function’), or the name of a named route
newroute – The replacement route. This may be None, in which case the route will be removed without replacement
- route(pattern: str | Pattern, methods: str | Iterable[str] | None = None, view: str | Callable | None = None, *args, route_class: Type[Route] | None = None, **kwargs)[source]¶
Match a URL pattern to a view function. Can be used as a function decorator, in which case the
view
parameter should not be passed.- Parameters:
pattern – A string that can be compiled into a path pattern
methods – A list of HTTP methods the view is bound to
view – The view function. If not specified a function decorator will be returned.
Other parameters are as for the
Route
constructor.
- route_all(path, methods=None, view=None, *args, route_class=None, **kwargs)[source]¶
Expose a view for all URLs starting with
path
.- Parameters:
path – the path prefix at which the view will be routed
- route_wsgi(path: str, wsgiapp: Callable | str, rewrite_script_name: bool = True, *args, **kwargs)[source]¶
Route requests to
path
to the given WSGI application- Parameters:
path – the mount point for the app
wsgiapp – the WSGI callable, or the path to a callable in the format
myapp.module.do_wsgi
.rewrite_script_name – if
True
(the default), the mount point specified bypath
will be shifted offPATH_INFO
and into theSCRIPT_NAME
environ key.
- routefor(viewspec: Callable | str) Route [source]¶
Return the
Route
instance associated withviewspec
.Views may have multiple routes bound, in this case the first bound route will always take precedence.
This method does not resolve delegated routes.
- Parameters:
viewspec – a view callable or a string in the form ‘package.module.viewfunction’
API reference: fresco.routeargs¶
- class fresco.routeargs.CookieArg(converter=None, key=None, default=<object object>, exception=<class 'fresco.exceptions.MissingRouteArg'>)[source]¶
Extract a view keyword argument from
request.cookies
.Example:
@app.route('/', GET, message=CookieArg(key='msg', default=None)) def view(message, message): return Response([message])
- fresco.routeargs.FormArg¶
FormArg may be used as an alias for PostArg
- fresco.routeargs.FormData¶
FormData may be used as an alias for PostData
- class fresco.routeargs.GetArg(converter=None, key=None, default=<object object>, exception=<class 'fresco.exceptions.MissingRouteArg'>)[source]¶
Extract a view keyword argument from
request.query
.Example:
@app.route('/add', GET, a=QueryArg(int), b=QueryArg(int)) def view(a, b): return Response(['a + b = %d' % (a + b)])
- class fresco.routeargs.GetData(default=<object object>, exception=<class 'fresco.exceptions.MissingRouteArg'>)[source]¶
Make the
request.form
MultiDict available as a view argument.Example:
@app.route('/form', POST, data=GetData()) def view(formdata, data): ...
- class fresco.routeargs.PostArg(converter=None, key=None, default=<object object>, exception=<class 'fresco.exceptions.MissingRouteArg'>)[source]¶
Extract a view keyword argument from
request.form
.Example:
@app.route('/mul', POST, a=FormArg(int), b=FormArg(int)) def view(a, b): return Response(['a * b = %d' % (a * b)])
- class fresco.routeargs.PostData(default=<object object>, exception=<class 'fresco.exceptions.MissingRouteArg'>)[source]¶
Make the
request.form
MultiDict available as a view argument.Example:
@app.route('/form', POST, data=FormData()) def view(formdata, data): ...
- fresco.routeargs.QueryArg¶
QueryArg may be used as an alias for GetArg
- fresco.routeargs.QueryData¶
QueryData may be used as an alias for GetData
- class fresco.routeargs.RequestObject(default=<object object>, exception=<class 'fresco.exceptions.MissingRouteArg'>)[source]¶
Make the request object itself available as a view argument.
Example:
@app.route('/form', POST, request=RequestObject()) def view(formdata, request): ...
- class fresco.routeargs.SessionArg(converter=None, key=None, default=<object object>, exception=<class 'fresco.exceptions.MissingRouteArg'>)[source]¶
Extract a view keyword argument from
request.session
.Example:
@app.route('/mul', POST, a=FormArg(int), b=FormArg(int)) def view(a, b): return Response(['a * b = %d' % (a * b)])
- fresco.routeargs.routearg(func, *args, **kwargs)[source]¶
Construct a
RouteArg
instance that callsfunc
with the request object as an argument and passes the return value to the routed view:def extract_name(req): return req.get('name') Route('/', GET, myview, name=routearg(extract_name))
Additional positional and keyword arguments may be passed, eg:
def name_is(req, *friends): return req.get('name') in friends Route('/', GET, myview, is_a_friend=routearg(name_is, 'fred', 'jim'))