Subrequests

The fresco.subrequests module contains a handful of functions that lets your views embed output from other views.

Example:

from fresco import subrequest

@app.route('/', GET)
def homepage():
    return render('homepage.html',
                  {'promoted_products': subrequest('promoted-products'),
                   'shopping_cart': subrequest('shopping-cart')}

@app.route('/__promoted_products', GET, name='promoted-products')
def promoted_products():
    "render the list of products currently on promotion"

@app.route('/__cart', GET, name='shopping-cart')
def shopping_cart():
    "render the shopping cart for the current user"

An application that uses subrequests will typically have a number of small views, each with responsibility for rendering only a single well defined area of content. New pages can be formed by composing existing views without the need to duplicate logic.

This has a few benefits:

  • Testing: instead of having to render a whole page with every possible combination of behaviour, you can test individual components, making your tests lighter and more targeted.
  • Client side JavaScript can call the individual views to update components of the page without the need for a full refresh.
  • Fine-grained caching: the output of expensive-to-generate sub views can be cached individually without affecting the other parts of your page.
fresco.subrequests.subrequest(view, *args, **kwargs)[source]

Return the response generated by a subrequest to view

This behaves differently depending on the value of view:

  • A string containing a ``/``: a full request context is constructed to emulate a request to the given path. The subrequest will invoke all middleware layers and application hooks.
  • A callable: a new subrequest context will be created and view(*args, **kwargs) will be called. Middleware and application hooks will not be called, and any RouteArgs defined will not be resolved.
  • Any other value: the view function is looked up using the same route resolution rules as urlfor(). Middleware and hooks will be skipped, but RouteArgs will be resolved.

If you pass in a view callable you can force RouteArgs to be resolved by specifying _resolve=True.

You can force a full request to be emulated by specifying _full=True.

Passing additional positional and keyword arguments has a different effect depending on the value of view, _resolve and _full:

  • If view is a path, or if _full is True, *args and **kwargs are passed to requestcontext(), and may be used to customize the WSGI environment used for the subrequest.
  • If view is a callable and _resolve is False, *args and **kwargs are passed to the view callable.
  • Otherwise *args and **kwargs are passed to the route lookup mechanism and should provide the values defined in the route’s path. kwargs values also override any RouteArgs defined by the route. These will only be generated from the request if a corresponding value is not present in kwargs.
Parameters:
  • view – The target path, view callable, or viewspec.
  • _mode – One of raw, str or bytes. If str, the content of the subrequest will be returned as a string. If bytes, the content will be returned as a byte string. If raw, the raw response will be returned. In this case the caller is responsible for iterating the content and calling any functions in response.onclose.
  • _resolve – if True, callable views will be resolved via the route traversal mechanism, allowing routed arguments to be set from the current request.
  • _full – if True, a full new request context will be set up ensuring application hooks and middleware are called for the subrequest. In this case any additional arguments are passed to requestcontext() and used to populate the new request environ.
  • args – Additional positional arguments
  • kwargs – Additional keyword arguments
fresco.subrequests.subrequest_raw(*args, **kwargs)[source]

Perform a subrequest and return the raw response object. See subrequest() for details

fresco.subrequests.subrequest_bytes(*args, **kwargs)[source]

Perform a subrequest and return the response content as a byte string. See subrequest() for details