Serving Static Assets¶
This collection of recipes describes how to serve static assets in a variety of manners.
Serving File Content Dynamically¶
Usually you'll use a static view (via "config.add_static_view") to serve file content that lives on the filesystem. But sometimes files need to be composed and read from a nonstatic area, or composed on the fly by view code and served out (for example, a view callable might construct and return a PDF file or an image).
By way of example, here's a Pyramid application which serves a single static
file (a jpeg) when the URL
/test.jpg is executed:
1from pyramid.view import view_config 2from pyramid.config import Configurator 3from pyramid.response import FileResponse 4from paste.httpserver import serve 5 6@view_config(route_name='jpg') 7def test_page(request): 8 response = FileResponse( 9 '/home/chrism/groundhog1.jpg', 10 request=request, 11 content_type='image/jpeg' 12 ) 13 return response 14 15if __name__ == '__main__': 16 config = Configurator() 17 config.add_route('jpg', '/test.jpg') 18 config.scan('__main__') 19 serve(config.make_wsgi_app())
Basically, use a
pyramid.response.FileResponse as the response object and
return it. Note that the
content_type arguments are
request is not supplied, any
optimization supplied by your WSGI server will not be used when serving the
content_type is not supplied, it will be guessed using the
mimetypes module (which uses the file extension); if it cannot be guessed
application/octet-stream content type will be used.
Serving a Single File from the Root¶
If you need to serve a single file such as
/favicon.ico that must be served from the root, you cannot use a
static view to do it, as static views cannot serve files from the
root (a static view must have a nonempty prefix such as
work around this limitation, create views "by hand" that serve up the raw
file data. Below is an example of creating two views: one serves up a
/favicon.ico, the other serves up
At startup time, both files are read into memory from files on disk using plain Python. A Response object is created for each. This response is served by a view which hooks up the static file's URL.
1# this module = myapp.views 2 3import os 4 5from pyramid.response import Response 6from pyramid.view import view_config 7 8# _here = /app/location/myapp 9 10_here = os.path.dirname(__file__) 11 12# _icon = /app/location/myapp/static/favicon.ico 13 14_icon = open(os.path.join( 15 _here, 'static', 'favicon.ico')).read() 16_fi_response = Response(content_type='image/x-icon', 17 body=_icon) 18 19# _robots = /app/location/myapp/static/robots.txt 20 21_robots = open(os.path.join( 22 _here, 'static', 'robots.txt')).read() 23_robots_response = Response(content_type='text/plain', 24 body=_robots) 25 26@view_config(name='favicon.ico') 27def favicon_view(context, request): 28 return _fi_response 29 30@view_config(name='robots.txt') 31def robotstxt_view(context, request): 32 return _robots_response
Root-Relative Custom Static View (URL Dispatch Only)¶
pyramid.static.static_view helper class generates a Pyramid view
callable. This view callable can serve static assets from a directory. An
instance of this class is actually used by the
pyramid.config.Configurator.add_static_view() configuration method, so
its behavior is almost exactly the same once it's configured.
The following example will not work for applications that use
traversal, it will only work if you use URL dispatch
exclusively. The root-relative route we'll be registering will always be
matched before traversal takes place, subverting any views registered via
add_view (at least those without a
pyramid.static.static_view cannot be made root-relative when you
To serve files within a directory located on your filesystem at
/path/to/static/dir as the result of a "catchall" route hanging from the
root that exists at the end of your routing table, create an instance of the
pyramid.static.static_view class inside a
static.py file in your
application root as below:
from pyramid.static import static_view www = static_view('/path/to/static/dir', use_subpath=True)
For better cross-system flexibility, use an asset
specification as the argument to
instead of a physical absolute filesystem path, e.g.
Subsequently, you may wire the files that are served by this view up to be
/<filename> using a configuration method in your
application's startup code:
# .. every other add_route and/or add_handler declaration should come # before this one, as it will, by default, catch all requests config.add_route('catchall_static', '/*subpath', 'myapp.static.www')
The special name
*subpath above is used by the
pyramid.static.static_view view callable to signify the path of the
file relative to the directory you're serving.