- •Front Matter
- •Copyright, Trademarks, and Attributions
- •Attributions
- •Print Production
- •Contacting The Publisher
- •HTML Version and Source Code
- •Typographical Conventions
- •Author Introduction
- •Audience
- •Book Content
- •The Genesis of repoze.bfg
- •The Genesis of Pyramid
- •Thanks
- •Pyramid Introduction
- •What Makes Pyramid Unique
- •URL generation
- •Debug Toolbar
- •Debugging settings
- •Class-based and function-based views
- •Extensible templating
- •Rendered views can return dictionaries
- •Event system
- •Built-in internationalization
- •HTTP caching
- •Sessions
- •Speed
- •Exception views
- •No singletons
- •View predicates and many views per route
- •Transaction management
- •Flexible authentication and authorization
- •Traversal
- •Tweens
- •View response adapters
- •Testing
- •Support
- •Documentation
- •What Is The Pylons Project?
- •Pyramid and Other Web Frameworks
- •Installing Pyramid
- •Before You Install
- •Installing Pyramid on a UNIX System
- •Installing the virtualenv Package
- •Creating the Virtual Python Environment
- •Installing Pyramid Into the Virtual Python Environment
- •Installing Pyramid on a Windows System
- •What Gets Installed
- •Application Configuration
- •Summary
- •Creating Your First Pyramid Application
- •Hello World
- •Imports
- •View Callable Declarations
- •WSGI Application Creation
- •WSGI Application Serving
- •Conclusion
- •References
- •Creating a Pyramid Project
- •Scaffolds Included with Pyramid
- •Creating the Project
- •Installing your Newly Created Project for Development
- •Running The Tests For Your Application
- •Running The Project Application
- •Reloading Code
- •Viewing the Application
- •The Debug Toolbar
- •The Project Structure
- •The MyProject Project
- •development.ini
- •production.ini
- •MANIFEST.in
- •setup.py
- •setup.cfg
- •The myproject Package
- •__init__.py
- •views.py
- •static
- •templates/mytemplate.pt
- •tests.py
- •Modifying Package Structure
- •Using the Interactive Shell
- •What Is This pserve Thing
- •Using an Alternate WSGI Server
- •Startup
- •The Startup Process
- •Deployment Settings
- •Request Processing
- •URL Dispatch
- •High-Level Operational Overview
- •Route Pattern Syntax
- •Route Declaration Ordering
- •Route Matching
- •The Matchdict
- •The Matched Route
- •Routing Examples
- •Example 1
- •Example 2
- •Example 3
- •Matching the Root URL
- •Generating Route URLs
- •Static Routes
- •Debugging Route Matching
- •Using a Route Prefix to Compose Applications
- •Custom Route Predicates
- •Route Factories
- •Using Pyramid Security With URL Dispatch
- •Route View Callable Registration and Lookup Details
- •References
- •Views
- •View Callables
- •View Callable Responses
- •Using Special Exceptions In View Callables
- •HTTP Exceptions
- •How Pyramid Uses HTTP Exceptions
- •Custom Exception Views
- •Using a View Callable to Do an HTTP Redirect
- •Handling Form Submissions in View Callables (Unicode and Character Set Issues)
- •Alternate View Callable Argument/Calling Conventions
- •Renderers
- •Writing View Callables Which Use a Renderer
- •Built-In Renderers
- •string: String Renderer
- •json: JSON Renderer
- •JSONP Renderer
- •*.pt or *.txt: Chameleon Template Renderers
- •*.mak or *.mako: Mako Template Renderer
- •Varying Attributes of Rendered Responses
- •Deprecated Mechanism to Vary Attributes of Rendered Responses
- •Adding and Changing Renderers
- •Adding a New Renderer
- •Changing an Existing Renderer
- •Overriding A Renderer At Runtime
- •Templates
- •Using Templates Directly
- •System Values Used During Rendering
- •Chameleon ZPT Templates
- •A Sample ZPT Template
- •Using ZPT Macros in Pyramid
- •Templating with Chameleon Text Templates
- •Side Effects of Rendering a Chameleon Template
- •Debugging Templates
- •Chameleon Template Internationalization
- •Templating With Mako Templates
- •A Sample Mako Template
- •Automatically Reloading Templates
- •Available Add-On Template System Bindings
- •View Configuration
- •Mapping a Resource or URL Pattern to a View Callable
- •@view_defaults Class Decorator
- •NotFound Errors
- •Debugging View Configuration
- •Static Assets
- •Serving Static Assets
- •Generating Static Asset URLs
- •Advanced: Serving Static Assets Using a View Callable
- •Root-Relative Custom Static View (URL Dispatch Only)
- •Overriding Assets
- •The override_asset API
- •Request and Response Objects
- •Request
- •Special Attributes Added to the Request by Pyramid
- •URLs
- •Methods
- •Unicode
- •Multidict
- •Dealing With A JSON-Encoded Request Body
- •Cleaning Up After a Request
- •More Details
- •Response
- •Headers
- •Instantiating the Response
- •Exception Responses
- •More Details
- •Sessions
- •Using The Default Session Factory
- •Using a Session Object
- •Using Alternate Session Factories
- •Creating Your Own Session Factory
- •Flash Messages
- •Using the session.flash Method
- •Using the session.pop_flash Method
- •Using the session.peek_flash Method
- •Preventing Cross-Site Request Forgery Attacks
- •Using the session.get_csrf_token Method
- •Using the session.new_csrf_token Method
- •Using Events
- •An Example
- •Reloading Templates
- •Reloading Assets
- •Debugging Authorization
- •Debugging Not Found Errors
- •Debugging Route Matching
- •Preventing HTTP Caching
- •Debugging All
- •Reloading All
- •Default Locale Name
- •Including Packages
- •pyramid.includes vs. pyramid.config.Configurator.include()
- •Mako Template Render Settings
- •Mako Directories
- •Mako Module Directory
- •Mako Input Encoding
- •Mako Error Handler
- •Mako Default Filters
- •Mako Import
- •Mako Preprocessor
- •Examples
- •Understanding the Distinction Between reload_templates and reload_assets
- •Adding A Custom Setting
- •Logging
- •Sending Logging Messages
- •Filtering log messages
- •Logging Exceptions
- •PasteDeploy Configuration Files
- •PasteDeploy
- •Entry Points and PasteDeploy .ini Files
- •[DEFAULTS] Section of a PasteDeploy .ini File
- •Command-Line Pyramid
- •Displaying Matching Views for a Given URL
- •The Interactive Shell
- •Extending the Shell
- •IPython or bpython
- •Displaying All Application Routes
- •Invoking a Request
- •Writing a Script
- •Changing the Request
- •Cleanup
- •Setting Up Logging
- •Making Your Script into a Console Script
- •Internationalization and Localization
- •Creating a Translation String
- •Using The TranslationString Class
- •Using the TranslationStringFactory Class
- •Working With gettext Translation Files
- •Installing Babel and Lingua
- •Extracting Messages from Code and Templates
- •Initializing a Message Catalog File
- •Updating a Catalog File
- •Compiling a Message Catalog File
- •Using a Localizer
- •Performing a Translation
- •Performing a Pluralization
- •Obtaining the Locale Name for a Request
- •Performing Date Formatting and Currency Formatting
- •Chameleon Template Support for Translation Strings
- •Mako Pyramid I18N Support
- •Localization-Related Deployment Settings
- •Activating Translation
- •Adding a Translation Directory
- •Setting the Locale
- •Locale Negotiators
- •The Default Locale Negotiator
- •Using a Custom Locale Negotiator
- •Virtual Hosting
- •Virtual Root Support
- •Further Documentation and Examples
- •Test Set Up and Tear Down
- •What?
- •Using the Configurator and pyramid.testing APIs in Unit Tests
- •Creating Integration Tests
- •Creating Functional Tests
- •Resources
- •Location-Aware Resources
- •Generating The URL Of A Resource
- •Overriding Resource URL Generation
- •Generating the Path To a Resource
- •Finding a Resource by Path
- •Obtaining the Lineage of a Resource
- •Determining if a Resource is In The Lineage of Another Resource
- •Finding the Root Resource
- •Resources Which Implement Interfaces
- •Finding a Resource With a Class or Interface in Lineage
- •Pyramid API Functions That Act Against Resources
- •Much Ado About Traversal
- •URL Dispatch
- •Historical Refresher
- •Traversal (aka Resource Location)
- •View Lookup
- •Use Cases
- •Traversal
- •Traversal Details
- •The Resource Tree
- •The Traversal Algorithm
- •A Description of The Traversal Algorithm
- •Traversal Algorithm Examples
- •References
- •Security
- •Enabling an Authorization Policy
- •Enabling an Authorization Policy Imperatively
- •Protecting Views with Permissions
- •Setting a Default Permission
- •Assigning ACLs to your Resource Objects
- •Elements of an ACL
- •Special Principal Names
- •Special Permissions
- •Special ACEs
- •ACL Inheritance and Location-Awareness
- •Changing the Forbidden View
- •Debugging View Authorization Failures
- •Debugging Imperative Authorization Failures
- •Creating Your Own Authentication Policy
- •Creating Your Own Authorization Policy
- •Combining Traversal and URL Dispatch
- •A Review of Non-Hybrid Applications
- •URL Dispatch Only
- •Traversal Only
- •Hybrid Applications
- •The Root Object for a Route Match
- •Using *traverse In a Route Pattern
- •Using *subpath in a Route Pattern
- •Corner Cases
- •Registering a Default View for a Route That Has a view Attribute
- •Using Hooks
- •Changing the Not Found View
- •Changing the Forbidden View
- •Changing the Request Factory
- •Using The Before Render Event
- •Adding Renderer Globals (Deprecated)
- •Using Response Callbacks
- •Using Finished Callbacks
- •Changing the Traverser
- •Changing How pyramid.request.Request.resource_url() Generates a URL
- •Changing How Pyramid Treats View Responses
- •Using a View Mapper
- •Creating a Tween Factory
- •Registering an Implicit Tween Factory
- •Suggesting Implicit Tween Ordering
- •Explicit Tween Ordering
- •Displaying Tween Ordering
- •Pyramid Configuration Introspection
- •Using the Introspector
- •Introspectable Objects
- •Pyramid Introspection Categories
- •Introspection in the Toolbar
- •Disabling Introspection
- •Rules for Building An Extensible Application
- •Fundamental Plugpoints
- •Extending an Existing Application
- •Extending the Application
- •Overriding Views
- •Overriding Routes
- •Overriding Assets
- •Advanced Configuration
- •Two-Phase Configuration
- •Using config.action in a Directive
- •Adding Configuration Introspection
- •Introspectable Relationships
- •Thread Locals
- •Why and How Pyramid Uses Thread Local Variables
- •Using the Zope Component Architecture in Pyramid
- •Using the ZCA Global API in a Pyramid Application
- •Disusing the Global ZCA API
- •Enabling the ZCA Global API by Using hook_zca
- •Enabling the ZCA Global API by Using The ZCA Global Registry
- •Background
- •Design
- •Overall
- •Models
- •Views
- •Security
- •Summary
- •Installation
- •Preparation
- •Make a Project
- •Run the Tests
- •Expose Test Coverage Information
- •Start the Application
- •Visit the Application in a Browser
- •Decisions the zodb Scaffold Has Made For You
- •Basic Layout
- •Resources and Models with models.py
- •Views With views.py
- •Defining the Domain Model
- •Delete the Database
- •Edit models.py
- •Look at the Result of Our Edits to models.py
- •View the Application in a Browser
- •Defining Views
- •Declaring Dependencies in Our setup.py File
- •Adding View Functions
- •Viewing the Result of all Our Edits to views.py
- •Adding Templates
- •Viewing the Application in a Browser
- •Adding Authorization
- •Add Authentication and Authorization Policies
- •Add security.py
- •Give Our Root Resource an ACL
- •Add Login and Logout Views
- •Change Existing Views
- •Add permission Declarations to our view_config Decorators
- •Add the login.pt Template
- •Change view.pt and edit.pt
- •See Our Changes To views.py and our Templates
- •View the Application in a Browser
- •Adding Tests
- •Test the Models
- •Test the Views
- •Functional tests
- •View the results of all our edits to tests.py
- •Run the Tests
- •Distributing Your Application
- •SQLAlchemy + URL Dispatch Wiki Tutorial
- •Background
- •Design
- •Overall
- •Models
- •Views
- •Security
- •Summary
- •Installation
- •Preparation
- •Making a Project
- •Running the Tests
- •Exposing Test Coverage Information
- •Initializing the Database
- •Starting the Application
- •Decisions the alchemy Scaffold Has Made For You
- •Basic Layout
- •View Declarations via views.py
- •Content Models with models.py
- •Making Edits to models.py
- •Changing scripts/initializedb.py
- •Reinitializing the Database
- •Viewing the Application in a Browser
- •Defining Views
- •Declaring Dependencies in Our setup.py File
- •Running setup.py develop
- •Changing the views.py File
- •Adding Templates
- •Adding Routes to __init__.py
- •Viewing the Application in a Browser
- •Adding Authorization
- •Adding A Root Factory
- •Add an Authorization Policy and an Authentication Policy
- •Adding an authentication policy callback
- •Adding Login and Logout Views
- •Changing Existing Views
- •Adding the login.pt Template
- •Seeing Our Changes To views.py and our Templates
- •Viewing the Application in a Browser
- •Adding Tests
- •Testing the Models
- •Testing the Views
- •Functional tests
- •Viewing the results of all our edits to tests.py
- •Running the Tests
- •Distributing Your Application
- •Converting a repoze.bfg Application to Pyramid
- •Running a Pyramid Application under mod_wsgi
- •pyramid.authorization
- •pyramid.authentication
- •Authentication Policies
- •Helper Classes
- •pyramid.chameleon_text
- •pyramid.chameleon_zpt
- •pyramid.config
- •pyramid.events
- •Functions
- •Event Types
- •pyramid.exceptions
- •pyramid.httpexceptions
- •HTTP Exceptions
- •pyramid.i18n
- •pyramid.interfaces
- •Event-Related Interfaces
- •Other Interfaces
- •pyramid.location
- •pyramid.paster
- •pyramid.registry
- •pyramid.renderers
- •pyramid.request
- •pyramid.response
- •Functions
- •pyramid.scripting
- •pyramid.security
- •Authentication API Functions
- •Authorization API Functions
- •Constants
- •Return Values
- •pyramid.settings
- •pyramid.testing
- •pyramid.threadlocal
- •pyramid.traversal
- •pyramid.url
- •pyramid.view
- •pyramid.wsgi
- •Glossary
1. PYRAMID INTRODUCTION
Documentation Pyramid’s minimalism means that it is easier for us to maintain complete and up-to-date documentation. It is our goal that no aspect of Pyramid is undocumented.
Speed Pyramid is designed to provide noticeably fast execution for common tasks such as templating and simple response generation. Although “hardware is cheap”, the limits of this approach become painfully evident when one finds him or herself responsible for managing a great many machines.
Reliability Pyramid is developed conservatively and tested exhaustively. Where Pyramid source code is concerned, our motto is: “If it ain’t tested, it’s broke”.
Openness As with Python, the Pyramid software is distributed under a permissive open source license.
1.1 What Makes Pyramid Unique
Understandably, people don’t usually want to hear about squishy engineering principles, they want to hear about concrete stuff that solves their problems. With that in mind, what would make someone want to use Pyramid instead of one of the many other web frameworks available today? What makes Pyramid unique?
This is a hard question to answer, because there are lots of excellent choices, and it’s actually quite hard to make a wrong choice, particularly in the Python web framework market. But one reasonable answer is this: you can write very small applications in Pyramid without needing to know a lot. “What?”, you say, “that can’t possibly be a unique feature, lots of other web frameworks let you do that!” Well, you’re right. But unlike many other systems, you can also write very large applications in Pyramid if you learn a little more about it. Pyramid will allow you to become productive quickly, and will grow with you; it won’t hold you back when your application is small and it won’t get in your way when your application becomes large. “Well that’s fine,” you say, “lots of other frameworks let me write large apps too.” Absolutely. But other Python web frameworks don’t seamlessly let you do both. They seem to fall into two nonoverlapping categories: frameworks for “small apps” and frameworks for “big apps”. The “small app” frameworks typically sacrifice “big app” features, and vice versa.
We don’t think it’s a universally reasonable suggestion to write “small apps” in a “small framework” and “big apps” in a “big framework”. You can’t really know to what size every application will eventually grow. We don’t really want to have to rewrite a previously small application in another framework when it gets “too big”. We believe the current binary distinction between frameworks for small and large applications is just false; a well-designed framework should be able to be good at both. Pyramid strives to be that kind of framework.
To this end, Pyramid provides a set of features, that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some combination of these features; Pyramid of course actually stole many of them from those other frameworks. But Pyramid is the only one that has all of them in one place, documented appropriately, and useful a la carte without necessarily paying for the entire banquet. These are detailed below.
4
1.1. WHAT MAKES PYRAMID UNIQUE
1.1.1 Single-file applications
You can write a Pyramid application that lives entirely in one Python file, not unlike existing Python microframeworks. This is beneficial for one-off prototyping, bug reproduction, and very small applications. These applications are easy to understand because all the information about the application lives in a single place, and you can deploy them without needing to understand much about Python distributions and packaging. Pyramid isn’t really marketed as a microframework, but it allows you to do almost everything that frameworks that are marketed as micro offer in very similar ways.
from wsgiref.simple_server import make_server from pyramid.config import Configurator
from pyramid.response import Response
def hello_world(request):
return Response(’Hello %(name)s!’ % request.matchdict)
if __name__ == ’__main__’: config = Configurator()
config.add_route(’hello’, ’/hello/{name}’) config.add_view(hello_world, route_name=’hello’) app = config.make_wsgi_app()
server = make_server(’0.0.0.0’, 8080, app) server.serve_forever()
See also Creating Your First Pyramid Application.
1.1.2 Decorator-based configuration
If you like the idea of framework configuration statements living next to the code it configures, so you don’t have to constantly switch between files to refer to framework configuration when adding new code, you can use Pyramid decorators to localize the configuration. For example:
from pyramid.view import view_config from pyramid.response import Response
@view_config(route_name=’fred’) def fred_view(request):
return Response(’fred’)
However, unlike some other systems, using decorators for Pyramid configuration does not make your application difficult to extend, test or reuse. The view_config decorator, for example, does not actually
5
1. PYRAMID INTRODUCTION
change the input or output of the function it decorates, so testing it is a “WYSIWYG” operation; you don’t need to understand the framework to test your own code, you just behave as if the decorator is not there. You can also instruct Pyramid to ignore some decorators, or use completely imperative configuration instead of decorators to add views. Pyramid decorators are inert instead of eager: you detect and activate them with a scan.
Example: Adding View Configuration Using the @view_config Decorator.
1.1.3 URL generation
Pyramid is capable of generating URLs for resources, routes, and static assets. Its URL generation APIs are easy to use and flexible. If you use Pyramid’s various APIs for generating URLs, you can change your configuration around arbitrarily without fear of breaking a link on one of your web pages.
Example: Generating Route URLs.
1.1.4 Static file serving
Pyramid is perfectly willing to serve static files itself. It won’t make you use some external web server to do that. You can even serve more than one set of static files in a single Pyramid web application (e.g. /static and /static2). You can also, optionally, place your files on an external web server and ask Pyramid to help you generate URLs to those files, so you can use Pyramid’s internal fileserving while doing development, and a faster static file server in production without changing any code.
Example: Serving Static Assets.
1.1.5 Debug Toolbar
Pyramid’s debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and allows you access to framework data such as the routes configured, the last renderings performed, the current set of packages installed, SQLAlchemy queries run, logging data, and various other facts. When an exception occurs, you can use its interactive debugger to poke around right in your browser to try to determine the cause of the exception. It’s handy.
Example: The Debug Toolbar.
6
1.1. WHAT MAKES PYRAMID UNIQUE
1.1.6 Debugging settings
Pyramid has debugging settings that allow you to print Pyramid runtime information to the console when things aren’t behaving as you’re expecting. For example, you can turn on “debug_notfound”, which prints an informative message to the console every time a URL does not match any view. You can turn on “debug_authorization”, which lets you know why a view execution was allowed or denied by printing a message to the console. These features are useful for those WTF moments.
There are also a number of commands that you can invoke within a Pyramid environment that allow you to introspect the configuration of your system: proutes shows all configured routes for an application in the order they’ll be evaluated for matching; pviews shows all configured views for any given URL. These are also WTF-crushers in some circumstances.
Examples: Debugging View Authorization Failures and Command-Line Pyramid.
1.1.7 Add-ons
Pyramid has an extensive set of add-ons held to the same quality standards as the Pyramid core itself. Addons are packages which provide functionality that the Pyramid core doesn’t. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc.
Examples: http://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation
1.1.8 Class-based and function-based views
Pyramid has a structured, unified concept of a view callable. View callables can be functions, methods of classes, or even instances. When you add a new view callable, you can choose to make it a function or a method of a class; in either case, Pyramid treats it largely the same way. You can change your mind later, and move code between methods of classes and functions. A collection of similar view callables can be attached to a single class as methods, if that floats your boat, and they can share initialization code as necessary. All kinds of views are easy to understand and use and operate similarly. There is no phony distinction between them; they can be used for the same purposes.
Here’s a view callable defined as a function:
7
1. PYRAMID INTRODUCTION
1
2
3
4
5
6
from pyramid.response import Response from pyramid.view import view_config
@view_config(route_name=’aview’) def aview(request):
return Response(’one’)
Here’s a few views defined as methods of a class instead:
1 |
from pyramid.response import Response |
2 |
from pyramid.view import view_config |
3 |
|
4 |
class AView(object): |
5 |
def __init__(self, request): |
6self.request = request
7
8 @view_config(route_name=’view_one’)
9def view_one(self):
10 return Response(’one’)
11
12@view_config(route_name=’view_two’)
13def view_two(self):
14return Response(’two’)
See also @view_config Placement.
1.1.9 Asset specifications
Asset specifications are strings that contain both a Python package name and a file or directory name, e.g. MyPackage:static/index.html. Use of these specifications is omnipresent in Pyramid. An asset specification can refer to a template, a translation directory, or any other package-bound static resource. This makes a system built on Pyramid extensible, because you don’t have to rely on globals (“the static directory”) or lookup schemes (“the ordered set of template directories”) to address your files. You can move files around as necessary, and include other packages that may not share your system’s templates or static files without encountering conflicts.
Because asset specifications are used heavily in Pyramid, we’ve also provided a way to allow users to override assets. Say you love a system that someone else has created with Pyramid but you just need to change “that one template” to make it all better. No need to fork the application. Just override the asset specification for that template with your own inside a wrapper, and you’re good to go.
Examples: Understanding Asset Specifications and Overriding Assets.
8