Steve Piercy
2016-11-29 968bebc0d1cbb6d85eb446b41c0f4560383c3022
commit | author | age
e0887e 1 .. index::
CM 2    single: Agendaless Consulting
3    single: Pylons
4    single: Django
5    single: Zope
9ec2d6 6    single: frameworks vs. libraries
CM 7    single: framework
e0887e 8
fd5ae9 9 :app:`Pyramid` Introduction
ca00fb 10 ===========================
9e3bdb 11
b0d207 12 :app:`Pyramid` is a general, open source, Python web application development
7a505d 13 *framework*. Its primary goal is to make it easier for a Python developer to
CM 14 create web applications.
9e3bdb 15
9ec2d6 16 .. sidebar:: Frameworks vs. Libraries
CM 17
ca00fb 18    A *framework* differs from a *library* in one very important way: library
SP 19    code is always *called* by code that you write, while a framework always
20    *calls* code that you write.  Using a set of libraries to create an
21    application is usually easier than using a framework initially, because you
22    can choose to cede control to library code you have not authored very
23    selectively. But when you use a framework, you are required to cede a
24    greater portion of control to code you have not authored: code that resides
25    in the framework itself.  You needn't use a framework at all to create a web
26    application using Python.  A rich set of libraries already exists for the
27    platform.  In practice, however, using a framework to create an application
28    is often more practical than rolling your own via a set of libraries if the
29    framework provides a set of facilities that fits your application
30    requirements.
0bc787 31
b20299 32 Pyramid attempts to follow these design and engineering principles:
9e3bdb 33
878328 34 Simplicity
7a505d 35   :app:`Pyramid` takes a *"pay only for what you eat"* approach.  You can get
ca00fb 36   results even if you have only a partial understanding of :app:`Pyramid`.  It
SP 37   doesn't force you to use any particular technology to produce an application,
38   and we try to keep the core set of concepts that you need to understand to a
39   minimum.
9e3bdb 40
878328 41 Minimalism
ca00fb 42   :app:`Pyramid` tries to solve only the fundamental problems of creating a web
SP 43   application: the mapping of URLs to code, templating, security, and serving
44   static assets. We consider these to be the core activities that are common to
45   nearly all web applications.
9e3bdb 46
878328 47 Documentation
ca00fb 48   Pyramid's minimalism means that it is easier for us to maintain complete and
SP 49   up-to-date documentation. It is our goal that no aspect of Pyramid is
50   undocumented.
9e3bdb 51
878328 52 Speed
b0d207 53   :app:`Pyramid` is designed to provide noticeably fast execution for common
01c184 54   tasks such as templating and simple response generation.
9e3bdb 55
b0d207 56 Reliability
CM 57   :app:`Pyramid` is developed conservatively and tested exhaustively. Where
ca00fb 58   Pyramid source code is concerned, our motto is: "If it ain't tested, it's
bb93cb 59   broke".
878328 60
9ec2d6 61 Openness
ca00fb 62   As with Python, the Pyramid software is distributed under a `permissive open
SP 63   source license <http://repoze.org/license.html>`_.
3ea7c7 64
d8fc16 65 .. _what_makes_pyramid_unique:
CM 66
d59239 67 What makes Pyramid unique
bb93cb 68 -------------------------
CM 69
70 Understandably, people don't usually want to hear about squishy engineering
ca00fb 71 principles; they want to hear about concrete stuff that solves their problems. 
SP 72 With that in mind, what would make someone want to use Pyramid instead of one
73 of the many other web frameworks available today?  What makes Pyramid unique?
bb93cb 74
ca00fb 75 This is a hard question to answer because there are lots of excellent choices,
SP 76 and it's actually quite hard to make a wrong choice, particularly in the Python
77 web framework market.  But one reasonable answer is this: you can write very
78 small applications in Pyramid without needing to know a lot. "What?" you say.
79 "That can't possibly be a unique feature. Lots of other web frameworks let you
80 do that!"  Well, you're right.  But unlike many other systems, you can also
81 write very large applications in Pyramid if you learn a little more about it. 
82 Pyramid will allow you to become productive quickly, and will grow with you. It
83 won't hold you back when your application is small, and it won't get in your
84 way when your application becomes large.  "Well that's fine," you say. "Lots of
85 other frameworks let me write large apps, too."  Absolutely.  But other Python
86 web frameworks don't seamlessly let you do both.  They seem to fall into two
87 non-overlapping categories: frameworks for "small apps" and frameworks for "big
88 apps".  The "small app" frameworks typically sacrifice "big app" features, and
89 vice versa.
bb93cb 90
CM 91 We don't think it's a universally reasonable suggestion to write "small apps"
92 in a "small framework" and "big apps" in a "big framework".  You can't really
ca00fb 93 know to what size every application will eventually grow.  We don't really want
SP 94 to have to rewrite a previously small application in another framework when it
95 gets "too big".  We believe the current binary distinction between frameworks
96 for small and large applications is just false. A well-designed framework
97 should be able to be good at both.  Pyramid strives to be that kind of
98 framework.
bb93cb 99
ca00fb 100 To this end, Pyramid provides a set of features that combined are unique
bb93cb 101 amongst Python web frameworks.  Lots of other frameworks contain some
d59239 102 combination of these features. Pyramid of course actually stole many of them
ca00fb 103 from those other frameworks.  But Pyramid is the only one that has all of them
SP 104 in one place, documented appropriately, and useful *à la carte* without
bb93cb 105 necessarily paying for the entire banquet.  These are detailed below.
CM 106
d3aae8 107 Single-file applications
bb93cb 108 ~~~~~~~~~~~~~~~~~~~~~~~~
CM 109
ca00fb 110 You can write a Pyramid application that lives entirely in one Python file, not
SP 111 unlike existing Python microframeworks.  This is beneficial for one-off
112 prototyping, bug reproduction, and very small applications.  These applications
113 are easy to understand because all the information about the application lives
114 in a single place, and you can deploy them without needing to understand much
115 about Python distributions and packaging.  Pyramid isn't really marketed as a
116 microframework, but it allows you to do almost everything that frameworks that
117 are marketed as "micro" offer in very similar ways.
bb93cb 118
d3aae8 119 .. literalinclude:: helloworld.py
bb93cb 120
2033ee 121 .. seealso::
SP 122
123     See also :ref:`firstapp_chapter`.
d3aae8 124
CM 125 Decorator-based configuration
bb93cb 126 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CM 127
128 If you like the idea of framework configuration statements living next to the
129 code it configures, so you don't have to constantly switch between files to
130 refer to framework configuration when adding new code, you can use Pyramid
bdebfb 131 decorators to localize the configuration.  For example:
CM 132
133 .. code-block:: python
134
135    from pyramid.view import view_config
136    from pyramid.response import Response
bb93cb 137
CM 138    @view_config(route_name='fred')
139    def fred_view(request):
140        return Response('fred')
141
ca00fb 142 However, unlike some other systems, using decorators for Pyramid configuration
SP 143 does not make your application difficult to extend, test, or reuse.  The
144 :class:`~pyramid.view.view_config` decorator, for example, does not actually
145 *change* the input or output of the function it decorates, so testing it is a
146 "WYSIWYG" operation. You don't need to understand the framework to test your
147 own code. You just behave as if the decorator is not there.  You can also
148 instruct Pyramid to ignore some decorators, or use completely imperative
149 configuration instead of decorators to add views. Pyramid decorators are inert
150 instead of eager. You detect and activate them with a :term:`scan`.
bb93cb 151
CM 152 Example: :ref:`mapping_views_using_a_decorator_section`.
153
d3aae8 154 URL generation
bb93cb 155 ~~~~~~~~~~~~~~
CM 156
ca00fb 157 Pyramid is capable of generating URLs for resources, routes, and static assets.
SP 158 Its URL generation APIs are easy to use and flexible.  If you use Pyramid's
159 various APIs for generating URLs, you can change your configuration around
160 arbitrarily without fear of breaking a link on one of your web pages.
bb93cb 161
CM 162 Example: :ref:`generating_route_urls`.
163
164 Static file serving
165 ~~~~~~~~~~~~~~~~~~~
166
167 Pyramid is perfectly willing to serve static files itself.  It won't make you
ca00fb 168 use some external web server to do that.  You can even serve more than one set
SP 169 of static files in a single Pyramid web application (e.g., ``/static`` and
170 ``/static2``).  You can optionally place your files on an external web server
171 and ask Pyramid to help you generate URLs to those files. This let's you use
172 Pyramid's internal file serving while doing development, and a faster static
173 file server in production, without changing any code.
bb93cb 174
CM 175 Example: :ref:`static_assets_section`.
176
d59239 177 Fully interactive development
daefb5 178 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
KOP 179
d84407 180 When developing a Pyramid application, several interactive features are
4bc489 181 available. Pyramid can automatically utilize changed templates when rendering
d59239 182 pages and automatically restart the application to incorporate changed Python
4bc489 183 code. Plain old ``print()`` calls used for debugging can display to a console.
bb93cb 184
CM 185 Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to
186 render a project.  This toolbar overlays your application in the browser, and
d59239 187 allows you access to framework data, such as the routes configured, the last
ca00fb 188 renderings performed, the current set of packages installed, SQLAlchemy queries
SP 189 run, logging data, and various other facts.  When an exception occurs, you can
190 use its interactive debugger to poke around right in your browser to try to
191 determine the cause of the exception.  It's handy.
bb93cb 192
CM 193 Example: :ref:`debug_toolbar`.
194
195 Debugging settings
196 ~~~~~~~~~~~~~~~~~~
197
198 Pyramid has debugging settings that allow you to print Pyramid runtime
ca00fb 199 information to the console when things aren't behaving as you're expecting. For
SP 200 example, you can turn on ``debug_notfound``, which prints an informative
201 message to the console every time a URL does not match any view.  You can turn
202 on ``debug_authorization``, which lets you know why a view execution was
bb93cb 203 allowed or denied by printing a message to the console.  These features are
CM 204 useful for those WTF moments.
205
cfb2b5 206 There are also a number of commands that you can invoke within a Pyramid
d59239 207 environment that allow you to introspect the configuration of your system.
ca00fb 208 ``proutes`` shows all configured routes for an application in the order they'll
SP 209 be evaluated for matching. ``pviews`` shows all configured views for any given
210 URL.  These are also WTF-crushers in some circumstances.
bb93cb 211
ab7b24 212 Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`.
bb93cb 213
214125 214 Add-ons
ca00fb 215 ~~~~~~~
214125 216
CM 217 Pyramid has an extensive set of add-ons held to the same quality standards as
ca00fb 218 the Pyramid core itself.  Add-ons are packages which provide functionality that
SP 219 the Pyramid core doesn't.  Add-on packages already exist which let you easily
220 send email, let you use the Jinja2 templating system, let you use XML-RPC or
221 JSON-RPC, let you integrate with jQuery Mobile, etc.
214125 222
d59239 223 Examples:
c6729d 224 https://trypyramid.com/resources-extending-pyramid.html
214125 225
d3aae8 226 Class-based and function-based views
bb93cb 227 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CM 228
ca00fb 229 Pyramid has a structured, unified concept of a :term:`view callable`. View
SP 230 callables can be functions, methods of classes, or even instances.  When you
231 add a new view callable, you can choose to make it a function or a method of a
232 class. In either case Pyramid treats it largely the same way.  You can change
233 your mind later and move code between methods of classes and functions.  A
234 collection of similar view callables can be attached to a single class as
235 methods, if that floats your boat, and they can share initialization code as
236 necessary.  All kinds of views are easy to understand and use, and operate
237 similarly.  There is no phony distinction between them. They can be used for
238 the same purposes.
bb93cb 239
214125 240 Here's a view callable defined as a function:
CM 241
242 .. code-block:: python
243    :linenos:
244
245    from pyramid.response import Response
246    from pyramid.view import view_config
247
248    @view_config(route_name='aview')
249    def aview(request):
250        return Response('one')
251
252 Here's a few views defined as methods of a class instead:
253
254 .. code-block:: python
255    :linenos:
256
257    from pyramid.response import Response
258    from pyramid.view import view_config
259
260    class AView(object):
261        def __init__(self, request):
262            self.request = request
263
264        @view_config(route_name='view_one')
e73a54 265        def view_one(self):
214125 266            return Response('one')
CM 267
268        @view_config(route_name='view_two')
e73a54 269        def view_two(self):
214125 270            return Response('two')
CM 271
2033ee 272 .. seealso::
SP 273
274     See also :ref:`view_config_placement`.
bb93cb 275
82dcba 276 .. _intro_asset_specs:
CM 277
278 Asset specifications
279 ~~~~~~~~~~~~~~~~~~~~
280
ca00fb 281 Asset specifications are strings that contain both a Python package name and a
SP 282 file or directory name, e.g., ``MyPackage:static/index.html``.  Use of these
283 specifications is omnipresent in Pyramid.  An asset specification can refer to
284 a template, a translation directory, or any other package-bound static
d59239 285 resource.  This makes a system built on Pyramid extensible because you don't
82dcba 286 have to rely on globals ("*the* static directory") or lookup schemes ("*the*
CM 287 ordered set of template directories") to address your files.  You can move
288 files around as necessary, and include other packages that may not share your
289 system's templates or static files without encountering conflicts.
290
ca00fb 291 Because asset specifications are used heavily in Pyramid, we've also provided a
SP 292 way to allow users to override assets.  Say you love a system that someone else
293 has created with Pyramid but you just need to change "that one template" to
294 make it all better.  No need to fork the application.  Just override the asset
295 specification for that template with your own inside a wrapper, and you're good
296 to go.
82dcba 297
CM 298 Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`.
299
300 Extensible templating
301 ~~~~~~~~~~~~~~~~~~~~~
302
303 Pyramid has a structured API that allows for pluggability of "renderers".
304 Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated
305 as renderers.  Renderer bindings for all of these templating systems already
306 exist for use in Pyramid.  But if you'd rather use another, it's not a big
307 deal.  Just copy the code from an existing renderer package, and plug in your
ca00fb 308 favorite templating system.  You'll then be able to use that templating system
SP 309 from within Pyramid just as you'd use one of the "built-in" templating systems.
82dcba 310
ca00fb 311 Pyramid does not make you use a single templating system exclusively.  You can
SP 312 use multiple templating systems, even in the same project.
82dcba 313
CM 314 Example: :ref:`templates_used_directly`.
315
85ac6b 316 Rendered views can return dictionaries
CM 317 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e08844 318
CM 319 If you use a :term:`renderer`, you don't have to return a special kind of
ca00fb 320 "webby" ``Response`` object from a view.  Instead you can return a dictionary,
SP 321 and Pyramid will take care of converting that dictionary to a Response using a
322 template on your behalf.  This makes the view easier to test, because you don't
323 have to parse HTML in your tests. Instead just make an assertion that the view
324 returns "the right stuff" in the dictionary.  You can write "real" unit tests
325 instead of functionally testing all of your views.
85ac6b 326
1f7a00 327 .. index::
KOP 328    pair: renderer; explicitly calling
329    pair: view renderer; explictly calling
330
331 .. _example_render_to_response_call:
332
333 For example, instead of returning a ``Response`` object from a
334 ``render_to_response`` call:
85ac6b 335
CM 336 .. code-block:: python
392a6c 337     :linenos:
85ac6b 338
CM 339     from pyramid.renderers import render_to_response
340
341     def myview(request):
342         return render_to_response('myapp:templates/mytemplate.pt', {'a':1},
343                                   request=request)
344
1f7a00 345 You can return a Python dictionary:
85ac6b 346
CM 347 .. code-block:: python
392a6c 348     :linenos:
85ac6b 349
CM 350     from pyramid.view import view_config
351
352     @view_config(renderer='myapp:templates/mytemplate.pt')
353     def myview(request):
354         return {'a':1}
e08844 355
d10aeb 356 When this view callable is called by Pyramid, the ``{'a':1}`` dictionary will
CM 357 be rendered to a response on your behalf.  The string passed as ``renderer=``
358 above is an :term:`asset specification`.  It is in the form
c946fc 359 ``packagename:directoryname/filename.ext``.  In this case, it refers to the
d10aeb 360 ``mytemplate.pt`` file in the ``templates`` directory within the ``myapp``
ca00fb 361 Python package.  Asset specifications are omnipresent in Pyramid. See
d10aeb 362 :ref:`intro_asset_specs` for more information.
CM 363
e08844 364 Example: :ref:`renderers_chapter`.
CM 365
82dcba 366 Event system
CM 367 ~~~~~~~~~~~~
bb93cb 368
82dcba 369 Pyramid emits *events* during its request processing lifecycle.  You can
ca00fb 370 subscribe any number of listeners to these events.  For example, to be notified
SP 371 of a new request, you can subscribe to the ``NewRequest`` event.  To be
372 notified that a template is about to be rendered, you can subscribe to the
82dcba 373 ``BeforeRender`` event, and so forth.  Using an event publishing system as a
CM 374 framework notification feature instead of hardcoded hook points tends to make
375 systems based on that framework less brittle.
bb93cb 376
82dcba 377 You can also use Pyramid's event system to send your *own* events.  For
CM 378 example, if you'd like to create a system that is itself a framework, and may
379 want to notify subscribers that a document has just been indexed, you can
ca00fb 380 create your own event type (``DocumentIndexed`` perhaps) and send the event via
SP 381 Pyramid.  Users of this framework can then subscribe to your event like they'd
382 subscribe to the events that are normally sent by Pyramid itself.
970b88 383
82dcba 384 Example: :ref:`events_chapter` and :ref:`event_types`.
CM 385
386 Built-in internationalization
387 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
388
0e5e1b 389 Pyramid ships with internationalization-related features in its core:
82dcba 390 localization, pluralization, and creating message catalogs from source files
d59239 391 and templates.  Pyramid allows for a plurality of message catalogs via the use
ca00fb 392 of translation domains.  You can create a system that has its own translations
82dcba 393 without conflict with other translations in other domains.
CM 394
395 Example: :ref:`i18n_chapter`.
396
397 HTTP caching
398 ~~~~~~~~~~~~
399
ca00fb 400 Pyramid provides an easy way to associate views with HTTP caching policies. You
SP 401 can just tell Pyramid to configure your view with an ``http_cache`` statement,
402 and it will take care of the rest::
82dcba 403
CM 404    @view_config(http_cache=3600) # 60 minutes
405    def myview(request): ....
406
407 Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to
408 responses generated when this view is invoked.
409
ca00fb 410 See the :meth:`~pyramid.config.Configurator.add_view` method's ``http_cache``
SP 411 documentation for more information.
82dcba 412
CM 413 Sessions
414 ~~~~~~~~
415
416 Pyramid has built-in HTTP sessioning.  This allows you to associate data with
417 otherwise anonymous users between requests.  Lots of systems do this.  But
200417 418 Pyramid also allows you to plug in your own sessioning system by creating some
KOP 419 code that adheres to a documented interface.  Currently there is a binding
ca00fb 420 package for the third-party Redis sessioning system that does exactly this. But
SP 421 if you have a specialized need (perhaps you want to store your session data in
422 MongoDB), you can.  You can even switch between implementations without
200417 423 changing your application code.
82dcba 424
CM 425 Example: :ref:`sessions_chapter`.
426
427 Speed
428 ~~~~~
429
ca00fb 430 The Pyramid core is, as far as we can tell, at least marginally faster than any
SP 431 other existing Python web framework.  It has been engineered from the ground up
432 for speed.  It only does as much work as absolutely necessary when you ask it
433 to get a job done.  Extraneous function calls and suboptimal algorithms in its
434 core codepaths are avoided.  It is feasible to get, for example, between 3500
435 and 4000 requests per second from a simple Pyramid view on commodity dual-core
436 laptop hardware and an appropriate WSGI server (mod_wsgi or gunicorn).  In any
437 case, performance statistics are largely useless without requirements and
438 goals, but if you need speed, Pyramid will almost certainly never be your
439 application's bottleneck; at least no more than Python will be a bottleneck.
82dcba 440
d59239 441 Example: http://blog.curiasolutions.com/pages/the-great-web-framework-shootout.html
82dcba 442
CM 443 Exception views
444 ~~~~~~~~~~~~~~~
445
446 Exceptions happen.  Rather than deal with exceptions that might present
447 themselves to a user in production in an ad-hoc way, Pyramid allows you to
448 register an :term:`exception view`.  Exception views are like regular Pyramid
449 views, but they're only invoked when an exception "bubbles up" to Pyramid
450 itself.  For example, you might register an exception view for the
451 :exc:`Exception` exception, which will catch *all* exceptions, and present a
452 pretty "well, this is embarrassing" page.  Or you might choose to register an
ca00fb 453 exception view for only specific kinds of application-specific exceptions, such
SP 454 as an exception that happens when a file is not found, or an exception that
455 happens when an action cannot be performed because the user doesn't have
82dcba 456 permission to do something.  In the former case, you can show a pretty "Not
CM 457 Found" page; in the latter case you might show a login form.
458
459 Example: :ref:`exception_views`.
460
461 No singletons
462 ~~~~~~~~~~~~~
463
464 Pyramid is written in such a way that it requires your application to have
ca00fb 465 exactly zero "singleton" data structures.  Or put another way, Pyramid doesn't
SP 466 require you to construct any "mutable globals".  Or put even another different
467 way, an import of a Pyramid application needn't have any "import-time side
468 effects".  This is esoteric-sounding, but if you've ever tried to cope with
469 parameterizing a Django ``settings.py`` file for multiple installations of the
470 same application, or if you've ever needed to monkey-patch some framework
471 fixture so that it behaves properly for your use case, or if you've ever wanted
472 to deploy your system using an asynchronous server, you'll end up appreciating
473 this feature.  It just won't be a problem. You can even run multiple copies of
474 a similar but not identically configured Pyramid application within the same
475 Python process.  This is good for shared hosting environments, where RAM is at
476 a premium.
82dcba 477
CM 478 View predicates and many views per route
479 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
480
481 Unlike many other systems, Pyramid allows you to associate more than one view
ca00fb 482 per route.  For example, you can create a route with the pattern ``/items`` and
SP 483 when the route is matched, you can shuffle off the request to one view if the
484 request method is GET, another view if the request method is POST, etc. A
485 system known as "view predicates" allows for this.  Request method matching is
486 the most basic thing you can do with a view predicate.  You can also associate
487 views with other request parameters, such as the elements in the query string,
488 the Accept header, whether the request is an XHR request or not, and lots of
489 other things.  This feature allows you to keep your individual views clean.
490 They won't need much conditional logic, so they'll be easier to test.
82dcba 491
CM 492 Example: :ref:`view_configuration_parameters`.
493
494 Transaction management
495 ~~~~~~~~~~~~~~~~~~~~~~
496
ca00fb 497 Pyramid's :term:`scaffold` system renders projects that include a *transaction
SP 498 management* system, stolen from Zope.  When you use this transaction management
499 system, you cease being responsible for committing your data anymore.  Instead
500 Pyramid takes care of committing: it commits at the end of a request or aborts
501 if there's an exception.  Why is that a good thing?  Having a centralized place
502 for transaction management is a great thing.  If, instead of managing your
503 transactions in a centralized place, you sprinkle ``session.commit`` calls in
504 your application logic itself, you can wind up in a bad place.  Wherever you
505 manually commit data to your database, it's likely that some of your other code
506 is going to run *after* your commit. If that code goes on to do other important
507 things after that commit, and an error happens in the later code, you can
508 easily wind up with inconsistent data if you're not extremely careful.  Some
509 data will have been written to the database that probably should not have. 
510 Having a centralized commit point saves you from needing to think about this;
511 it's great for lazy people who also care about data integrity.  Either the
512 request completes successfully, and all changes are committed, or it does not,
513 and all changes are aborted.
82dcba 514
ca00fb 515 Pyramid's transaction management system allows you to synchronize commits
SP 516 between multiple databases. It also allows you to do things like conditionally
517 send email if a transaction commits, but otherwise keep quiet.
82dcba 518
CM 519 Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements
520 anywhere in application code).
521
522 Configuration conflict detection
523 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
524
ca00fb 525 When a system is small, it's reasonably easy to keep it all in your head. But
SP 526 when systems grow large, you may have hundreds or thousands of configuration
527 statements which add a view, add a route, and so forth.
d59239 528
ca00fb 529 Pyramid's configuration system keeps track of your configuration statements. If
SP 530 you accidentally add two that are identical, or Pyramid can't make sense out of
531 what it would mean to have both statements active at the same time, it will
532 complain loudly at startup time.  It's not dumb though. It will automatically
533 resolve conflicting configuration statements on its own if you use the
534 configuration :meth:`~pyramid.config.Configurator.include` system. "More local"
535 statements are preferred over "less local" ones.  This allows you to
536 intelligently factor large systems into smaller ones.
82dcba 537
CM 538 Example: :ref:`conflict_detection`.
539
540 Configuration extensibility
541 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
542
543 Unlike other systems, Pyramid provides a structured "include" mechanism (see
1d03bb 544 :meth:`~pyramid.config.Configurator.include`) that allows you to combine
82dcba 545 applications from multiple Python packages.  All the configuration statements
ca00fb 546 that can be performed in your "main" Pyramid application can also be performed
SP 547 by included packages, including the addition of views, routes, subscribers, and
548 even authentication and authorization policies. You can even extend or override
549 an existing application by including another application's configuration in
550 your own, overriding or adding new views and routes to it.  This has the
551 potential to allow you to create a big application out of many other smaller
552 ones.  For example, if you want to reuse an existing application that already
553 has a bunch of routes, you can just use the ``include`` statement with a
554 ``route_prefix``. The new application will live within your application at an
555 URL prefix.  It's not a big deal, and requires little up-front engineering
556 effort.
82dcba 557
CM 558 For example:
559
560 .. code-block:: python
561    :linenos:
562
563    from pyramid.config import Configurator
564
565    if __name__ == '__main__':
566       config = Configurator()
567       config.include('pyramid_jinja2')
568       config.include('pyramid_exclog')
569       config.include('some.other.guys.package', route_prefix='/someotherguy')
570
2033ee 571 .. seealso::
SP 572
573     See also :ref:`including_configuration` and
574     :ref:`building_an_extensible_app`.
82dcba 575
CM 576 Flexible authentication and authorization
577 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
578
ca00fb 579 Pyramid includes a flexible, pluggable authentication and authorization system.
SP 580 No matter where your user data is stored, or what scheme you'd like to use to
581 permit your users to access your data, you can use a predefined Pyramid
582 plugpoint to plug in your custom authentication and authorization code.  If you
583 want to change these schemes later, you can just change it in one place rather
584 than everywhere in your code.  It also ships with prebuilt well-tested
585 authentication and authorization schemes out of the box.  But what if you don't
586 want to use Pyramid's built-in system?  You don't have to. You can just write
587 your own bespoke security code as you would in any other system.
82dcba 588
CM 589 Example: :ref:`enabling_authorization_policy`.
590
591 Traversal
592 ~~~~~~~~~
593
594 :term:`Traversal` is a concept stolen from :term:`Zope`.  It allows you to
ca00fb 595 create a tree of resources, each of which can be addressed by one or more URLs.
SP 596 Each of those resources can have one or more *views* associated with it. If
597 your data isn't naturally treelike, or you're unwilling to create a treelike
598 representation of your data, you aren't going to find traversal very useful. 
599 However, traversal is absolutely fantastic for sites that need to be
600 arbitrarily extensible. It's a lot easier to add a node to a tree than it is to
601 shoehorn a route into an ordered list of other routes, or to create another
602 entire instance of an application to service a department and glue code to
603 allow disparate apps to share data.  It's a great fit for sites that naturally
604 lend themselves to changing departmental hierarchies, such as content
605 management systems and document management systems.  Traversal also lends
606 itself well to systems that require very granular security ("Bob can edit
607 *this* document" as opposed to "Bob can edit documents").
82dcba 608
d6a954 609 Examples: :ref:`hello_traversal_chapter` and
CM 610 :ref:`much_ado_about_traversal_chapter`.
82dcba 611
CM 612 Tweens
613 ~~~~~~
614
37607c 615 Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be hooked
CI 616 by arbitrary add-ons named "tweens".  The debug toolbar is a "tween", and the
617 ``pyramid_tm`` transaction manager is also.  Tweens are more useful than WSGI
618 :term:`middleware` in some circumstances because they run in the context of
82dcba 619 Pyramid itself, meaning you have access to templates and other renderers, a
CM 620 "real" request object, and other niceties.
621
622 Example: :ref:`registering_tweens`.
bb93cb 623
d3aae8 624 View response adapters
970b88 625 ~~~~~~~~~~~~~~~~~~~~~~
85ac6b 626
970b88 627 A lot is made of the aesthetics of what *kinds* of objects you're allowed to
CM 628 return from view callables in various frameworks.  In a previous section in
d59239 629 this document, we showed you that, if you use a :term:`renderer`, you can
970b88 630 usually return a dictionary from a view callable instead of a full-on
814455 631 :term:`Response` object.  But some frameworks allow you to return strings or
e7085b 632 tuples from view callables.  When frameworks allow for this, code looks
CM 633 slightly prettier, because fewer imports need to be done, and there is less
634 code.  For example, compare this:
85ac6b 635
CM 636 .. code-block:: python
637    :linenos:
638
639    def aview(request):
640        return "Hello world!"
641
642 To this:
643
644 .. code-block:: python
645    :linenos:
646
647    from pyramid.response import Response
648
649    def aview(request):
650        return Response("Hello world!")
651
652 The former is "prettier", right?
653
654 Out of the box, if you define the former view callable (the one that simply
655 returns a string) in Pyramid, when it is executed, Pyramid will raise an
ca00fb 656 exception.  This is because "explicit is better than implicit", in most cases,
SP 657 and by default Pyramid wants you to return a :term:`Response` object from a
658 view callable.  This is because there's usually a heck of a lot more to a
659 response object than just its body.  But if you're the kind of person who
660 values such aesthetics, we have an easy way to allow for this sort of thing:
85ac6b 661
CM 662 .. code-block:: python
663    :linenos:
664
665    from pyramid.config import Configurator
666    from pyramid.response import Response
667
668    def string_response_adapter(s):
669        response = Response(s)
670        response.content_type = 'text/html'
671        return response
672
673    if __name__ == '__main__':
674        config = Configurator()
675        config.add_response_adapter(string_response_adapter, basestring)
676
677 Do that once in your Pyramid application at startup.  Now you can return
678 strings from any of your view callables, e.g.:
679
680 .. code-block:: python
681    :linenos:
682
683    def helloview(request):
684        return "Hello world!"
685
686    def goodbyeview(request):
687        return "Goodbye world!"
688
689 Oh noes!  What if you want to indicate a custom content type?  And a custom
690 status code?  No fear:
691
692 .. code-block:: python
693    :linenos:
694
695    from pyramid.config import Configurator
696
697    def tuple_response_adapter(val):
698        status_int, content_type, body = val
699        response = Response(body)
700        response.content_type = content_type
701        response.status_int = status_int
702        return response
703
704    def string_response_adapter(body):
705        response = Response(body)
706        response.content_type = 'text/html'
707        response.status_int = 200
708        return response
709
710    if __name__ == '__main__':
711        config = Configurator()
712        config.add_response_adapter(string_response_adapter, basestring)
713        config.add_response_adapter(tuple_response_adapter, tuple)
714
715 Once this is done, both of these view callables will work:
716
717 .. code-block:: python
718    :linenos:
719
720    def aview(request):
721        return "Hello world!"
722
723    def anotherview(request):
724        return (403, 'text/plain', "Forbidden")
725
ca00fb 726 Pyramid defaults to explicit behavior, because it's the most generally useful,
SP 727 but provides hooks that allow you to adapt the framework to localized aesthetic
728 desires.
85ac6b 729
2033ee 730 .. seealso::
SP 731
732     See also :ref:`using_iresponse`.
85ac6b 733
d3aae8 734 "Global" response object
970b88 735 ~~~~~~~~~~~~~~~~~~~~~~~~
CM 736
ca00fb 737 "Constructing these response objects in my view callables is such a chore! And
SP 738 I'm way too lazy to register a response adapter, as per the prior section," you
739 say.  Fine.  Be that way:
970b88 740
CM 741 .. code-block:: python
742    :linenos:
743
744    def aview(request):
745        response = request.response
746        response.body = 'Hello world!'
747        response.content_type = 'text/plain'
748        return response
749
2033ee 750 .. seealso::
SP 751
752     See also :ref:`request_response_attr`.
bb93cb 753
214125 754 Automating repetitive configuration
CM 755 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
756
757 Does Pyramid's configurator allow you to do something, but you're a little
ca00fb 758 adventurous and just want it a little less verbose?  Or you'd like to offer up
SP 759 some handy configuration feature to other Pyramid users without requiring that
760 we change Pyramid?  You can extend Pyramid's :term:`Configurator` with your own
761 directives.  For example, let's say you find yourself calling
214125 762 :meth:`pyramid.config.Configurator.add_view` repetitively.  Usually you can
ca00fb 763 take the boring away by using existing shortcuts, but let's say that this is a
SP 764 case where there is no such shortcut:
214125 765
CM 766 .. code-block:: python
767    :linenos:
768
769    from pyramid.config import Configurator
770
771    config = Configurator()
772    config.add_route('xhr_route', '/xhr/{id}')
773    config.add_view('my.package.GET_view', route_name='xhr_route',
774                    xhr=True,  permission='view', request_method='GET')
775    config.add_view('my.package.POST_view', route_name='xhr_route',
776                    xhr=True, permission='view', request_method='POST')
777    config.add_view('my.package.HEAD_view', route_name='xhr_route',
778                    xhr=True, permission='view', request_method='HEAD')
779
780 Pretty tedious right?  You can add a directive to the Pyramid configurator to
781 automate some of the tedium away:
782
783 .. code-block:: python
784    :linenos:
785
786    from pyramid.config import Configurator
787
788    def add_protected_xhr_views(config, module):
789        module = config.maybe_dotted(module)
790        for method in ('GET', 'POST', 'HEAD'):
791            view = getattr(module, 'xhr_%s_view' % method, None)
792            if view is not None:
d84407 793                config.add_view(view, route_name='xhr_route', xhr=True,
214125 794                               permission='view', request_method=method)
CM 795
796    config = Configurator()
797    config.add_directive('add_protected_xhr_views', add_protected_xhr_views)
798
799 Once that's done, you can call the directive you've just added as a method of
800 the Configurator object:
801
802 .. code-block:: python
803    :linenos:
804
805    config.add_route('xhr_route', '/xhr/{id}')
806    config.add_protected_xhr_views('my.package')
807
808 Your previously repetitive configuration lines have now morphed into one line.
809
ca00fb 810 You can share your configuration code with others this way, too, by packaging
214125 811 it up and calling :meth:`~pyramid.config.Configurator.add_directive` from
CM 812 within a function called when another user uses the
813 :meth:`~pyramid.config.Configurator.include` method against your code.
814
2033ee 815 .. seealso::
SP 816
817     See also :ref:`add_directive`.
214125 818
d59239 819 Programmatic introspection
321785 820 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5d0989 821
CM 822 If you're building a large system that other users may plug code into, it's
823 useful to be able to get an enumeration of what code they plugged in *at
824 application runtime*.  For example, you might want to show them a set of tabs
825 at the top of the screen based on an enumeration of views they registered.
826
827 This is possible using Pyramid's :term:`introspector`.
828
ca00fb 829 Here's an example of using Pyramid's introspector from within a view callable:
5d0989 830
CM 831 .. code-block:: python
392a6c 832     :linenos:
5d0989 833
CM 834     from pyramid.view import view_config
835     from pyramid.response import Response
836
837     @view_config(route_name='bar')
838     def show_current_route_pattern(request):
839         introspector = request.registry.introspector
840         route_name = request.matched_route.name
841         route_intr = introspector.get('routes', route_name)
842         return Response(str(route_intr['pattern']))
843
2033ee 844 .. seealso::
SP 845
846     See also :ref:`using_introspection`.
5d0989 847
d59239 848 Python 3 compatibility
321785 849 ~~~~~~~~~~~~~~~~~~~~~~
1252ab 850
CM 851 Pyramid and most of its add-ons are Python 3 compatible.  If you develop a
852 Pyramid application today, you won't need to worry that five years from now
ca00fb 853 you'll be backwatered because there are language features you'd like to use but
SP 854 your framework doesn't support newer Python versions.
1252ab 855
bb93cb 856 Testing
CM 857 ~~~~~~~
858
859 Every release of Pyramid has 100% statement coverage via unit and integration
860 tests, as measured by the ``coverage`` tool available on PyPI.  It also has
861 greater than 95% decision/condition coverage as measured by the
682ca5 862 ``instrumental`` tool available on PyPI. It is automatically tested by Travis,
c8a5e0 863 and Jenkins on Python 2.7, Python 3.4, Python 3.5, Python 3.6, and PyPy
682ca5 864 after each commit to its GitHub repository. Official Pyramid add-ons are held
BJR 865 to a similar testing standard.  We still find bugs in Pyramid and its official
866 add-ons, but we've noticed we find a lot more of them while working on other
867 projects that don't have a good testing regime.
bb93cb 868
682ca5 869 Travis: https://travis-ci.org/Pylons/pyramid
BJR 870 Jenkins: http://jenkins.pylonsproject.org/job/pyramid/
bb93cb 871
CM 872 Support
873 ~~~~~~~
874
875 It's our goal that no Pyramid question go unanswered.  Whether you ask a
d59239 876 question on IRC, on the Pylons-discuss mailing list, or on StackOverflow,
SP 877 you're likely to get a reasonably prompt response.  We don't tolerate "support
bdebfb 878 trolls" or other people who seem to get their rocks off by berating fellow
ca00fb 879 users in our various official support channels.  We try to keep it well-lit and
SP 880 new-user-friendly.
bb93cb 881
c8b363 882 Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on
bb93cb 883 irc.freenode.net in an IRC client) or the pylons-discuss maillist at
1cb30e 884 https://groups.google.com/forum/#!forum/pylons-discuss.
bb93cb 885
CM 886 Documentation
887 ~~~~~~~~~~~~~
888
ca00fb 889 It's a constant struggle, but we try to maintain a balance between completeness
SP 890 and new-user-friendliness in the official narrative Pyramid documentation
891 (concrete suggestions for improvement are always appreciated, by the way).  We
892 also maintain a "cookbook" of recipes, which are usually demonstrations of
893 common integration scenarios too specific to add to the official narrative
894 docs.  In any case, the Pyramid documentation is comprehensive.
bb93cb 895
34515f 896 Example: The :ref:`Pyramid Community Cookbook <cookbook:pyramid-cookbook>`.
bb93cb 897
3ea7c7 898 .. index::
6ce1e0 899    single: Pylons Project
3ea7c7 900
a3a27a 901 What Is The Pylons Project?
CM 902 ---------------------------
3ea7c7 903
fd5ae9 904 :app:`Pyramid` is a member of the collection of software published under the
c06d4a 905 Pylons Project.  Pylons software is written by a loose-knit community of
1cb30e 906 contributors.  The `Pylons Project website <http://www.pylonsproject.org>`_
fd5ae9 907 includes details about how :app:`Pyramid` relates to the Pylons Project.
093628 908
8c56ae 909 .. index::
fec0f0 910    single: pyramid and other frameworks
e0887e 911    single: Zope
CM 912    single: Pylons
913    single: Django
914    single: MVC
8c56ae 915
fd5ae9 916 :app:`Pyramid` and Other Web Frameworks
9ec2d6 917 ------------------------------------------
9e3bdb 918
7a505d 919 The first release of Pyramid's predecessor (named :mod:`repoze.bfg`) was made
ca00fb 920 in July of 2008.  At the end of 2010, we changed the name of :mod:`repoze.bfg`
SP 921 to :app:`Pyramid`.  It was merged into the Pylons project as :app:`Pyramid` in
922 November of that year.
fec0f0 923
ca00fb 924 :app:`Pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version 1.0), and
SP 925 :term:`Django`.  As a result, :app:`Pyramid` borrows several concepts and
926 features from each, combining them into a unique web framework.
878328 927
ca00fb 928 Many features of :app:`Pyramid` trace their origins back to :term:`Zope`. Like
SP 929 Zope applications, :app:`Pyramid` applications can be easily extended. If you
930 obey certain constraints, the application you produce can be reused, modified,
931 re-integrated, or extended by third-party developers without forking the
932 original application.  The concepts of :term:`traversal` and declarative
933 security in :app:`Pyramid` were pioneered first in Zope.
601289 934
fd5ae9 935 The :app:`Pyramid` concept of :term:`URL dispatch` is inspired by the
d59239 936 :term:`Routes` system used by :term:`Pylons` version 1.0.  Like Pylons version
SP 937 1.0, :app:`Pyramid` is mostly policy-free.  It makes no assertions about which
938 database you should use. Pyramid no longer has built-in templating facilities
939 as of version 1.5a2, but instead officially supports bindings for templating
ca00fb 940 languages, including Chameleon, Jinja2, and Mako.  In essence, it only supplies
SP 941 a mechanism to map URLs to :term:`view` code, along with a set of conventions
942 for calling those views.  You are free to use third-party components that fit
943 your needs in your applications.
601289 944
ca00fb 945 The concept of :term:`view` is used by :app:`Pyramid` mostly as it would be by
SP 946 Django.  :app:`Pyramid` has a documentation culture more like Django's than
947 like Zope's.
52ced0 948
7a505d 949 Like :term:`Pylons` version 1.0, but unlike :term:`Zope`, a :app:`Pyramid`
CM 950 application developer may use completely imperative code to perform common
951 framework configuration tasks such as adding a view or a route.  In Zope,
952 :term:`ZCML` is typically required for similar purposes.  In :term:`Grok`, a
953 Zope-based web framework, :term:`decorator` objects and class-level
55ce9d 954 declarations are used for this purpose.  Out of the box, Pyramid supports
ca00fb 955 imperative and decorator-based configuration. :term:`ZCML` may be used via an
55ce9d 956 add-on package named ``pyramid_zcml``.
c0c188 957
ca00fb 958 Also unlike :term:`Zope` and other "full-stack" frameworks such as
SP 959 :term:`Django`, :app:`Pyramid` makes no assumptions about which persistence
960 mechanisms you should use to build an application.  Zope applications are
961 typically reliant on :term:`ZODB`. :app:`Pyramid` allows you to build
962 :term:`ZODB` applications, but it has no reliance on the ZODB software.
963 Likewise, :term:`Django` tends to assume that you want to store your
964 application's data in a relational database. :app:`Pyramid` makes no such
965 assumption, allowing you to use a relational database, and neither encouraging
966 nor discouraging the decision.
a56d0c 967
ca00fb 968 Other Python web frameworks advertise themselves as members of a class of web
SP 969 frameworks named `model-view-controller
1cb30e 970 <https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller>`_
SP 971 frameworks. Insofar as this term has been claimed to represent a class of web
972 frameworks, :app:`Pyramid` also generally fits into this class.
c5f24b 973
ca00fb 974 .. sidebar:: You Say :app:`Pyramid` is MVC, but Where's the Controller?
c5f24b 975
ca00fb 976    The :app:`Pyramid` authors believe that the MVC pattern just doesn't really
SP 977    fit the web very well. In a :app:`Pyramid` application, there is a resource
978    tree which represents the site structure, and views which tend to present
979    the data stored in the resource tree and a user-defined "domain model".
980    However, no facility provided *by the framework* actually necessarily maps
981    to the concept of a "controller" or "model".  So if you had to give it some
982    acronym, I guess you'd say :app:`Pyramid` is actually an "RV" framework
983    rather than an "MVC" framework.  "MVC", however, is close enough as a
984    general classification moniker for purposes of comparison with other web
985    frameworks.