ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 02.01.2026
Просмотров: 2705
Скачиваний: 0
|
13.3. ADVANCED: SERVING STATIC ASSETS USING A VIEW CALLABLE |
|
|
1 |
# .. every other add_route declaration should come |
2 |
# before this one, as it will, by default, catch all requests |
3 |
|
4 |
config.add_route(’catchall_static’, ’/*subpath’) |
5 |
config.add_view(’myapp.static.static_view’, route_name=’catchall_static’) |
|
|
The special name *subpath above is used by the static_view view callable to signify the path of the file relative to the directory you’re serving.
13.3.2 Registering A View Callable to Serve a “Static” Asset
You can register a simple view callable to serve a single static asset. To do so, do things “by hand”. First define the view callable.
1 |
import os |
2 |
from pyramid.response import FileResponse |
3 |
|
4 |
def favicon_view(request): |
5here = os.path.dirname(__file__)
6 icon = os.path.join(here, ’static’, ’favicon.ico’)
7return FileResponse(icon, request=request)
The above bit of code within favicon_view computes “here”, which is a path relative to the Python file in which the function is defined. It then creates a pyramid.response.FileResponse using the file path as the response’s path argument and the request as the response’s request argument. pyramid.response.FileResponse will serve the file as quickly as possible when it’s used this way. It makes sure to set the right content length and content_type too based on the file extension of the file you pass.
You might register such a view via configuration as a view callable that should be called as the result of a traversal:
1 config.add_view(’myapp.views.favicon_view’, name=’favicon.ico’)
Or you might register it to be the view callable for a particular route:
1
2
config.add_route(’favicon’, ’/favicon.ico’) config.add_view(’myapp.views.favicon_view’, route_name=’favicon’)
Because this is a simple view callable, it can be protected with a permission or can be configured to respond under different circumstances using view predicate arguments.
159
13. STATIC ASSETS
13.4 Overriding Assets
It can often be useful to override specific assets from “outside” a given Pyramid application. For example, you may wish to reuse an existing Pyramid application more or less unchanged. However, some specific template file owned by the application might have inappropriate HTML, or some static asset (such as a logo file or some CSS file) might not be appropriate. You could just fork the application entirely, but it’s often more convenient to just override the assets that are inappropriate and reuse the application “as is”. This is particularly true when you reuse some “core” application over and over again for some set of customers (such as a CMS application, or some bug tracking application), and you want to make arbitrary visual modifications to a particular application deployment without forking the underlying code.
To this |
end, |
Pyramid contains |
a |
feature that makes it possible to “override” one asset with |
one or |
more |
other assets. |
In |
support of this feature, a Configurator API exists named |
pyramid.config.Configurator.override_asset(). This API allows you to override the following kinds of assets defined in any Python package:
•Individual Chameleon templates.
•A directory containing multiple Chameleon templates.
•Individual static files served up by an instance of the pyramid.static.static_view helper class.
•A directory of static files served up by an instance of the pyramid.static.static_view helper class.
•Any other asset (or set of assets) addressed by code that uses the setuptools pkg_resources API.
13.4.1 The override_asset API
An individual call to override_asset() can override a single asset. For example:
1 config.override_asset(
2to_override=’some.package:templates/mytemplate.pt’,
3override_with=’another.package:othertemplates/anothertemplate.pt’)
The string value passed to both to_override and override_with sent to the override_asset API is called an asset specification. The colon separator in a specification separates the package name from the asset name. The colon and the following asset name are optional. If they are not specified, the override attempts to resolve every lookup into a package from the directory of another package. For example:
160
13.4. OVERRIDING ASSETS
1
2
config.override_asset(to_override=’some.package’, override_with=’another.package’)
Individual subdirectories within a package can also be overridden:
1
2
config.override_asset(to_override=’some.package:templates/’, override_with=’another.package:othertemplates/’)
If you wish to override a directory with another directory, you must make sure to attach the slash to the end of both the to_override specification and the override_with specification. If you fail to attach a slash to the end of a specification that points to a directory, you will get unexpected results.
You cannot override a directory specification with a file specification, and vice versa: a startup error will occur if you try. You cannot override an asset with itself: a startup error will occur if you try.
Only individual package assets may be overridden. Overrides will not traverse through subpackages within an overridden package. This means that if you want to override assets for both some.package:templates, and some.package.views:templates, you will need to register two overrides.
The package name in a specification may start with a dot, meaning that the package is relative to the package in which the configuration construction file resides (or the package argument to the Configurator class construction). For example:
1
2
config.override_asset(to_override=’.subpackage:templates/’, override_with=’another.package:templates/’)
Multiple calls to override_asset which name a shared to_override but a different override_with specification can be “stacked” to form a search path. The first asset that exists in the search path will be used; if no asset exists in the override path, the original asset is used.
Asset |
overrides |
can actually |
override |
assets other than templates and static files. |
Any |
software |
which uses |
the |
pkg_resources.get_resource_filename(), |
pkg_resources.get_resource_stream() or pkg_resources.get_resource_string()
APIs will obtain an overridden file when an override is used.
161
13. STATIC ASSETS
162
CHAPTER
FOURTEEN
REQUEST AND RESPONSE OBJECTS
latex-note.png
This chapter is adapted from a portion of the WebOb documentation, originally written by Ian Bicking.
Pyramid uses the WebOb package as a basis for its request and response object implementations. The request object that is passed to a Pyramid view is an instance of the pyramid.request.Request class, which is a subclass of webob.Request. The response returned from a Pyramid view renderer is an instance of the pyramid.response.Response class, which is a subclass of the webob.Response class. Users can also return an instance of pyramid.response.Response directly from a view as necessary.
WebOb is a project separate from Pyramid with a separate set of authors and a fully separate set of documentation. Pyramid adds some functionality to the standard WebOb request, which is documented in the pyramid.request API documentation.
WebOb provides objects for HTTP requests and responses. Specifically it does this by wrapping the WSGI request environment and response status, header list, and app_iter (body) values.
WebOb request and response objects provide many conveniences for parsing WSGI requests and forming WSGI responses. WebOb is a nice way to represent “raw” WSGI requests and responses; however, we won’t cover that use case in this document, as users of Pyramid don’t typically need to use the WSGIrelated features of WebOb directly. The reference documentation shows many examples of creating requests and using response objects in this manner, however.
163