- All references to Pyramid-the-application were changed from :mod:`pyramid`
to :app:`Pyramid`. A custom role setting was added to ``docs/conf.py`` to
allow for this. (internal)
| | |
| | | their concrete classes (e.g. ``pyramid.events.NewRequest``) in |
| | | documentation about making subscriptions. |
| | | |
| | | - All references to Pyramid-the-application were changed from :mod:`pyramid` |
| | | to :app:`Pyramid`. A custom role setting was added to ``docs/conf.py`` to |
| | | allow for this. (internal) |
| | | |
| | | 1.0a1 (2010-11-05) |
| | | ================== |
| | | |
| | |
| | | ================= |
| | | |
| | | Comprehensive reference material for every public API exposed by |
| | | :mod:`pyramid` is available within this chapter. The API |
| | | :app:`Pyramid` is available within this chapter. The API |
| | | documentation is organized alphabetically by module name. |
| | | |
| | | .. toctree:: |
| | |
| | | .. autofunction:: default_locale_negotiator |
| | | |
| | | See :ref:`i18n_chapter` for more information about using |
| | | :mod:`pyramid` internationalization and localization services within |
| | | :app:`Pyramid` internationalization and localization services within |
| | | an application. |
| | | |
| | | |
| | |
| | | |
| | | If an exception was raised by a :term:`root factory` or a |
| | | :term:`view callable`, or at various other points where |
| | | :mod:`pyramid` executes user-defined code during the |
| | | :app:`Pyramid` executes user-defined code during the |
| | | processing of a request, the exception object which was caught |
| | | will be available as the ``exception`` attribute of the request |
| | | within a :term:`exception view`, a :term:`response callback` or a |
| | |
| | | Author Introduction |
| | | ===================== |
| | | |
| | | Welcome to "The :mod:`pyramid` Web Application Framework". In this |
| | | Welcome to "The :app:`Pyramid` Web Application Framework". In this |
| | | introduction, I'll describe the audience for this book, I'll describe |
| | | the book content, I'll provide some context regarding the genesis of |
| | | :mod:`pyramid`, and I'll thank some important people. |
| | | :app:`Pyramid`, and I'll thank some important people. |
| | | |
| | | I hope you enjoy both this book and the software it documents. I've |
| | | had a blast writing both. |
| | |
| | | concepts like "URL" or "query string." Likewise, the book describes |
| | | various interactions in terms of the HTTP protocol, but it does not |
| | | describe how the HTTP protocol works in detail. Like any good web |
| | | framework, though, :mod:`pyramid` shields you from needing to know |
| | | framework, though, :app:`Pyramid` shields you from needing to know |
| | | most of the gory details of web protocols and low-level data |
| | | structures. As a result, you can usually avoid becoming "blocked" |
| | | while you read this book even if you don't yet deeply understand web |
| | |
| | | |
| | | :ref:`narrative_documentation` |
| | | |
| | | This is documentation which describes :mod:`pyramid` concepts in |
| | | This is documentation which describes :app:`Pyramid` concepts in |
| | | narrative form, written in a largely conversational tone. Each |
| | | narrative documentation chapter describes an isolated |
| | | :mod:`pyramid` concept. You should be able to get useful |
| | | :app:`Pyramid` concept. You should be able to get useful |
| | | information out of the narrative chapters if you read them |
| | | out-of-order, or when you need only a reminder about a particular |
| | | topic while you're developing an application. |
| | |
| | | Each tutorial builds a sample application or implements a set of |
| | | concepts with a sample; it then describes the application or |
| | | concepts in terms of the sample. You should read the tutorials if |
| | | you want a guided tour of :mod:`pyramid`. |
| | | you want a guided tour of :app:`Pyramid`. |
| | | |
| | | :ref:`api_reference` |
| | | |
| | | Comprehensive reference material for every public API exposed by |
| | | :mod:`pyramid`. The API documentation is organized |
| | | :app:`Pyramid`. The API documentation is organized |
| | | alphabetically by module name. |
| | | |
| | | :ref:`zcml_reference` |
| | | |
| | | Comprehensive reference material for every :term:`ZCML directive` |
| | | provided by :mod:`pyramid`. The ZCML directive documentation is |
| | | provided by :app:`Pyramid`. The ZCML directive documentation is |
| | | organized alphabetically by directive name. |
| | | |
| | | .. index:: |
| | |
| | | The Genesis of :mod:`repoze.bfg` |
| | | ================================ |
| | | |
| | | Before the end of 2010, :mod:`pyramid` was known as :mod:`repoze.bfg`. |
| | | Before the end of 2010, :app:`Pyramid` was known as :mod:`repoze.bfg`. |
| | | |
| | | I wrote :mod:`repoze.bfg` after many years of writing applications |
| | | using :term:`Zope`. Zope provided me with a lot of mileage: it wasn't |
| | |
| | | retained features I had become accustomed to when developing Zope |
| | | applications was a more reasonable idea than continuing to use any |
| | | Zope publisher or living with the limitations and unfamiliarities of a |
| | | different framework. The result is what is now :mod:`pyramid`. |
| | | different framework. The result is what is now :app:`Pyramid`. |
| | | |
| | | The Genesis of :mod:`pyramid` |
| | | The Genesis of :app:`Pyramid` |
| | | ============================= |
| | | |
| | | What was :mod:`repoze.bfg` has become :mod:`pyramid` as the result of |
| | | What was :mod:`repoze.bfg` has become :app:`Pyramid` as the result of |
| | | a coalition built between the :term:`Repoze` and :term:`Pylons` |
| | | community throughout the year 2010. By merging technology, we're able |
| | | to reduce duplication of effort, and take advantage of more of each |
| | |
| | | :mod:`pyramid` Change History |
| | | :app:`Pyramid` Change History |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | .. include:: ../CHANGES.txt |
| | |
| | | # skip raw nodes |
| | | from sphinx.writers.text import TextTranslator |
| | | from docutils import nodes |
| | | from docutils import utils |
| | | |
| | | def raw(*arg): |
| | | raise nodes.SkipNode |
| | | TextTranslator.visit_raw = raw |
| | |
| | | # 'pointsize':'12pt', # uncomment for 12pt version |
| | | } |
| | | |
| | | from docutils import nodes |
| | | |
| | | # secnumdepth counter reset to 2 causes numbering in related matter; |
| | | # reset to -1 causes chapters to not be numbered, reset to -2 causes |
| | | # parts to not be numbered. |
| | |
| | | return [nodes.raw('', '\\backmatter\n\\setcounter{secnumdepth}{-1}\n', |
| | | format='latex')] |
| | | |
| | | def app_role(role, rawtext, text, lineno, inliner, options={}, content=[]): |
| | | """custom role for :app: marker, does nothing in particular except allow |
| | | :app:`Pyramid` to work (for later search and replace).""" |
| | | if 'class' in options: |
| | | assert 'classes' not in options |
| | | options['classes'] = options['class'] |
| | | del options['class'] |
| | | return [nodes.inline(rawtext, utils.unescape(text), **options)], [] |
| | | |
| | | |
| | | def setup(app): |
| | | app.add_role('app', app_role) |
| | | app.add_directive('frontmatter', frontmatter, 1, (0, 0, 0)) |
| | | app.add_directive('mainmatter', mainmatter, 1, (0, 0, 0)) |
| | | app.add_directive('backmatter', backmatter, 1, (0, 0, 0)) |
| | |
| | | |
| | | .. note:: |
| | | |
| | | While the :mod:`pyramid` documentation is offered under the |
| | | While the :app:`Pyramid` documentation is offered under the |
| | | Creative Commons Attribution-Nonconmmercial-Share Alike 3.0 United |
| | | States License, the :mod:`pyramid` *software* is offered under a |
| | | States License, the :app:`Pyramid` *software* is offered under a |
| | | `less restrictive (BSD-like) license |
| | | <http://repoze.org/license.html>`_ . |
| | | |
| | |
| | | http://docs.pylonshq.com |
| | | |
| | | The source code for the examples used in this book are available |
| | | within the :mod:`pyramid` software distribution, always available |
| | | within the :app:`Pyramid` software distribution, always available |
| | | via http://pylonshq.com/pyramid. |
| | | |
| | |
| | | Defending Pyramid's Design |
| | | ========================== |
| | | |
| | | From time to time, challenges to various aspects of :mod:`pyramid` |
| | | From time to time, challenges to various aspects of :app:`Pyramid` |
| | | design are lodged. To give context to discussions that follow, we |
| | | detail some of the design decisions and trade-offs here. In some |
| | | cases, we acknowledge that the framework can be made better and we |
| | |
| | | If it's Zope2-the-web-framework, Pyramid is not that. The primary designers |
| | | and developers of Pyramid, if anyone, should know. We wrote Pyramid's |
| | | predecessor (:mod:`repoze.bfg`), in part, because *we* knew that Zope 2 had |
| | | usability issues and limitations. :mod:`repoze.bfg` (and now :mod:`pyramid`) |
| | | usability issues and limitations. :mod:`repoze.bfg` (and now :app:`Pyramid`) |
| | | was written to address these issues. |
| | | |
| | | If it's Zope3-the-web-framework, Pyramid is *definitely* not that. Making |
| | |
| | | Pyramid Uses A Zope Component Architecture ("ZCA") Registry |
| | | ----------------------------------------------------------- |
| | | |
| | | :mod:`pyramid` uses a :term:`Zope Component Architecture` (ZCA) |
| | | :app:`Pyramid` uses a :term:`Zope Component Architecture` (ZCA) |
| | | "component registry" as its :term:`application registry` under the |
| | | hood. This is a point of some contention. :mod:`pyramid` is of a |
| | | hood. This is a point of some contention. :app:`Pyramid` is of a |
| | | :term:`Zope` pedigree, so it was natural for its developers to use a |
| | | ZCA registry at its inception. However, we understand that using a |
| | | ZCA registry has issues and consequences, which we've attempted to |
| | | address as best we can. Here's an introspection about |
| | | :mod:`pyramid` use of a ZCA registry, and the trade-offs its usage |
| | | :app:`Pyramid` use of a ZCA registry, and the trade-offs its usage |
| | | involves. |
| | | |
| | | Problems |
| | |
| | | would require knowledge of internals). Can there be more than one |
| | | registry? Yes. So *which* registry does it find the registration in? |
| | | Well, the "current" registry of course. In terms of |
| | | :mod:`pyramid`, the current registry is a thread local variable. |
| | | :app:`Pyramid`, the current registry is a thread local variable. |
| | | Using an API that consults a thread local makes understanding how it |
| | | works non-local. |
| | | |
| | |
| | | comprehend. Problem number six. |
| | | |
| | | Clearly there's some amount of cognitive load here that needs to be |
| | | borne by a reader of code that extends the :mod:`pyramid` framework |
| | | borne by a reader of code that extends the :app:`Pyramid` framework |
| | | due to its use of the ZCA, even if he or she is already an expert |
| | | Python programmer and whom is an expert in the domain of web |
| | | applications. This is suboptimal. |
| | |
| | | Ameliorations |
| | | +++++++++++++ |
| | | |
| | | First, the primary amelioration: :mod:`pyramid` *does not expect |
| | | First, the primary amelioration: :app:`Pyramid` *does not expect |
| | | application developers to understand ZCA concepts or any of its APIs*. |
| | | If an *application* developer needs to understand a ZCA concept or API |
| | | during the creation of a :mod:`pyramid` application, we've failed |
| | | during the creation of a :app:`Pyramid` application, we've failed |
| | | on some axis. |
| | | |
| | | Instead, the framework hides the presence of the ZCA registry behind |
| | |
| | | about the ZCA API: they should call a Python function with some object |
| | | germane to the domain as an argument, and it should returns a result. |
| | | A corollary that follows is that any reader of an application that has |
| | | been written using :mod:`pyramid` needn't understand the ZCA API |
| | | been written using :app:`Pyramid` needn't understand the ZCA API |
| | | either. |
| | | |
| | | Hiding the ZCA API from application developers and code readers is a |
| | |
| | | wants to need to understand the minutiae of the mechanics of how a web |
| | | framework does its thing. People want to deal in concepts that are |
| | | closer to the domain they're working in: for example, web developers |
| | | want to know about *users*, not *utilities*. :mod:`pyramid` uses |
| | | want to know about *users*, not *utilities*. :app:`Pyramid` uses |
| | | the ZCA as an implementation detail, not as a feature which is exposed |
| | | to end users. |
| | | |
| | | However, unlike application developers, *framework developers*, |
| | | including people who want to override :mod:`pyramid` functionality |
| | | including people who want to override :app:`Pyramid` functionality |
| | | via preordained framework plugpoints like traversal or view lookup |
| | | *must* understand the ZCA registry API. |
| | | |
| | | :mod:`pyramid` framework developers were so concerned about |
| | | :app:`Pyramid` framework developers were so concerned about |
| | | conceptual load issues of the ZCA registry API for framework |
| | | developers that a `replacement registry implementation |
| | | <http://svn.repoze.org/repoze.component/trunk>`_ named |
| | | :mod:`repoze.component` was actually developed. Though this package |
| | | has a registry implementation which is fully functional and |
| | | well-tested, and its API is much nicer than the ZCA registry API, work |
| | | on it was largely abandoned and it is not used in :mod:`pyramid`. |
| | | We continued to use a ZCA registry within :mod:`pyramid` because it |
| | | on it was largely abandoned and it is not used in :app:`Pyramid`. |
| | | We continued to use a ZCA registry within :app:`Pyramid` because it |
| | | ultimately proved a better fit. |
| | | |
| | | .. note:: We continued using ZCA registry rather than disusing it in |
| | |
| | | reinventing the wheel. |
| | | |
| | | Making framework developers and extenders understand the ZCA registry |
| | | API is a trade-off. We (the :mod:`pyramid` developers) like the |
| | | API is a trade-off. We (the :app:`Pyramid` developers) like the |
| | | features that the ZCA registry gives us, and we have long-ago borne |
| | | the weight of understanding what it does and how it works. The |
| | | authors of :mod:`pyramid` understand the ZCA deeply and can read |
| | | authors of :app:`Pyramid` understand the ZCA deeply and can read |
| | | code that uses it as easily as any other code. |
| | | |
| | | But we recognize that developers who my want to extend the framework |
| | | are not as comfortable with the ZCA registry API as the original |
| | | developers are with it. So, for the purposes of being kind to |
| | | third-party :mod:`pyramid` framework developers in, we've drawn |
| | | third-party :app:`Pyramid` framework developers in, we've drawn |
| | | some lines in the sand. |
| | | |
| | | #) In all "core" code, We've made use of ZCA global API functions such |
| | |
| | | from zope.component import getUtility |
| | | policy = getUtility(IAuthenticationPolicy) |
| | | |
| | | :mod:`pyramid` code will usually do: |
| | | :app:`Pyramid` code will usually do: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | |
| | | policy = registry.getUtility(IAuthenticationPolicy) |
| | | |
| | | While the latter is more verbose, it also arguably makes it more |
| | | obvious what's going on. All of the :mod:`pyramid` core code uses |
| | | obvious what's going on. All of the :app:`Pyramid` core code uses |
| | | this pattern rather than the ZCA global API. |
| | | |
| | | #) We've turned the component registry used by :mod:`pyramid` into |
| | | #) We've turned the component registry used by :app:`Pyramid` into |
| | | something that is accessible using the plain old dictionary API |
| | | (like the :mod:`repoze.component` API). For example, the snippet |
| | | of code in the problem section above was: |
| | |
| | | attributes and the dictionary API. Every Python programmer knows |
| | | these things, even framework programmers. |
| | | |
| | | While :mod:`pyramid` still uses some suboptimal unnamed utility |
| | | While :app:`Pyramid` still uses some suboptimal unnamed utility |
| | | registrations, future versions of it will where possible disuse these |
| | | things in favor of straight dictionary assignments and lookups, as |
| | | demonstrated above, to be kinder to new framework developers. We'll |
| | |
| | | Rationale |
| | | +++++++++ |
| | | |
| | | Here are the main rationales involved in the :mod:`pyramid` |
| | | Here are the main rationales involved in the :app:`Pyramid` |
| | | decision to use the ZCA registry: |
| | | |
| | | - Pedigree. A nontrivial part of the answer to this question is |
| | | "pedigree". Much of the design of :mod:`pyramid` is stolen |
| | | "pedigree". Much of the design of :app:`Pyramid` is stolen |
| | | directly from :term:`Zope`. Zope uses the ZCA registry to do a |
| | | number of tricks. :mod:`pyramid` mimics these tricks, and, |
| | | number of tricks. :app:`Pyramid` mimics these tricks, and, |
| | | because the ZCA registry works well for that set of tricks, |
| | | :mod:`pyramid` uses it for the same purposes. For example, the |
| | | way that :mod:`pyramid` maps a :term:`request` to a :term:`view |
| | | :app:`Pyramid` uses it for the same purposes. For example, the |
| | | way that :app:`Pyramid` maps a :term:`request` to a :term:`view |
| | | callable` is lifted almost entirely from Zope. The ZCA registry |
| | | plays an important role in the particulars of how this request to |
| | | view mapping is done. |
| | |
| | | :term:`interface`. |
| | | |
| | | - Singularity. There's only one "place" where "application |
| | | configuration" lives in a :mod:`pyramid` application: in a |
| | | configuration" lives in a :app:`Pyramid` application: in a |
| | | component registry. The component registry answers questions made |
| | | to it by the framework at runtime based on the configuration of *an |
| | | application*. Note: "an application" is not the same as "a |
| | | process", multiple independently configured copies of the same |
| | | :mod:`pyramid` application are capable of running in the same |
| | | :app:`Pyramid` application are capable of running in the same |
| | | process space. |
| | | |
| | | - Composability. A ZCA component registry can be populated |
| | |
| | | extensibility via a well-defined and widely understood plugin |
| | | architecture. As long as framework developers and extenders |
| | | understand the ZCA registry, it's possible to extend |
| | | :mod:`pyramid` almost arbitrarily. For example, it's relatively |
| | | :app:`Pyramid` almost arbitrarily. For example, it's relatively |
| | | easy to build a ZCML directive that registers several views "all at |
| | | once", allowing app developers to use that ZCML directive as a |
| | | "macro" in code that they write. This is somewhat of a |
| | |
| | | lookups in the code find our mock objects. |
| | | |
| | | - Speed. The ZCA registry is very fast for a specific set of complex |
| | | lookup scenarios that :mod:`pyramid` uses, having been optimized |
| | | lookup scenarios that :app:`Pyramid` uses, having been optimized |
| | | through the years for just these purposes. The ZCA registry |
| | | contains optional C code for this purpose which demonstrably has no |
| | | (or very few) bugs. |
| | | |
| | | - Ecosystem. Many existing Zope packages can be used in |
| | | :mod:`pyramid` with few (or no) changes due to our use of the ZCA |
| | | :app:`Pyramid` with few (or no) changes due to our use of the ZCA |
| | | registry and :term:`ZCML`. |
| | | |
| | | Conclusion |
| | | ++++++++++ |
| | | |
| | | If you only *develop applications* using :mod:`pyramid`, there's not much to |
| | | If you only *develop applications* using :app:`Pyramid`, there's not much to |
| | | complain about here. You just should never need to understand the ZCA |
| | | registry or even know about its presence: use documented :mod:`pyramid` APIs |
| | | registry or even know about its presence: use documented :app:`Pyramid` APIs |
| | | instead. However, you may be an application developer who doesn't read API |
| | | documentation because it's unmanly. Instead you read the raw source code, and |
| | | because you haven't read the documentation, you don't know what functions, |
| | | classes, and methods even *form* the :mod:`pyramid` API. As a result, you've |
| | | classes, and methods even *form* the :app:`Pyramid` API. As a result, you've |
| | | now written code that uses internals and you've painted yourself into a |
| | | conceptual corner as a result of needing to wrestle with some ZCA-using |
| | | implementation detail. If this is you, it's extremely hard to have a lot of |
| | |
| | | the ZCA registry or you'll need to use only the documented APIs; that's why |
| | | we document them as APIs. |
| | | |
| | | If you *extend* or *develop* :mod:`pyramid` (create new ZCML directives, use |
| | | If you *extend* or *develop* :app:`Pyramid` (create new ZCML directives, use |
| | | some of the more obscure "ZCML hooks" as described in :ref:`hooks_chapter`, |
| | | or work on the :mod:`pyramid` core code), you will be faced with needing to |
| | | or work on the :app:`Pyramid` core code), you will be faced with needing to |
| | | understand at least some ZCA concepts. In some places it's used unabashedly, |
| | | and will be forever. We know it's quirky, but it's also useful and |
| | | fundamentally understandable if you take the time to do some reading about |
| | |
| | | Ian Bicking asserts that the way :mod:`repoze.bfg` used a Zope interface to |
| | | represent an HTTP request method added too much indirection for not enough |
| | | gain. We agreed in general, and for this reason, :mod:`repoze.bfg` version 1.1 |
| | | (and subsequent versions including :mod:`pyramid` 1.0+) added :term:`view |
| | | (and subsequent versions including :app:`Pyramid` 1.0+) added :term:`view |
| | | predicate` and :term:`route predicate` modifiers to view configuration. |
| | | Predicates are request-specific (or :term:`context` -specific) matching |
| | | narrowers which don't use interfaces. Instead, each predicate uses a |
| | |
| | | -------------------------------- |
| | | |
| | | :term:`ZCML` is a configuration language that can be used to configure the |
| | | :term:`Zope Component Architecture` registry that :mod:`pyramid` uses as its |
| | | :term:`Zope Component Architecture` registry that :app:`Pyramid` uses as its |
| | | application configuration. Often people claim that Pyramid "needs ZCML". |
| | | |
| | | Quick answer: well, it doesn't. At least not anymore. In :mod:`repoze.bfg` |
| | | (the predecessor to Pyramid) versions 1.0 and and 1.1, an application needed to |
| | | possess a ZCML file for it to begin executing successfully. However, |
| | | :mod:`repoze.bfg` 1.2 and greater (including :mod:`pyramid` 1.0) includes a |
| | | :mod:`repoze.bfg` 1.2 and greater (including :app:`Pyramid` 1.0) includes a |
| | | completely imperative mode for all configuration. You will be able to make |
| | | "single file" apps in this mode, which should help people who need to see |
| | | everything done completely imperatively. For example, the very most basic |
| | | :mod:`pyramid` "helloworld" program has become something like: |
| | | :app:`Pyramid` "helloworld" program has become something like: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | |
| | | |
| | | This declaration associates a :term:`view` with a route pattern. |
| | | |
| | | All :mod:`pyramid` declarations are singleton tags, unlike many |
| | | All :app:`Pyramid` declarations are singleton tags, unlike many |
| | | other XML configuration systems. No XML *values* in ZCML are |
| | | meaningful; it's always just XML tags and attributes. So in the very |
| | | common case it's not really very much different than an otherwise |
| | | "flat" configuration format like ``.ini``, except a developer can |
| | | *create* a directive that requires nesting (none of these exist in |
| | | :mod:`pyramid` itself), and multiple "sections" can exist with the |
| | | :app:`Pyramid` itself), and multiple "sections" can exist with the |
| | | same "name" (e.g. two ``<route>`` declarations) must be able to exist |
| | | simultaneously. |
| | | |
| | | You might think some other configuration file format would be better. |
| | | But all configuration formats suck in one way or another. I |
| | | personally don't think any of our lives would be markedly better if |
| | | the declarative configuration format used by :mod:`pyramid` were |
| | | the declarative configuration format used by :app:`Pyramid` were |
| | | YAML, JSON, or INI. It's all just plumbing that you mostly cut and |
| | | paste once you've progressed 30 minutes into your first project. |
| | | Folks who tend to agitate for another configuration file format are |
| | |
| | | Pyramid Uses "Model" To Represent A Node In The Graph of Objects Traversed |
| | | -------------------------------------------------------------------------- |
| | | |
| | | The :mod:`pyramid` documentation refers to the graph being |
| | | The :app:`Pyramid` documentation refers to the graph being |
| | | traversed when :term:`traversal` is used as a "model graph". Some of |
| | | the :mod:`pyramid` APIs also use the word "model" in them when |
| | | the :app:`Pyramid` APIs also use the word "model" in them when |
| | | referring to a node in this graph (e.g. ``pyramid.url.model_url``). |
| | | |
| | | A terminology overlap confuses people who write applications that |
| | |
| | | result of some query performed by a :term:`view`. As a result, it can |
| | | be unnatural to think of the nodes traversed as "model" objects if you |
| | | develop your application using traversal and a relational database. |
| | | When you develop such applications, the things that :mod:`pyramid` |
| | | When you develop such applications, the things that :app:`Pyramid` |
| | | refers to as "models" in such an application may just be stand-ins |
| | | that perform a query and generate some wrapper *for* an ORM "model" |
| | | (or set of ORM models). The graph *might* be composed completely of |
| | | "model" objects (as defined by the ORM) but it also might not be. |
| | | |
| | | The naming impedance mismatch between the way the term "model" is used |
| | | to refer to a node in a graph in :mod:`pyramid` and the way the |
| | | to refer to a node in a graph in :app:`Pyramid` and the way the |
| | | term "model" is used by packages like SQLAlchemy is unfortunate. For |
| | | the purpose of avoiding confusion, if we had it to do all over again, |
| | | we might refer to the graph that :mod:`pyramid` traverses a "node |
| | | we might refer to the graph that :app:`Pyramid` traverses a "node |
| | | graph" or "object graph" rather than a "model graph", but since we've |
| | | baked the name into the API, it's a little late. Sorry. |
| | | |
| | | In our defense, many :mod:`pyramid` applications (especially ones |
| | | In our defense, many :app:`Pyramid` applications (especially ones |
| | | which use :term:`ZODB`) do indeed traverse a graph full of model |
| | | nodes. Each node in the graph is a separate persistent object that is |
| | | stored within a database. This was the use case considered when |
| | |
| | | Pyramid Does Traversal, And I Don't Like Traversal |
| | | -------------------------------------------------- |
| | | |
| | | In :mod:`pyramid`, :term:`traversal` is the act of resolving a URL |
| | | In :app:`Pyramid`, :term:`traversal` is the act of resolving a URL |
| | | path to a :term:`model` object in an object graph. Some people are |
| | | uncomfortable with this notion, and believe it is wrong. |
| | | |
| | |
| | | database. In this situation, the graph being traversed is actually |
| | | less a "model graph" than a site structure. |
| | | |
| | | But the point is ultimately moot. If you use :mod:`pyramid`, and |
| | | But the point is ultimately moot. If you use :app:`Pyramid`, and |
| | | you don't want to model your application in terms of traversal, you |
| | | needn't use it at all. Instead, use :term:`URL dispatch` to map URL |
| | | paths to views. |
| | |
| | | Pyramid Does URL Dispatch, And I Don't Like URL Dispatch |
| | | -------------------------------------------------------- |
| | | |
| | | In :mod:`pyramid`, :term:`url dispatch` is the act of resolving a |
| | | In :app:`Pyramid`, :term:`url dispatch` is the act of resolving a |
| | | URL path to a :term:`view` callable by performing pattern matching |
| | | against some set of ordered route definitions. The route definitions |
| | | are examined in order: the first pattern which matches is used to |
| | |
| | | |
| | | I'll argue that URL dispatch is ultimately useful, even if you want to use |
| | | traversal as well. You can actually *combine* URL dispatch and traversal in |
| | | :mod:`pyramid` (see :ref:`hybrid_chapter`). One example of such a usage: if |
| | | :app:`Pyramid` (see :ref:`hybrid_chapter`). One example of such a usage: if |
| | | you want to emulate something like Zope 2's "Zope Management Interface" UI on |
| | | top of your object graph (or any administrative interface), you can register |
| | | a route like ``<route name="manage" pattern="manage/*traverse"/>`` and then |
| | |
| | | pointless to add a node to the object graph that effectively |
| | | represents the entry point for some bit of code. You can just use a |
| | | route and be done with it. If a route matches, a view associated with |
| | | the route will be called; if no route matches, :mod:`pyramid` falls |
| | | the route will be called; if no route matches, :app:`Pyramid` falls |
| | | back to using traversal. |
| | | |
| | | But the point is ultimately moot. If you use :mod:`pyramid`, and |
| | | But the point is ultimately moot. If you use :app:`Pyramid`, and |
| | | you really don't want to use URL dispatch, you needn't use it at all. |
| | | Instead, use :term:`traversal` exclusively to map URL paths to views, |
| | | just like you do in :term:`Zope`. |
| | |
| | | its argument list filled with values mentioned therein. TurboGears |
| | | and Pylons 1.X operate similarly. |
| | | |
| | | :mod:`pyramid` has neither of these features. :mod:`pyramid` |
| | | :app:`Pyramid` has neither of these features. :mod:`pyramid` |
| | | view callables always accept only ``context`` and ``request`` (or just |
| | | ``request``), and no other arguments. The rationale: this argument |
| | | specification matching done aggressively can be costly, and |
| | | :mod:`pyramid` has performance as one of its main goals, so we've |
| | | :app:`Pyramid` has performance as one of its main goals, so we've |
| | | decided to make people obtain information by interrogating the request |
| | | object for it in the view body instead of providing magic to do |
| | | unpacking into the view argument list. The feature itself also just |
| | |
| | | behavior as a decorator by wrapping the view with a decorator that |
| | | looks in ``request.matchdict``. |
| | | |
| | | It's possible at some point that :mod:`pyramid` will grow some form |
| | | It's possible at some point that :app:`Pyramid` will grow some form |
| | | of argument matching feature (it would be simple to make it an |
| | | always-on optional feature that has no cost unless you actually use |
| | | it) for, but currently it has none. |
| | |
| | | Pyramid Provides Too Few "Rails" |
| | | -------------------------------- |
| | | |
| | | By design, :mod:`pyramid` is not a particularly "opinionated" web framework. |
| | | By design, :app:`Pyramid` is not a particularly "opinionated" web framework. |
| | | It has a relatively parsimonious feature set. It contains no built in ORM |
| | | nor any particular database bindings. It contains no form generation |
| | | framework. It has no administrative web user interface. It has no built in |
| | | text indexing. It does not dictate how you arrange your code. |
| | | |
| | | Such opinionated functionality exists in applications and frameworks built |
| | | *on top* of :mod:`pyramid`. It's intended that higher-level systems emerge |
| | | built using :mod:`pyramid` as a base. See also :ref:`apps_are_extensible`. |
| | | *on top* of :app:`Pyramid`. It's intended that higher-level systems emerge |
| | | built using :app:`Pyramid` as a base. See also :ref:`apps_are_extensible`. |
| | | |
| | | Pyramid Provides Too Many "Rails" |
| | | --------------------------------- |
| | | |
| | | :mod:`pyramid` provides some features that other web frameworks do |
| | | :app:`Pyramid` provides some features that other web frameworks do |
| | | not. Most notably it has machinery which resolves a URL first to a |
| | | :term:`context` before calling a view (which has the capability to |
| | | accept the context in its argument list), and a declarative |
| | |
| | | Having context-sensitive declarative security for individual objects |
| | | in the object graph is simply required for this class of application. |
| | | Other frameworks save for Zope just do not have this feature. This is |
| | | one of the primary reasons that :mod:`pyramid` was actually |
| | | one of the primary reasons that :app:`Pyramid` was actually |
| | | written. |
| | | |
| | | If you don't like this, it doesn't mean you can't use |
| | | :mod:`pyramid`. Just ignore this feature and avoid configuring an |
| | | :app:`Pyramid`. Just ignore this feature and avoid configuring an |
| | | authorization or authentication policy and using ACLs. You can build |
| | | "Pylons-1.X-style" applications using :mod:`pyramid` that use their own |
| | | "Pylons-1.X-style" applications using :app:`Pyramid` that use their own |
| | | security model via decorators or plain-old-imperative logic in view |
| | | code. |
| | | |
| | | Pyramid Is Too Big |
| | | ------------------ |
| | | |
| | | "The :mod:`pyramid` compressed tarball is almost 2MB. It must be |
| | | "The :app:`Pyramid` compressed tarball is almost 2MB. It must be |
| | | enormous!" |
| | | |
| | | No. We just ship it with test code and helper templates. Here's a |
| | |
| | | |
| | | 539K |
| | | |
| | | The actual :mod:`pyramid` runtime code is about 10% of the total size of the |
| | | The actual :app:`Pyramid` runtime code is about 10% of the total size of the |
| | | tarball omitting docs, helper templates used for package generation, and test |
| | | code. Of the approximately 19K lines of Python code in the package, the code |
| | | that actually has a chance of executing during normal operation, excluding |
| | |
| | | --------------------------------- |
| | | |
| | | This is true. At the time of this writing, the total number of Python |
| | | package distributions that :mod:`pyramid` depends upon transitively |
| | | package distributions that :app:`Pyramid` depends upon transitively |
| | | is 18 if you use Python 2.6 or 2.7, or 16 if you use Python 2.4 or |
| | | 2.5. This is a lot more than zero package distribution dependencies: |
| | | a metric which various Python microframeworks and Django boast. |
| | | |
| | | The :mod:`zope.component` and :mod:`zope.configuration` packages on |
| | | which :mod:`pyramid` depends have transitive dependencies on |
| | | which :app:`Pyramid` depends have transitive dependencies on |
| | | several other packages (:mod:`zope.schema`, :mod:`zope.i18n`, |
| | | :mod:`zope.event`, :mod:`zope.interface`, :mod:`zope.deprecation`, |
| | | :mod:`zope.i18nmessageid`). We've been working with the Zope |
| | |
| | | dependencies, and that much of the functionality of these packages was |
| | | moved into a smaller *number* of packages. |
| | | |
| | | :mod:`pyramid` also has its own direct dependencies, such as :term:`Paste`, |
| | | :app:`Pyramid` also has its own direct dependencies, such as :term:`Paste`, |
| | | :term:`Chameleon`, :term:`Mako` and :term:`WebOb`, and some of these in turn |
| | | have their own transitive dependencies. |
| | | |
| | | It should be noted that :mod:`pyramid` is positively lithe compared |
| | | It should be noted that :app:`Pyramid` is positively lithe compared |
| | | to :term:`Grok`, a different Zope-based framework. As of this |
| | | writing, in its default configuration, Grok has 126 package |
| | | distribution dependencies. The number of dependencies required by |
| | | :mod:`pyramid` is many times fewer than Grok (or Zope itself, upon |
| | | which Grok is based). :mod:`pyramid` has a number of package |
| | | :app:`Pyramid` is many times fewer than Grok (or Zope itself, upon |
| | | which Grok is based). :app:`Pyramid` has a number of package |
| | | distribution dependencies comparable to similarly-targeted frameworks |
| | | such as Pylons 1.X. |
| | | |
| | |
| | | need reinventing), and this comes at the cost of some number of |
| | | dependencies. However, "number of package distributions" is just not |
| | | a terribly great metric to measure complexity. For example, the |
| | | :mod:`zope.event` distribution on which :mod:`pyramid` depends has |
| | | :mod:`zope.event` distribution on which :app:`Pyramid` depends has |
| | | a grand total of four lines of runtime code. As noted above, we're |
| | | continually trying to agitate for a collapsing of these sorts of |
| | | packages into fewer distribution files. |
| | |
| | | -------------------------------- |
| | | |
| | | Complaints have been lodged by other web framework authors at various |
| | | times that :mod:`pyramid` "cheats" to gain performance. One |
| | | times that :app:`Pyramid` "cheats" to gain performance. One |
| | | claimed cheating mechanism is our use (transitively) of the C |
| | | extensions provided by :mod:`zope.interface` to do fast lookups. |
| | | Another claimed cheating mechanism is the religious avoidance of |
| | | extraneous function calls. |
| | | |
| | | If there's such a thing as cheating to get better performance, we want |
| | | to cheat as much as possible. We optimize :mod:`pyramid` |
| | | to cheat as much as possible. We optimize :app:`Pyramid` |
| | | aggressively. This comes at a cost: the core code has sections that |
| | | could be expressed more readably. As an amelioration, we've commented |
| | | these sections liberally. |
| | |
| | | Pyramid Gets Its Terminology Wrong ("MVC") |
| | | ------------------------------------------ |
| | | |
| | | "I'm a MVC web framework user, and I'm confused. :mod:`pyramid` |
| | | "I'm a MVC web framework user, and I'm confused. :app:`Pyramid` |
| | | calls the controller a view! And it doesn't have any controllers." |
| | | |
| | | If you are in this camp, you might have come to expect things about how your |
| | | existing "MVC" framework uses its terminology. For example, you probably |
| | | expect that models are ORM models, controllers are classes that have methods |
| | | that map to URLs, and views are templates. :mod:`pyramid` indeed has each of |
| | | that map to URLs, and views are templates. :app:`Pyramid` indeed has each of |
| | | these concepts, and each probably *works* almost exactly like your existing |
| | | "MVC" web framework. We just don't use the "MVC" terminology, as we can't |
| | | square its usage in the web framework space with historical reality. |
| | |
| | | Pyramid Applications are Extensible; I Don't Believe In Application Extensibility |
| | | --------------------------------------------------------------------------------- |
| | | |
| | | Any :mod:`pyramid` application written obeying certain constraints |
| | | is *extensible*. This feature is discussed in the :mod:`pyramid` |
| | | Any :app:`Pyramid` application written obeying certain constraints |
| | | is *extensible*. This feature is discussed in the :app:`Pyramid` |
| | | documentation chapter named :ref:`extending_chapter`. It is made |
| | | possible by the use of the :term:`Zope Component Architecture` and |
| | | :term:`ZCML` within :mod:`pyramid`. |
| | | :term:`ZCML` within :app:`Pyramid`. |
| | | |
| | | "Extensible", in this context, means: |
| | | |
| | |
| | | often useful to be able to modify an application for a particular |
| | | deployment in a less invasive way. |
| | | |
| | | If you don't want to think about :mod:`pyramid` application |
| | | If you don't want to think about :app:`Pyramid` application |
| | | extensibility at all, you needn't. You can ignore extensibility |
| | | entirely. However, if you follow the set of rules defined in |
| | | :ref:`extending_chapter`, you don't need to *make* your application |
| | |
| | | |
| | | Branching an application and continually merging in order to get new |
| | | features and bugfixes is clearly useful. You can do that with a |
| | | :mod:`pyramid` application just as usefully as you can do it with |
| | | :app:`Pyramid` application just as usefully as you can do it with |
| | | any application. But deployment of an application written in |
| | | :mod:`pyramid` makes it possible to avoid the need for this even if |
| | | :app:`Pyramid` makes it possible to avoid the need for this even if |
| | | the application doesn't define any plugpoints ahead of time. It's |
| | | possible that promoters of competing web frameworks dismiss this |
| | | feature in favor of branching and merging because applications written |
| | | in their framework of choice aren't extensible out of the box in a |
| | | comparably fundamental way. |
| | | |
| | | While :mod:`pyramid` application are fundamentally extensible even |
| | | While :app:`Pyramid` application are fundamentally extensible even |
| | | if you don't write them with specific extensibility in mind, if you're |
| | | moderately adventurous, you can also take it a step further. If you |
| | | learn more about the :term:`Zope Component Architecture`, you can |
| | | optionally use it to expose other more domain-specific configuration |
| | | plugpoints while developing an application. The plugpoints you expose |
| | | needn't be as coarse as the ones provided automatically by |
| | | :mod:`pyramid` itself. For example, you might compose your own |
| | | :app:`Pyramid` itself. For example, you might compose your own |
| | | :term:`ZCML` directive that configures a set of views for a prebaked |
| | | purpose (e.g. ``restview`` or somesuch) , allowing other people to |
| | | refer to that directive when they make declarations in the |
| | |
| | | will need to develop his own similar extensibility system. |
| | | |
| | | Ultimately, any argument about whether the extensibility features lent |
| | | to applications by :mod:`pyramid` are "good" or "bad" is somewhat |
| | | to applications by :app:`Pyramid` are "good" or "bad" is somewhat |
| | | pointless. You needn't take advantage of the extensibility features |
| | | provided by a particular :mod:`pyramid` application in order to |
| | | provided by a particular :app:`Pyramid` application in order to |
| | | affect a modification for a particular set of its deployments. You |
| | | can ignore the application's extensibility plugpoints entirely, and |
| | | instead use version control branching and merging to manage |
| | |
| | | Challenge |
| | | +++++++++ |
| | | |
| | | :mod:`pyramid` performs automatic authorization checks only at |
| | | :app:`Pyramid` performs automatic authorization checks only at |
| | | :term:`view` execution time. Zope 3 wraps context objects with a |
| | | `security proxy <http://wiki.zope.org/zope3/WhatAreSecurityProxies>`, |
| | | which causes Zope 3 to do also security checks during attribute |
| | |
| | | #) I want to also expose my model via a REST API using Twisted Web. If |
| | | Pyramid performed authorization based on attribute access via Zope3's |
| | | security proies, I could enforce my authorization policy in both |
| | | :mod:`pyramid` and in the Twisted-based system the same way. |
| | | :app:`Pyramid` and in the Twisted-based system the same way. |
| | | |
| | | Defense |
| | | +++++++ |
| | | |
| | | :mod:`pyramid` was developed by folks familiar with Zope 2, which |
| | | :app:`Pyramid` was developed by folks familiar with Zope 2, which |
| | | has a "through the web" security model. This "TTW" security model was |
| | | the precursor to Zope 3's security proxies. Over time, as the |
| | | :mod:`pyramid` developers (working in Zope 2) created such sites, |
| | | :app:`Pyramid` developers (working in Zope 2) created such sites, |
| | | we found authorization checks during code interpretation extremely |
| | | useful in a minority of projects. But much of the time, TTW |
| | | authorization checks usually slowed down the development velocity of |
| | |
| | | nature, the only requirement to use one is to make sure you wrap a |
| | | single object in a security proxy and make sure to access that object |
| | | normally when you want proxy security checks to happen. It is |
| | | possible to override the :mod:`pyramid` "traverser" for a given |
| | | possible to override the :app:`Pyramid` "traverser" for a given |
| | | application (see :ref:`changing_the_traverser`). To get Zope3-like |
| | | behavior, it is possible to plug in a different traverser which |
| | | returns Zope3-security-proxy-wrapped objects for each traversed object |
| | |
| | | |
| | | The methods :meth:`pyramid.configuration.Configurator.begin` and |
| | | :meth:`pyramid.configuration.Configurator.end` are used to bracket |
| | | the configuration phase of a :mod:`pyramid` application. |
| | | the configuration phase of a :app:`Pyramid` application. |
| | | |
| | | These exist because existing legacy third party *configuration* (not |
| | | runtime) code relies on a threadlocal stack being populated. The |
| | |
| | | traversal-based applications in which a :term:`context` is always |
| | | very important. A view callable is the primary mechanism by |
| | | which a developer writes user interface code within |
| | | :mod:`pyramid`. See :ref:`views_chapter` for more information |
| | | about :mod:`pyramid` view callables. |
| | | :app:`Pyramid`. See :ref:`views_chapter` for more information |
| | | about :app:`Pyramid` view callables. |
| | | |
| | | view configuration |
| | | View configuration is the act of associating a :term:`view |
| | | callable` with configuration information. This configuration |
| | | information helps map a given :term:`request` to a particular view |
| | | callable and it can influence the response of a view callable. |
| | | :mod:`pyramid` views can be configured via :term:`imperative |
| | | :app:`Pyramid` views can be configured via :term:`imperative |
| | | configuration`, :term:`ZCML` or by a special ``@view_config`` |
| | | decorator coupled with a :term:`scan`. See :ref:`views_chapter` |
| | | for more information about view configuration. |
| | |
| | | :term:`context` of a :term:`view`. If :mod:`url dispatch` is |
| | | used, a single :term:`context` is generated for each request and |
| | | is used as the context of a view: this object is also technically |
| | | a "model" in :mod:`pyramid` terms, although this terminology |
| | | a "model" in :app:`Pyramid` terms, although this terminology |
| | | can be a bit confusing: see :ref:`model_traversal_confusion`. |
| | | |
| | | traversal |
| | | The act of descending "down" a graph of model objects from a root |
| | | model in order to find a :term:`context`. The :mod:`pyramid` |
| | | model in order to find a :term:`context`. The :app:`Pyramid` |
| | | :term:`router` performs traversal of model objects when a |
| | | :term:`root factory` is specified. See the |
| | | :ref:`traversal_chapter` chapter for more information. Traversal |
| | |
| | | |
| | | router |
| | | The :term:`WSGI` application created when you start a |
| | | :mod:`pyramid` application. The router intercepts requests, |
| | | :app:`Pyramid` application. The router intercepts requests, |
| | | invokes traversal and/or URL dispatch, calls view functions, and |
| | | returns responses to the WSGI server on behalf of your |
| | | :mod:`pyramid` application. |
| | | :app:`Pyramid` application. |
| | | |
| | | URL dispatch |
| | | An alternative to graph traversal as a mechanism for locating a |
| | | :term:`context` for a :term:`view`. When you use a :term:`route` |
| | | in your :mod:`pyramid` application via a :term:`route |
| | | in your :app:`Pyramid` application via a :term:`route |
| | | configuration`, you are using URL dispatch. See the |
| | | :ref:`urldispatch_chapter` for more information. |
| | | |
| | |
| | | |
| | | application registry |
| | | A registry of configuration information consulted by |
| | | :mod:`pyramid` while servicing an application. An application |
| | | :app:`Pyramid` while servicing an application. An application |
| | | registry maps model types to views, as well as housing other |
| | | application-specific component registrations. Every |
| | | :mod:`pyramid` application has one (and only one) application |
| | | :app:`Pyramid` application has one (and only one) application |
| | | registry. |
| | | |
| | | template |
| | |
| | | authentication |
| | | The act of determining that the credentials a user presents |
| | | during a particular request are "good". Authentication in |
| | | :mod:`pyramid` is performed via an :term:`authentication |
| | | :app:`Pyramid` is performed via an :term:`authentication |
| | | policy`. |
| | | |
| | | authorization |
| | |
| | | action. In pyramid terms, this means determining whether, for a |
| | | given context, any :term:`principal` (or principals) associated |
| | | with the request have the requisite :term:`permission` to allow |
| | | the request to continue. Authorization in :mod:`pyramid` is |
| | | the request to continue. Authorization in :app:`Pyramid` is |
| | | performed via its :term:`authorization policy`. |
| | | |
| | | principal |
| | |
| | | "group foo" and "group bar". |
| | | |
| | | authorization policy |
| | | An authorization policy in :mod:`pyramid` terms is a bit of |
| | | An authorization policy in :app:`Pyramid` terms is a bit of |
| | | code which has an API which determines whether or not the |
| | | principals associated with the request can perform an action |
| | | associated with a permission, based on the information found on the |
| | | :term:`context`. |
| | | |
| | | authentication policy |
| | | An authentication policy in :mod:`pyramid` terms is a bit of |
| | | An authentication policy in :app:`Pyramid` terms is a bit of |
| | | code which has an API which determines the current |
| | | :term:`principal` (or principals) associated with a request. |
| | | |
| | |
| | | |
| | | PasteDeploy |
| | | `PasteDeploy <http://pythonpaste.org>`_ is a library used by |
| | | :mod:`pyramid` which makes it possible to configure |
| | | :app:`Pyramid` which makes it possible to configure |
| | | :term:`WSGI` components together declaratively within an ``.ini`` |
| | | file. It was developed by Ian Bicking as part of :term:`Paste`. |
| | | |
| | |
| | | maintained by Malthe Borch. It has several extensions, such as |
| | | the ability to use bracketed (Genshi-style) ``${name}`` syntax, |
| | | even within ZPT. It is also much faster than the reference |
| | | implementations of both ZPT and Genshi. :mod:`pyramid` offers |
| | | implementations of both ZPT and Genshi. :app:`Pyramid` offers |
| | | Chameleon templating out of the box in ZPT and text flavors. |
| | | |
| | | ZPT |
| | |
| | | Routes |
| | | A `system by Ben Bangert <http://routes.groovie.org/>`_ which |
| | | parses URLs and compares them against a number of user defined |
| | | mappings. The URL pattern matching syntax in :mod:`pyramid` is |
| | | mappings. The URL pattern matching syntax in :app:`Pyramid` is |
| | | inspired by the Routes syntax (which was inspired by Ruby On |
| | | Rails pattern syntax). |
| | | |
| | |
| | | ZCML |
| | | `Zope Configuration Markup Language |
| | | <http://www.muthukadan.net/docs/zca.html#zcml>`_, an XML dialect |
| | | used by Zope and :mod:`pyramid` for configuration tasks. ZCML |
| | | used by Zope and :app:`Pyramid` for configuration tasks. ZCML |
| | | is capable of performing different types of :term:`configuration |
| | | declaration`, but its primary purpose in :mod:`pyramid` is to |
| | | declaration`, but its primary purpose in :app:`Pyramid` is to |
| | | perform :term:`view configuration` and :term:`route configuration` |
| | | within the ``configure.zcml`` file in a :mod:`pyramid` |
| | | within the ``configure.zcml`` file in a :app:`Pyramid` |
| | | application. You can use ZCML as an alternative to |
| | | :term:`imperative configuration`. |
| | | |
| | |
| | | <http://www.muthukadan.net/docs/zca.html>`_ (aka ZCA) is a system |
| | | which allows for application pluggability and complex dispatching |
| | | based on objects which implement an :term:`interface`. |
| | | :mod:`pyramid` uses the ZCA "under the hood" to perform view |
| | | :app:`Pyramid` uses the ZCA "under the hood" to perform view |
| | | dispatching and other application configuration tasks. |
| | | |
| | | reStructuredText |
| | |
| | | |
| | | root |
| | | The object at which :term:`traversal` begins when |
| | | :mod:`pyramid` searches for a :term:`context` (for :term:`URL |
| | | :app:`Pyramid` searches for a :term:`context` (for :term:`URL |
| | | Dispatch`, the root is *always* the context). |
| | | |
| | | subpath |
| | |
| | | |
| | | interface |
| | | A `Zope interface <http://pypi.python.org/pypi/zope.interface>`_ |
| | | object. In :mod:`pyramid`, an interface may be attached to a |
| | | object. In :app:`Pyramid`, an interface may be attached to a |
| | | :term:`model` object or a :term:`request` object in order to |
| | | identify that the object is "of a type". Interfaces are used |
| | | internally by :mod:`pyramid` to perform view lookups and other |
| | | internally by :app:`Pyramid` to perform view lookups and other |
| | | policy lookups. The ability to make use of an interface is |
| | | exposed to an application programmers during :term:`view |
| | | configuration` via the ``context`` argument, the ``request_type`` |
| | | argument and the ``containment`` argument. Interfaces are also |
| | | exposed to application developers when they make use of the |
| | | :term:`event` system. Fundamentally, :mod:`pyramid` |
| | | :term:`event` system. Fundamentally, :app:`Pyramid` |
| | | programmers can think of an interface as something that they can |
| | | attach to an object that stamps it with a "type" unrelated to its |
| | | underlying Python type. Interfaces can also be used to describe |
| | | the behavior of an object (its methods and attributes), but |
| | | unless they choose to, :mod:`pyramid` programmers do not need |
| | | unless they choose to, :app:`Pyramid` programmers do not need |
| | | to understand or use this feature of interfaces. |
| | | |
| | | event |
| | | An object broadcast to zero or more :term:`subscriber` callables |
| | | during normal :mod:`pyramid` system operations during the |
| | | during normal :app:`Pyramid` system operations during the |
| | | lifetime of an application. Application code can subscribe to |
| | | these events by using the subscriber functionality described in |
| | | :ref:`events_chapter`. |
| | |
| | | request type |
| | | An attribute of a :term:`request` that allows for specialization |
| | | of view invocation based on arbitrary categorization. The every |
| | | :term:`request` object that :mod:`pyramid` generates and |
| | | :term:`request` object that :app:`Pyramid` generates and |
| | | manipulates has one or more :term:`interface` objects attached to |
| | | it. The default interface attached to a request object is |
| | | ``pyramid.interfaces.IRequest``. |
| | |
| | | repoze.lemonade |
| | | Zope2 CMF-like `data structures and helper facilities |
| | | <http://docs.repoze.org/lemonade>`_ for CA-and-ZODB-based |
| | | applications useful within :mod:`pyramid` applications. |
| | | applications useful within :app:`Pyramid` applications. |
| | | |
| | | repoze.catalog |
| | | An indexing and search facility (fielded and full-text) based on |
| | | `zope.index <http://pypi.python.org/pypi/zope.index>`_. See `the |
| | | documentation <http://docs.repoze.org/catalog>`_ for more |
| | | information. A tutorial for its usage in :mod:`pyramid` |
| | | information. A tutorial for its usage in :app:`Pyramid` |
| | | exists in :ref:`catalog_tutorial`. |
| | | |
| | | repoze.who |
| | | `Authentication middleware <http://docs.repoze.org/who>`_ for |
| | | :term:`WSGI` applications. It can be used by :mod:`pyramid` to |
| | | :term:`WSGI` applications. It can be used by :app:`Pyramid` to |
| | | provide authentication information. |
| | | |
| | | repoze.workflow |
| | | `Barebones workflow for Python apps |
| | | <http://docs.repoze.org/workflow>`_ . It can be used by |
| | | :mod:`pyramid` to form a workflow system. |
| | | :app:`Pyramid` to form a workflow system. |
| | | |
| | | virtual root |
| | | A model object representing the "virtual" root of a request; this |
| | |
| | | object in a lineage is available as its ``__parent__`` attribute. |
| | | |
| | | root factory |
| | | The "root factory" of an :mod:`pyramid` application is called |
| | | The "root factory" of an :app:`Pyramid` application is called |
| | | on every request sent to the application. The root factory |
| | | returns the traversal root of an application. It is |
| | | conventionally named ``get_root``. An application may supply a |
| | | root factory to :mod:`pyramid` during the construction of a |
| | | root factory to :app:`Pyramid` during the construction of a |
| | | :term:`Configurator`. If a root factory is not supplied, the |
| | | application uses a default root object. Use of the default root |
| | | object is useful in application which use :term:`URL dispatch` for |
| | |
| | | `mod_wsgi <http://code.google.com/p/modwsgi/>`_ is an Apache |
| | | module developed by Graham Dumpleton. It allows :term:`WSGI` |
| | | applications (such as applications developed using |
| | | :mod:`pyramid`) to be served using the Apache web server. |
| | | :app:`Pyramid`) to be served using the Apache web server. |
| | | |
| | | view predicate |
| | | An argument to a :term:`view configuration` which evaluates to |
| | |
| | | |
| | | predicate |
| | | A test which returns ``True`` or ``False``. Two different types |
| | | of predicates exist in :mod:`pyramid`: a :term:`view predicate` |
| | | of predicates exist in :app:`Pyramid`: a :term:`view predicate` |
| | | and a :term:`route predicate`. View predicates are attached to |
| | | :term:`view configuration` and route predicates are attached to |
| | | :term:`route configuration`. |
| | |
| | | decorator |
| | | A wrapper around a Python function or class which accepts the |
| | | function or class as its first argument and which returns an |
| | | arbitrary object. :mod:`pyramid` provides several decorators, |
| | | arbitrary object. :app:`Pyramid` provides several decorators, |
| | | used for configuration and return value modification purposes. See |
| | | also `PEP 318 <http://www.python.org/dev/peps/pep-0318/>`_. |
| | | |
| | | configuration declaration |
| | | An individual method call made to an instance of a |
| | | :mod:`pyramid` :term:`Configurator` object which performs an |
| | | :app:`Pyramid` :term:`Configurator` object which performs an |
| | | arbitrary action, such as registering a :term:`view configuration` |
| | | (via the ``view`` method of the configurator) or :term:`route |
| | | configuration` (via the ``route`` method of the configurator). A |
| | |
| | | ``@view_config``. |
| | | |
| | | scan |
| | | The term used by :mod:`pyramid` to define the process of |
| | | The term used by :app:`Pyramid` to define the process of |
| | | importing and examining all code in a Python package or module for |
| | | :term:`configuration decoration`. |
| | | |
| | |
| | | a set of :term:`configuration declaration` statements. |
| | | |
| | | Not Found view |
| | | An :term:`exception view` invoked by :mod:`pyramid` when the |
| | | An :term:`exception view` invoked by :app:`Pyramid` when the |
| | | developer explicitly raises a ``pyramid.exceptions.NotFound`` |
| | | exception from within :term:`view` code or :term:`root factory` |
| | | code, or when the current request doesn't match any :term:`view |
| | | configuration`. :mod:`pyramid` provides a default |
| | | configuration`. :app:`Pyramid` provides a default |
| | | implementation of a not found view; it can be overridden. See |
| | | :ref:`changing_the_notfound_view`. |
| | | |
| | | Forbidden view |
| | | An :term:`exception view` invoked by :mod:`pyramid` when the |
| | | An :term:`exception view` invoked by :app:`Pyramid` when the |
| | | developer explicitly raises a |
| | | ``pyramid.exceptions.Forbidden`` exception from within |
| | | :term:`view` code or :term:`root factory` code, or when the |
| | | :term:`view configuration` and :term:`authorization policy` |
| | | found for a request disallows a particular view invocation. |
| | | :mod:`pyramid` provides a default implementation of a |
| | | :app:`Pyramid` provides a default implementation of a |
| | | forbidden view; it can be overridden. See |
| | | :ref:`changing_the_forbidden_view`. |
| | | |
| | | Exception view |
| | | An exception view is a :term:`view callable` which may be |
| | | invoked by :mod:`pyramid` when an exception is raised during |
| | | invoked by :app:`Pyramid` when an exception is raised during |
| | | request processing. See :ref:`exception_views` for more |
| | | information. |
| | | |
| | |
| | | each `thread |
| | | <http://en.wikipedia.org/wiki/Thread_(computer_science)>` used by |
| | | the application may have a different value for this same "global" |
| | | variable. :mod:`pyramid` uses a small number of thread local |
| | | variable. :app:`Pyramid` uses a small number of thread local |
| | | variables, as described in :ref:`threadlocals_chapter`. See also |
| | | the `threading.local documentation |
| | | <http://docs.python.org/library/threading.html#threading.local>` |
| | |
| | | |
| | | Python |
| | | The `programming language <http://python.org>` in which |
| | | :mod:`pyramid` is written. |
| | | :app:`Pyramid` is written. |
| | | |
| | | CPython |
| | | The C implementation of the Python language. This is the |
| | |
| | | The act of locating a :term:`context` and a :term:`view name` |
| | | given a :term:`request`. :term:`Traversal` and :term:`URL |
| | | dispatch` are the context finding subsystems used by |
| | | :mod:`pyramid`. |
| | | :app:`Pyramid`. |
| | | |
| | | Triad |
| | | The three bits of information used by :term:`view lookup` to find |
| | |
| | | Google App Engine |
| | | `Google App Engine <http://code.google.com/appengine/>`_ (aka |
| | | "GAE") is a Python application hosting service offered by Google. |
| | | :mod:`pyramid` runs on GAE. |
| | | :app:`Pyramid` runs on GAE. |
| | | |
| | | Venusian |
| | | `Venusian <http://docs.repoze.org/venusian>`_ is a library which |
| | | allows framework authors to defer decorator actions. Instead of |
| | | taking actions when a function (or class) decorator is executed |
| | | at import time, the action usually taken by the decorator is |
| | | deferred until a separate "scan" phase. :mod:`pyramid` relies |
| | | deferred until a separate "scan" phase. :app:`Pyramid` relies |
| | | on Venusian to provide a basis for its :term:`scan` feature. |
| | | |
| | | Translation String |
| | |
| | | A callable which receives a :term:`translation string` and |
| | | returns a translated Unicode object for the purposes of |
| | | internationalization. A :term:`localizer` supplies a |
| | | translator to a :mod:`pyramid` application accessible via its |
| | | translator to a :app:`Pyramid` application accessible via its |
| | | ``translate`` method. |
| | | |
| | | Translation Directory |
| | |
| | | |
| | | Gettext |
| | | The GNU `gettext <http://www.gnu.org/software/gettext/>`_ |
| | | library, used by the :mod:`pyramid` translation machinery. |
| | | library, used by the :app:`Pyramid` translation machinery. |
| | | |
| | | Babel |
| | | A `collection of tools <http://babel.edgewall.org/>`_ for |
| | | internationalizing Python applications. :mod:`pyramid` does |
| | | internationalizing Python applications. :app:`Pyramid` does |
| | | not depend on Babel to operate, but if Babel is installed, |
| | | additional locale functionality becomes available to your |
| | | application. |
| | |
| | | The pyramid Web Application Development Framework |
| | | ================================================= |
| | | |
| | | :mod:`pyramid` is a small, fast, down-to-earth Python web application |
| | | :app:`Pyramid` is a small, fast, down-to-earth Python web application |
| | | development framework. It is developed as part of the `Pylons Project |
| | | <http://docs.pylonshq.com/>`_. It is licensed under a `BSD-like license |
| | | <http://repoze.org/license.html>`_. |
| | |
| | | ======================= |
| | | |
| | | Narrative documentation in chapter form explaining how to use |
| | | :mod:`pyramid`. |
| | | :app:`Pyramid`. |
| | | |
| | | .. toctree:: |
| | | :maxdepth: 2 |
| | |
| | | Tutorials |
| | | ========= |
| | | |
| | | Detailed tutorials explaining how to use :mod:`pyramid` to build |
| | | various types of applications and how to deploy :mod:`pyramid` |
| | | Detailed tutorials explaining how to use :app:`Pyramid` to build |
| | | various types of applications and how to deploy :app:`Pyramid` |
| | | applications to various platforms. |
| | | |
| | | .. toctree:: |
| | |
| | | ================== |
| | | |
| | | Reference material includes API documentation and documentation of |
| | | every :mod:`pyramid` :term:`ZCML directive`. |
| | | every :app:`Pyramid` :term:`ZCML directive`. |
| | | |
| | | .. toctree:: |
| | | :maxdepth: 2 |
| | |
| | | |
| | | .. warning:: |
| | | |
| | | These applications are for an older version of :mod:`pyramid`, |
| | | These applications are for an older version of :app:`Pyramid`, |
| | | which was named :mod:`repoze.bfg`. We'll be updating them soon to |
| | | use :mod:`pyramid`. |
| | | use :app:`Pyramid`. |
| | | |
| | | `repoze.cluegun <http://svn.repoze.org/repoze.cluegun/trunk/>`_ is a |
| | | simple pastebin application based on Rocky Burt's `ClueBin |
| | |
| | | ======================= |
| | | |
| | | The `Pylons Project web site <http://docs.pylonshq.com/>`_ is the main online |
| | | source of :mod:`pyramid` support and development information. |
| | | source of :app:`Pyramid` support and development information. |
| | | |
| | | To report bugs, use the `issue tracker |
| | | <http://github.com/Pylons/pyramid/issues>`_. |
| | |
| | | <http://groups.google.com/group/pylons-devel>`_ or join the `#pylons |
| | | IRC channel <irc://irc.freenode.net/#pylons>`_. |
| | | |
| | | Browse and check out tagged and trunk versions of :mod:`pyramid` via |
| | | Browse and check out tagged and trunk versions of :app:`Pyramid` via |
| | | the `Pyramid GitHub repository <http://github.com/Pylons/pyramid/>`_. |
| | | To check out the trunk via ``git``, use this command:: |
| | | |
| | | git clone git@github.com:Pylons/pyramid.git |
| | | |
| | | To find out how to become a contributor to :mod:`pyramid`, please see |
| | | To find out how to become a contributor to :app:`Pyramid`, please see |
| | | the `contributor's page <http://repoze.org/contributing.html>`_. |
| | | |
| | | Index and Glossary |
| | |
| | | .. _latexindex: |
| | | |
| | | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| | | The :mod:`pyramid` Web Application Framework |
| | | The :app:`Pyramid` Web Application Framework |
| | | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
| | | |
| | | .. frontmatter:: |
| | |
| | | Application Configuration |
| | | ========================= |
| | | |
| | | Each deployment of an application written using :mod:`pyramid` implies a |
| | | Each deployment of an application written using :app:`Pyramid` implies a |
| | | specific *configuration* of the framework itself. For example, an |
| | | application which serves up MP3s for user consumption might plug code into |
| | | the framework that manages songs, while an application that manages corporate |
| | | data might plug in code that manages accounting information. :mod:`pyramid` |
| | | data might plug in code that manages accounting information. :app:`Pyramid` |
| | | refers to the way in which code is plugged in to it for a specific |
| | | application as "configuration". |
| | | |
| | | Most people understand "configuration" as coarse settings that inform the |
| | | high-level operation of a specific application deployment. For instance, |
| | | it's easy to think of the values implied by a ``.ini`` file parsed at |
| | | application startup time as "configuration". :mod:`pyramid` extends this |
| | | application startup time as "configuration". :app:`Pyramid` extends this |
| | | pattern to application development, using the term "configuration" to express |
| | | standardized ways that code gets plugged into a deployment of the framework |
| | | itself. When you plug code into the :mod:`pyramid` framework, you are |
| | | "configuring" :mod:`pyramid` for the purpose of creating a particular |
| | | itself. When you plug code into the :app:`Pyramid` framework, you are |
| | | "configuring" :app:`Pyramid` for the purpose of creating a particular |
| | | application deployment. |
| | | |
| | | .. index:: |
| | |
| | | Imperative Configuration |
| | | ------------------------ |
| | | |
| | | Here's one of the simplest :mod:`pyramid` applications, configured |
| | | Here's one of the simplest :app:`Pyramid` applications, configured |
| | | imperatively: |
| | | |
| | | .. code-block:: python |
| | |
| | | configuration done in imperative code, because you may need to have two files |
| | | open at once to see the "big picture": the file that represents the |
| | | configuration, and the file that contains the implementation objects |
| | | referenced by the configuration. To avoid this, :mod:`pyramid` allows you to |
| | | referenced by the configuration. To avoid this, :app:`Pyramid` allows you to |
| | | insert :term:`configuration decoration` statements very close to code that is |
| | | referred to by the declaration itself. For example: |
| | | |
| | |
| | | |
| | | The mere existence of configuration decoration doesn't cause any |
| | | configuration registration to be made. Before they have any effect on |
| | | the configuration of a :mod:`pyramid` application, a configuration |
| | | the configuration of a :app:`Pyramid` application, a configuration |
| | | decoration within application code must be found through a process |
| | | known as a :term:`scan`. |
| | | |
| | |
| | | attribute to the ``hello`` function, making it available for a |
| | | :term:`scan` to find it later. |
| | | |
| | | :mod:`pyramid` is willing to :term:`scan` a module or a package and |
| | | :app:`Pyramid` is willing to :term:`scan` a module or a package and |
| | | its subpackages for decorations when the |
| | | :meth:`pyramid.configuration.Configurator.scan` method is invoked: |
| | | scanning implies searching for configuration declarations in a package |
| | |
| | | ------------------------- |
| | | |
| | | A third mode of configuration can be employed when you create a |
| | | :mod:`pyramid` application named *declarative configuration*. This mode uses |
| | | :app:`Pyramid` application named *declarative configuration*. This mode uses |
| | | :term:`ZCML` to represent configuration statements rather than Python. ZCML |
| | | is often used when application extensibility is important. Most of the |
| | | examples in the narrative portion of this documentation concentrate on |
| | |
| | | the application developer based on parameters present in the |
| | | :term:`request`. |
| | | |
| | | :mod:`pyramid` uses two separate but cooperating subsystems to find |
| | | :app:`Pyramid` uses two separate but cooperating subsystems to find |
| | | and invoke code written by the application developer: :term:`context |
| | | finding` and :term:`view lookup`. |
| | | |
| | | - A :mod:`pyramid` :term:`context finding` subsystem is given a |
| | | - A :app:`Pyramid` :term:`context finding` subsystem is given a |
| | | :term:`request`; it is responsible for finding a :term:`context` |
| | | object and a :term:`view name` based on information present in the |
| | | request. |
| | | |
| | | - Using the context and view name provided by :term:`context finding`, |
| | | the :mod:`pyramid` :term:`view lookup` subsystem is provided with |
| | | the :app:`Pyramid` :term:`view lookup` subsystem is provided with |
| | | a :term:`request`, a :term:`context` and a :term:`view name`. It is |
| | | then responsible for finding and invoking a :term:`view callable`. |
| | | A view callable is a specific bit of code written and registered by |
| | | the application developer which receives the :term:`request` and |
| | | which returns a :term:`response`. |
| | | |
| | | These two subsystems are used by :mod:`pyramid` serially: |
| | | These two subsystems are used by :app:`Pyramid` serially: |
| | | first, a :term:`context finding` subsystem does its job. Then the |
| | | result of context finding is passed to the :term:`view lookup` |
| | | subsystem. The view lookup system finds a :term:`view callable` |
| | |
| | | |
| | | .. sidebar:: What Good is A Context Finding Subsystem? |
| | | |
| | | The :term:`URL dispatch` mode of :mod:`pyramid` as well as many |
| | | The :term:`URL dispatch` mode of :app:`Pyramid` as well as many |
| | | other web frameworks such as :term:`Pylons` or :term:`Django` |
| | | actually collapse the two steps of context finding and view lookup |
| | | into a single step. In these systems, a URL can map *directly* to |
| | |
| | | that do not provide a notion of a context. |
| | | |
| | | There are two separate :term:`context finding` subsystems in |
| | | :mod:`pyramid`: :term:`traversal` and :term:`URL dispatch`. The |
| | | :app:`Pyramid`: :term:`traversal` and :term:`URL dispatch`. The |
| | | subsystems are documented within this chapter. They can be used |
| | | separately or they can be combined. Three chapters which follow |
| | | describe :term:`context finding`: :ref:`traversal_chapter`, |
| | | :ref:`urldispatch_chapter` and :ref:`hybrid_chapter`. |
| | | |
| | | There is only one :term:`view lookup` subsystem present in |
| | | :mod:`pyramid`. Where appropriate, within this chapter, we |
| | | :app:`Pyramid`. Where appropriate, within this chapter, we |
| | | describe how view lookup interacts with context finding. One chapter |
| | | which follows describes :term:`view lookup`: :ref:`views_chapter`. |
| | | |
| | |
| | | hierarchical data store, using traversal can provide significant |
| | | advantages over using URL-based dispatch. |
| | | |
| | | Since :mod:`pyramid` provides support for both approaches, you can |
| | | Since :app:`Pyramid` provides support for both approaches, you can |
| | | use either exclusively or combine them as you see fit. |
| | | |
| | |
| | | the framework; it's "imperative" because you express the configuration |
| | | directly in Python code, and you have the full power of Python at your |
| | | disposal as you issue configuration statements. However, another mode of |
| | | configuration exists within :mod:`pyramid`, which often provides better |
| | | configuration exists within :app:`Pyramid`, which often provides better |
| | | extensibility and configuration conflict detection. |
| | | |
| | | A complete listing of ZCML directives is available within |
| | |
| | | Declarative Configuration |
| | | ------------------------- |
| | | |
| | | A :mod:`pyramid` application can be configured "declaratively", if so |
| | | A :app:`Pyramid` application can be configured "declaratively", if so |
| | | desired. Declarative configuration relies on *declarations* made external to |
| | | the code in a configuration file format named :term:`ZCML` (Zope |
| | | Configuration Markup Language), an XML dialect. |
| | | |
| | | A :mod:`pyramid` application configured declaratively requires not |
| | | A :app:`Pyramid` application configured declaratively requires not |
| | | one, but two files: a Python file and a :term:`ZCML` file. |
| | | |
| | | In a file named ``helloworld.py``: |
| | |
| | | :meth:`pyramid.configuration.Configurator.add_view` method on your |
| | | behalf. |
| | | |
| | | The ``<view>`` tag is an example of a :mod:`pyramid` declaration |
| | | The ``<view>`` tag is an example of a :app:`Pyramid` declaration |
| | | tag. Other such tags include ``<route>`` and ``<scan>``. Each of |
| | | these tags is effectively a "macro" which calls methods of a |
| | | :class:`pyramid.configuration.Configurator` object on your behalf. |
| | |
| | | ---------------------------------------- |
| | | |
| | | Another almost entirely equivalent mode of application configuration |
| | | exists named *declarative* configuration. :mod:`pyramid` can be |
| | | exists named *declarative* configuration. :app:`Pyramid` can be |
| | | configured for the same "hello world" application "declaratively", if |
| | | so desired. |
| | | |
| | |
| | | </configure> |
| | | |
| | | Because :term:`ZCML` is XML, and because XML requires a single root |
| | | tag for each document, every ZCML file used by :mod:`pyramid` must |
| | | tag for each document, every ZCML file used by :app:`Pyramid` must |
| | | contain a ``configure`` container directive, which acts as the root |
| | | XML tag. It is a "container" directive because its only job is to |
| | | contain other directives. |
| | |
| | | |
| | | <include package="pyramid.includes" /> |
| | | |
| | | This self-closing tag instructs :mod:`pyramid` to load a ZCML file |
| | | This self-closing tag instructs :app:`Pyramid` to load a ZCML file |
| | | from the Python package with the :term:`dotted Python name` |
| | | ``pyramid.includes``, as specified by its ``package`` attribute. |
| | | This particular ``<include>`` declaration is required because it |
| | |
| | | view="helloworld.goodbye_world" |
| | | /> |
| | | |
| | | These ``<view>`` declaration tags direct :mod:`pyramid` to create |
| | | These ``<view>`` declaration tags direct :app:`Pyramid` to create |
| | | two :term:`view configuration` registrations. The first ``<view>`` |
| | | tag has an attribute (the attribute is also named ``view``), which |
| | | points at a :term:`dotted Python name`, referencing the |
| | |
| | | view="helloworld.hello_world" |
| | | /> |
| | | |
| | | We've now configured a :mod:`pyramid` helloworld application |
| | | We've now configured a :app:`Pyramid` helloworld application |
| | | declaratively. More information about this mode of configuration is |
| | | available in :ref:`declarative_configuration` and within |
| | | :ref:`zcml_reference`. |
| | |
| | | via ZCML and scanning can be used to configure any application. They |
| | | are not mutually exclusive. |
| | | |
| | | The :mod:`pyramid` authors often recommend using mostly declarative |
| | | The :app:`Pyramid` authors often recommend using mostly declarative |
| | | configuration, because it's the more traditional form of configuration |
| | | used in :mod:`pyramid` applications, it can be overridden and |
| | | used in :app:`Pyramid` applications, it can be overridden and |
| | | extended by third party deployers, and there are more examples for it |
| | | "in the wild". |
| | | |
| | |
| | | name="hello.html" |
| | | /> |
| | | |
| | | This indicates that when :mod:`pyramid` identifies that the |
| | | This indicates that when :app:`Pyramid` identifies that the |
| | | :term:`view name` is ``hello.html`` and the context is of any type, |
| | | the ``.views.hello_world`` view callable will be invoked. |
| | | |
| | |
| | | |
| | | Here's an example of a ``static`` ZCML directive that will serve files |
| | | up under the ``/static`` URL from the ``/var/www/static`` directory of |
| | | the computer which runs the :mod:`pyramid` application using an |
| | | the computer which runs the :app:`Pyramid` application using an |
| | | absolute path. |
| | | |
| | | .. code-block:: xml |
| | |
| | | :class:`pyramid.authorization.ACLAuthorizationPolicy` to be |
| | | injected as the :term:`authorization policy` used by this application. |
| | | |
| | | :mod:`pyramid` ships with a number of authorization and |
| | | :app:`Pyramid` ships with a number of authorization and |
| | | authentication policy ZCML directives that should prove useful. See |
| | | :ref:`authentication_policies_directives_section` and |
| | | :ref:`authorization_policies_directives_section` for more information. |
| | |
| | | ---------------------------------------------- |
| | | |
| | | Instead of configuring an authentication policy and authorization |
| | | policy imperatively, :mod:`pyramid` ships with a few "pre-chewed" |
| | | policy imperatively, :app:`Pyramid` ships with a few "pre-chewed" |
| | | authentication policy ZCML directives that you can make use of within |
| | | your application. |
| | | |
| | |
| | | Adding and Overriding Renderers via ZCML |
| | | ---------------------------------------- |
| | | |
| | | New templating systems and serializers can be associated with :mod:`pyramid` |
| | | New templating systems and serializers can be associated with :app:`Pyramid` |
| | | renderer names. To this end, configuration declarations can be made which |
| | | override an existing :term:`renderer factory` and which add a new renderer |
| | | factory. |
| | |
| | | name=".zpt" |
| | | factory="pyramid.chameleon_zpt.renderer_factory"/> |
| | | |
| | | After you do this, :mod:`pyramid` will treat templates ending in |
| | | After you do this, :app:`Pyramid` will treat templates ending in |
| | | both the ``.pt`` and ``.zpt`` filename extensions as Chameleon ZPT |
| | | templates. |
| | | |
| | |
| | | Environment Variables and ``.ini`` File Settings |
| | | ================================================ |
| | | |
| | | :mod:`pyramid` behavior can be configured through a combination of |
| | | :app:`Pyramid` behavior can be configured through a combination of |
| | | operating system environment variables and ``.ini`` configuration file |
| | | application section settings. The meaning of the environment |
| | | variables and the configuration file settings overlap. |
| | |
| | | The term "configuration file setting name" refers to a key in the |
| | | ``.ini`` configuration for your application. The configuration file |
| | | setting names documented in this chapter are reserved for |
| | | :mod:`pyramid` use. You should not use them to indicate |
| | | :app:`Pyramid` use. You should not use them to indicate |
| | | application-specific configuration settings. |
| | | |
| | | Reloading Templates |
| | |
| | | |
| | | Let's presume your configuration file is named ``MyProject.ini``, and |
| | | there is a section representing your application named ``[app:main]`` |
| | | within the file that represents your :mod:`pyramid` application. |
| | | within the file that represents your :app:`Pyramid` application. |
| | | The configuration file settings documented in the above "Config File |
| | | Setting Name" column would go in the ``[app:main]`` section. Here's |
| | | an example of such a section: |
| | |
| | | |
| | | You can also use environment variables to accomplish the same purpose |
| | | for settings documented as such. For example, you might start your |
| | | :mod:`pyramid` application using the following command line: |
| | | :app:`Pyramid` application using the following command line: |
| | | |
| | | .. code-block:: python |
| | | |
| | | $ BFG_DEBUG_AUTHORIZATION=1 BFG_RELOAD_TEMPLATES=1 bin/paster serve \ |
| | | MyProject.ini |
| | | |
| | | If you started your application this way, your :mod:`pyramid` |
| | | If you started your application this way, your :app:`Pyramid` |
| | | application would behave in the same manner as if you had placed the |
| | | respective settings in the ``[app:main]`` section of your |
| | | application's ``.ini`` file. |
| | |
| | | |
| | | The difference between ``reload_resources`` and ``reload_templates`` |
| | | is a bit subtle. Templates are themselves also treated by |
| | | :mod:`pyramid` as :term:`pkg_resources` resource files (along with |
| | | :app:`Pyramid` as :term:`pkg_resources` resource files (along with |
| | | static files and other resources), so the distinction can be |
| | | confusing. It's helpful to read :ref:`overriding_resources_section` |
| | | for some context about resources in general. |
| | | |
| | | When ``reload_templates`` is true, :mod:`pyramid` takes advantage |
| | | When ``reload_templates`` is true, :app:`Pyramid` takes advantage |
| | | of the underlying templating systems' ability to check for file |
| | | modifications to an individual template file. When |
| | | ``reload_templates`` is true but ``reload_resources`` is *not* true, |
| | | the template filename returned by pkg_resources is cached by |
| | | :mod:`pyramid` on the first request. Subsequent requests for the |
| | | :app:`Pyramid` on the first request. Subsequent requests for the |
| | | same template file will return a cached template filename. The |
| | | underlying templating system checks for modifications to this |
| | | particular file for every request. Setting ``reload_templates`` to |
| | | ``True`` doesn't affect performance dramatically (although it should |
| | | still not be used in production because it has some effect). |
| | | |
| | | However, when ``reload_resources`` is true, :mod:`pyramid` will not |
| | | However, when ``reload_resources`` is true, :app:`Pyramid` will not |
| | | cache the template filename, meaning you can see the effect of |
| | | changing the content of an overridden resource directory for templates |
| | | without restarting the server after every change. Subsequent requests |
| | |
| | | Using Events |
| | | ============= |
| | | |
| | | An *event* is an object broadcast by the :mod:`pyramid` framework |
| | | An *event* is an object broadcast by the :app:`Pyramid` framework |
| | | at interesting points during the lifetime of an application. You |
| | | don't need to use events in order to create most :mod:`pyramid` |
| | | don't need to use events in order to create most :app:`Pyramid` |
| | | applications, but they can be useful when you want to perform slightly |
| | | advanced operations. For example, subscribing to an event can allow |
| | | you to run some code as the result of every new request. |
| | | |
| | | Events in :mod:`pyramid` are always broadcast by the framework. |
| | | Events in :app:`Pyramid` are always broadcast by the framework. |
| | | However, they only become useful when you register a *subscriber*. A |
| | | subscriber is a function that accepts a single argument named `event`: |
| | | |
| | |
| | | :ref:`zcml_event_listener`. |
| | | |
| | | Either of the above registration examples implies that every time the |
| | | :mod:`pyramid` framework emits an event object that supplies an |
| | | :app:`Pyramid` framework emits an event object that supplies an |
| | | :class:`pyramid.events.NewRequest` interface, the ``mysubscriber`` function |
| | | will be called with an *event* object. |
| | | |
| | |
| | | the same event type are not guaranteed to be called in any particular |
| | | order relative to each other. |
| | | |
| | | All the concrete :mod:`pyramid` event types are documented in the |
| | | All the concrete :app:`Pyramid` event types are documented in the |
| | | :ref:`events_module` API documentation. |
| | | |
| | | An Example |
| | |
| | | .. _extending_chapter: |
| | | |
| | | Extending An Existing :mod:`pyramid` Application |
| | | Extending An Existing :app:`Pyramid` Application |
| | | =================================================== |
| | | |
| | | If the developer of a :mod:`pyramid` application has obeyed certain |
| | | If the developer of a :app:`Pyramid` application has obeyed certain |
| | | constraints while building that application, a third party should be |
| | | able to change its behavior without needing to modify its source code. |
| | | The behavior of a :mod:`pyramid` application that obeys certain |
| | | The behavior of a :app:`Pyramid` application that obeys certain |
| | | constraints can be *overridden* or *extended* without modification. |
| | | |
| | | .. index:: |
| | |
| | | -------------------------------------------- |
| | | |
| | | There's only one rule you need to obey if you want to build a |
| | | maximally extensible :mod:`pyramid` application: you should not use |
| | | maximally extensible :app:`Pyramid` application: you should not use |
| | | any :term:`configuration decoration` or :term:`imperative |
| | | configuration`. This means the application developer should avoid |
| | | relying on :term:`configuration decoration` meant to be detected via |
| | | a :term:`scan`, and you mustn't configure your :mod:`pyramid` |
| | | a :term:`scan`, and you mustn't configure your :app:`Pyramid` |
| | | application *imperatively* by using any code which configures the |
| | | application through methods of the :term:`Configurator` (except for |
| | | the :meth:`pyramid.configuration.Configurator.load_zcml` method). |
| | |
| | | ~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | The fundamental "plug points" of an application developed using |
| | | :mod:`pyramid` are *routes*, *views*, and *resources*. Routes are |
| | | :app:`Pyramid` are *routes*, *views*, and *resources*. Routes are |
| | | declarations made using the ZCML ``<route>`` directive. Views are |
| | | declarations made using the ZCML ``<view>`` directive (or the |
| | | ``@view_config`` decorator). Resources are files that are accessed by |
| | | :mod:`pyramid` using the :term:`pkg_resources` API such as static |
| | | :app:`Pyramid` using the :term:`pkg_resources` API such as static |
| | | files and templates. |
| | | |
| | | .. index:: |
| | |
| | | Extending an Application Which Possesses Configuration Decorators Or Which Does Configuration Imperatively |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | If you've inherited a :mod:`pyramid` application which uses |
| | | If you've inherited a :app:`Pyramid` application which uses |
| | | :class:`pyramid.view.view_config` decorators or which performs |
| | | configuration imperatively, one of two things may be true: |
| | | |
| | |
| | | something like this: |
| | | |
| | | - Create a new Python package. The easiest way to do this is to |
| | | create a new :mod:`pyramid` application using the "paster" |
| | | create a new :app:`Pyramid` application using the "paster" |
| | | template mechanism. See :ref:`creating_a_project` for more |
| | | information. |
| | | |
| | |
| | | setup.py install``). |
| | | |
| | | - Change the ``configure.zcml`` in the new package to include the |
| | | original :mod:`pyramid` application's ``configure.zcml`` via an |
| | | original :app:`Pyramid` application's ``configure.zcml`` via an |
| | | include statement, e.g. ``<include package="theoriginalapp"/>``. |
| | | Alternately, if the original application writer anticipated |
| | | overriding some things and not others, instead of including the |
| | |
| | | .. _firstapp_chapter: |
| | | |
| | | Creating Your First :mod:`pyramid` Application |
| | | Creating Your First :app:`Pyramid` Application |
| | | ================================================= |
| | | |
| | | We will walk through the creation of a tiny :mod:`pyramid` |
| | | We will walk through the creation of a tiny :app:`Pyramid` |
| | | application in this chapter. After we're finished creating it, we'll |
| | | explain in more detail how the application works. |
| | | |
| | |
| | | Hello World, Goodbye World |
| | | -------------------------- |
| | | |
| | | Here's one of the very simplest :mod:`pyramid` applications, |
| | | Here's one of the very simplest :app:`Pyramid` applications, |
| | | configured imperatively: |
| | | |
| | | .. code-block:: python |
| | |
| | | serve(app, host='0.0.0.0') |
| | | |
| | | When this code is inserted into a Python script named ``helloworld.py`` and |
| | | executed by a Python interpreter which has the :mod:`pyramid` software |
| | | executed by a Python interpreter which has the :app:`Pyramid` software |
| | | installed, an HTTP server is started on TCP port 8080: |
| | | |
| | | .. code-block:: bash |
| | |
| | | |
| | | The script imports the ``Configurator`` class from the |
| | | ``pyramid.configuration`` module. This class is used to configure |
| | | :mod:`pyramid` for a particular application. An instance of this class |
| | | provides methods which help configure various parts of :mod:`pyramid` for a |
| | | :app:`Pyramid` for a particular application. An instance of this class |
| | | provides methods which help configure various parts of :app:`Pyramid` for a |
| | | given application deployment. |
| | | |
| | | The script uses the :class:`pyramid.response.Response` class later in the |
| | | script to create a :term:`response` object. |
| | | |
| | | Like many other Python web frameworks, :mod:`pyramid` uses the :term:`WSGI` |
| | | Like many other Python web frameworks, :app:`Pyramid` uses the :term:`WSGI` |
| | | protocol to connect an application and a web server together. The |
| | | :mod:`paste.httpserver` server is used in this example as a WSGI server for |
| | | convenience, as the ``paste`` package is a dependency of :mod:`pyramid` itself. |
| | | convenience, as the ``paste`` package is a dependency of :app:`Pyramid` itself. |
| | | |
| | | View Callable Declarations |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | |
| | | body ``Goodbye world!``. |
| | | |
| | | Each of these functions is known as a :term:`view callable`. View |
| | | callables in a :mod:`pyramid` application accept a single argument, |
| | | callables in a :app:`Pyramid` application accept a single argument, |
| | | ``request`` and are expected to return a :term:`response` object. A |
| | | view callable doesn't need to be a function; it can be represented via |
| | | another type of object, like a class or an instance, but for our |
| | |
| | | |
| | | A view callable is always called with a :term:`request` object. A |
| | | request object is a representation of an HTTP request sent to |
| | | :mod:`pyramid` via the active :term:`WSGI` server. |
| | | :app:`Pyramid` via the active :term:`WSGI` server. |
| | | |
| | | A view callable is required to return a :term:`response` object because a |
| | | response object has all the information necessary to formulate an actual HTTP |
| | |
| | | The ``config = Configurator()`` line above creates an instance of the |
| | | :class:`pyramid.configuration.Configurator` class. The resulting |
| | | ``config`` object represents an API which the script uses to configure |
| | | this particular :mod:`pyramid` application. Methods called on the |
| | | this particular :app:`Pyramid` application. Methods called on the |
| | | Configurator will cause registrations to be made in a |
| | | :term:`application registry` associated with the application. |
| | | |
| | |
| | | ``add_view`` with a *default* value for the :term:`predicate` |
| | | argument, named ``name``. The ``name`` predicate defaults to a value |
| | | equalling the empty string (``''``). This means that we're |
| | | instructing :mod:`pyramid` to invoke the ``hello_world`` view |
| | | instructing :app:`Pyramid` to invoke the ``hello_world`` view |
| | | callable when the :term:`view name` is the empty string. We'll learn |
| | | in later chapters what a :term:`view name` is, and under which |
| | | circumstances a request will have a view name that is the empty |
| | |
| | | circumstances which would cause the view configuration's callable to |
| | | be invoked. In general, a greater number of predicates supplied along |
| | | with a view configuration will more strictly limit the applicability |
| | | of its associated view callable. When :mod:`pyramid` processes a |
| | | of its associated view callable. When :app:`Pyramid` processes a |
| | | request, however, the view callable with the *most specific* view |
| | | configuration (the view configuration that matches the most specific |
| | | set of predicates) is always invoked. |
| | | |
| | | In this application, :mod:`pyramid` chooses the most specific view |
| | | In this application, :app:`Pyramid` chooses the most specific view |
| | | callable based only on view :term:`predicate` applicability. The |
| | | ordering of calls to |
| | | :meth:`pyramid.configuration.Configurator.add_view` is never very |
| | | important. We can register ``goodbye_world`` first and |
| | | ``hello_world`` second; :mod:`pyramid` will still give us the most |
| | | ``hello_world`` second; :app:`Pyramid` will still give us the most |
| | | specific callable when a request is dispatched to it. |
| | | |
| | | Ending Configuration |
| | |
| | | within this book, however, you can learn more about it by visiting |
| | | `wsgi.org <http://wsgi.org>`_. |
| | | |
| | | The :mod:`pyramid` application object, in particular, is an |
| | | instance of a class representing a :mod:`pyramid` :term:`router`. |
| | | The :app:`Pyramid` application object, in particular, is an |
| | | instance of a class representing a :app:`Pyramid` :term:`router`. |
| | | It has a reference to the :term:`application registry` which resulted |
| | | from method calls to the configurator used to configure it. The |
| | | :term:`router` consults the registry to obey the policy choices made |
| | |
| | | ~~~~~~~~~~ |
| | | |
| | | Our hello world application is one of the simplest possible |
| | | :mod:`pyramid` applications, configured "imperatively". We can see |
| | | :app:`Pyramid` applications, configured "imperatively". We can see |
| | | that it's configured imperatively because the full power of Python is |
| | | available to us as we perform configuration tasks. |
| | | |
| | |
| | | View Handlers |
| | | ============= |
| | | |
| | | Along with normal view callables, :mod:`pyramid` provides the concept of a |
| | | Along with normal view callables, :app:`Pyramid` provides the concept of a |
| | | :term:`view handler`. Using a view handler instead of a plain :term:`view |
| | | callable` makes it unnecessary to call |
| | | :meth:`pyramid.configuration.Configurator.add_route` (and/or |
| | |
| | | :term:`url dispatch`. The concept of a view handler is analogous to a |
| | | "controller" in Pylons 1.0. |
| | | |
| | | The view handler class is initialized by :mod:`pyramid` in the same manner as |
| | | The view handler class is initialized by :app:`Pyramid` in the same manner as |
| | | a view class. Its ``__init__`` is called with a request object (see |
| | | :ref:`class_as_view`) when a request enters the system which corresponds with |
| | | a view handler registration made during configuration. A method of the view |
| | |
| | | Using Hooks |
| | | =========== |
| | | |
| | | "Hooks" can be used to influence the behavior of the :mod:`pyramid` |
| | | "Hooks" can be used to influence the behavior of the :app:`Pyramid` |
| | | framework in various ways. |
| | | |
| | | .. index:: |
| | |
| | | Changing the Not Found View |
| | | --------------------------- |
| | | |
| | | When :mod:`pyramid` can't map a URL to view code, it invokes a |
| | | When :app:`Pyramid` can't map a URL to view code, it invokes a |
| | | :term:`not found view`, which is a :term:`view callable`. A default |
| | | notfound view exists. The default not found view can be overridden |
| | | through application configuration. This override can be done via |
| | |
| | | Changing the Forbidden View |
| | | --------------------------- |
| | | |
| | | When :mod:`pyramid` can't authorize execution of a view based on |
| | | When :app:`Pyramid` can't authorize execution of a view based on |
| | | the :term:`authorization policy` in use, it invokes a :term:`forbidden |
| | | view`. The default forbidden response has a 401 status code and is |
| | | very plain, but the view which generates it can be overridden as |
| | |
| | | Changing the Traverser |
| | | ---------------------- |
| | | |
| | | The default :term:`traversal` algorithm that :mod:`pyramid` uses is |
| | | The default :term:`traversal` algorithm that :app:`Pyramid` uses is |
| | | explained in :ref:`traversal_algorithm`. Though it is rarely |
| | | necessary, this default algorithm can be swapped out selectively for a |
| | | different traversal pattern via configuration. |
| | |
| | | /> |
| | | |
| | | If the above stanza was added to a ``configure.zcml`` file, |
| | | :mod:`pyramid` would use the ``myapp.traversal.Traverser`` only |
| | | :app:`Pyramid` would use the ``myapp.traversal.Traverser`` only |
| | | when the application :term:`root factory` returned an instance of the |
| | | ``myapp.models.MyRoot`` object. Otherwise it would use the default |
| | | :mod:`pyramid` traverser to do traversal. |
| | | :app:`Pyramid` traverser to do traversal. |
| | | |
| | | .. index:: |
| | | single: url generator |
| | |
| | | Changing the Request Factory |
| | | ---------------------------- |
| | | |
| | | Whenever :mod:`pyramid` handles a :term:`WSGI` request, it creates |
| | | Whenever :app:`Pyramid` handles a :term:`WSGI` request, it creates |
| | | a :term:`request` object based on the WSGI environment it has been |
| | | passed. By default, an instance of the |
| | | :class:`pyramid.request.Request` class is created to represent the |
| | | request object. |
| | | |
| | | The class (aka "factory") that :mod:`pyramid` uses to create a |
| | | The class (aka "factory") that :app:`Pyramid` uses to create a |
| | | request object instance can be changed by passing a |
| | | ``request_factory`` argument to the constructor of the |
| | | :term:`configurator`. This argument can be either a callable or a |
| | |
| | | Adding Renderer Globals |
| | | ----------------------- |
| | | |
| | | Whenever :mod:`pyramid` handles a request to perform a rendering |
| | | Whenever :app:`Pyramid` handles a request to perform a rendering |
| | | (after a view with a ``renderer=`` configuration attribute is invoked, |
| | | or when the any of the methods beginning with ``render`` within the |
| | | :mod:`pyramid.renderers` module are called), *renderer globals* can |
| | |
| | | the only values present in the system dictionary passed to every |
| | | renderer. |
| | | |
| | | A callback that :mod:`pyramid` will call every time a renderer is |
| | | A callback that :app:`Pyramid` will call every time a renderer is |
| | | invoked can be added by passing a ``renderer_globals_factory`` |
| | | argument to the constructor of the :term:`configurator`. This |
| | | callback can either be a callable object or a :term:`dotted Python |
| | |
| | | Using Response Callbacks |
| | | ------------------------ |
| | | |
| | | Unlike many other web frameworks, :mod:`pyramid` does not eagerly |
| | | Unlike many other web frameworks, :app:`Pyramid` does not eagerly |
| | | create a global response object. Adding a :term:`response callback` |
| | | allows an application to register an action to be performed against a |
| | | response object once it is created, usually in order to mutate it. |
| | |
| | | (first-to-most-recently-added). All response callbacks are called *after* |
| | | the :class:`pyramid.events.NewResponse` event is sent. Errors raised by |
| | | response callbacks are not handled specially. They will be propagated to the |
| | | caller of the :mod:`pyramid` router application. |
| | | caller of the :app:`Pyramid` router application. |
| | | |
| | | A response callback has a lifetime of a *single* request. If you want a |
| | | response callback to happen as the result of *every* request, you must |
| | |
| | | ------------------------ |
| | | |
| | | A :term:`finished callback` is a function that will be called |
| | | unconditionally by the :mod:`pyramid` :term:`router` at the very |
| | | unconditionally by the :app:`Pyramid` :term:`router` at the very |
| | | end of request processing. A finished callback can be used to perform |
| | | an action at the end of a request unconditionally. |
| | | |
| | |
| | | default value of ``None``. |
| | | |
| | | Errors raised by finished callbacks are not handled specially. They |
| | | will be propagated to the caller of the :mod:`pyramid` router |
| | | will be propagated to the caller of the :app:`Pyramid` router |
| | | application. |
| | | |
| | | A finished callback has a lifetime of a *single* request. If you want a |
| | |
| | | Decorators such as :class:`pyramid.view.view_config` don't change the |
| | | behavior of the functions or classes they're decorating. Instead, |
| | | when a :term:`scan` is performed, a modified version of the function |
| | | or class is registered with :mod:`pyramid`. |
| | | or class is registered with :app:`Pyramid`. |
| | | |
| | | You may wish to have your own decorators that offer such |
| | | behaviour. This is possible by using the :term:`Venusian` package in |
| | | the same way that it is used by :mod:`pyramid`. |
| | | the same way that it is used by :app:`Pyramid`. |
| | | |
| | | By way of example, let's suppose you want to write a decorator that |
| | | registers the function it wraps with a :term:`Zope Component |
| | | Architecture` "utility" within the :term:`application registry` |
| | | provided by :mod:`pyramid`. The application registry and the |
| | | provided by :app:`Pyramid`. The application registry and the |
| | | utility inside the registry is likely only to be available once your |
| | | application's configuration is at least partially completed. A normal |
| | | decorator would fail as it would be executed before the configuration |
| | |
| | | Combining Traversal and URL Dispatch |
| | | ==================================== |
| | | |
| | | When you write most :mod:`pyramid` applications, you'll be using |
| | | When you write most :app:`Pyramid` applications, you'll be using |
| | | one or the other of two available :term:`context finding` subsystems: |
| | | traversal or URL dispatch. However, to solve a limited set of |
| | | problems, it's useful to use *both* traversal and URL dispatch |
| | | together within the same application. :mod:`pyramid` makes this |
| | | together within the same application. :app:`Pyramid` makes this |
| | | possible via *hybrid* applications. |
| | | |
| | | .. warning:: |
| | |
| | | ----------------------------------- |
| | | |
| | | When used according to the tutorials in its documentation |
| | | :mod:`pyramid` is a "dual-mode" framework: the tutorials explain |
| | | :app:`Pyramid` is a "dual-mode" framework: the tutorials explain |
| | | how to create an application in terms of using either :term:`url |
| | | dispatch` *or* :term:`traversal`. This chapter details how you might |
| | | combine these two dispatch mechanisms, but we'll review how they work |
| | |
| | | ------------------- |
| | | |
| | | Either traversal or url dispatch alone can be used to create a |
| | | :mod:`pyramid` application. However, it is also possible to |
| | | :app:`Pyramid` application. However, it is also possible to |
| | | combine the concepts of traversal and url dispatch when building an |
| | | application: the result is a hybrid application. In a hybrid |
| | | application, traversal is performed *after* a particular route has |
| | |
| | | the matched route's configuration. |
| | | |
| | | Because the pattern of the above route ends with ``*traverse``, when this |
| | | route configuration is matched during a request, :mod:`pyramid` |
| | | route configuration is matched during a request, :app:`Pyramid` |
| | | will attempt to use :term:`traversal` against the :term:`root` object |
| | | implied by the :term:`root factory` implied by the route's |
| | | configuration. Once :term:`traversal` has found a :term:`context`, |
| | |
| | | If the URL that matched a route with the pattern ``:foo/:bar/*traverse``, |
| | | is ``http://example.com/one/two/a/b/c``, the traversal path used |
| | | against the root object will be ``a/b/c``. As a result, |
| | | :mod:`pyramid` will attempt to traverse through the edges ``a``, |
| | | :app:`Pyramid` will attempt to traverse through the edges ``a``, |
| | | ``b``, and ``c``, beginning at the root object. |
| | | |
| | | In our above example, this particular set of traversal steps will mean |
| | |
| | | process of displaying the user interface of an internationalized |
| | | application in a *particular* language or cultural context. |
| | | |
| | | :mod:`pyramid` offers internationalization and localization |
| | | :app:`Pyramid` offers internationalization and localization |
| | | subsystems that can be used to translate the text of buttons, error |
| | | messages and other software- and template-defined values into the |
| | | native language of a user of your application. |
| | |
| | | markup creates a :term:`translation string`. A translation string is |
| | | an object that behaves mostly like a normal Unicode object, except that |
| | | it also carries around extra information related to its job as part of |
| | | the :mod:`pyramid` translation machinery. |
| | | the :app:`Pyramid` translation machinery. |
| | | |
| | | Using The ``TranslationString`` Class |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | |
| | | Working With ``gettext`` Translation Files |
| | | ------------------------------------------ |
| | | |
| | | The basis of :mod:`pyramid` translation services is |
| | | The basis of :app:`Pyramid` translation services is |
| | | GNU :term:`gettext`. Once your application source code files and templates |
| | | are marked up with translation markers, you can work on translations |
| | | by creating various kinds of gettext files. |
| | |
| | | .. note:: |
| | | |
| | | The steps a developer must take to work with :term:`gettext` |
| | | :term:`message catalog` files within a :mod:`pyramid` |
| | | :term:`message catalog` files within a :app:`Pyramid` |
| | | application are very similar to the steps a :term:`Pylons` |
| | | developer must take to do the same. See the `Pylons |
| | | internationalization documentation |
| | |
| | | makes the localized program run faster. |
| | | |
| | | The tool for working with :term:`gettext` translation files related to |
| | | a :mod:`pyramid` application is :term:`Babel`. |
| | | a :app:`Pyramid` application is :term:`Babel`. |
| | | |
| | | .. index:: |
| | | single: Babel |
| | |
| | | In order for the commands related to working with ``gettext`` |
| | | translation files to work properly, you will need to have |
| | | :term:`Babel` installed into the same environment in which |
| | | :mod:`pyramid` is installed. |
| | | :app:`Pyramid` is installed. |
| | | |
| | | Installation on UNIX |
| | | ++++++++++++++++++++ |
| | | |
| | | If the :term:`virtualenv` into which you've installed your |
| | | :mod:`pyramid` application lives in ``/my/virtualenv``, you can |
| | | :app:`Pyramid` application lives in ``/my/virtualenv``, you can |
| | | install Babel like so: |
| | | |
| | | .. code-block:: bash |
| | |
| | | +++++++++++++++++++++++ |
| | | |
| | | If the :term:`virtualenv` into which you've installed your |
| | | :mod:`pyramid` application lives in ``C:\my\virtualenv``, you can |
| | | :app:`Pyramid` application lives in ``C:\my\virtualenv``, you can |
| | | install Babel like so: |
| | | |
| | | .. code-block:: bash |
| | |
| | | Once :term:`Babel` is installed and your application's ``setup.py`` |
| | | file has the correct message extractor references, you may extract a |
| | | message catalog template from the code and :term:`Chameleon` templates |
| | | which reside in your :mod:`pyramid` application. You run a |
| | | which reside in your :app:`Pyramid` application. You run a |
| | | ``setup.py`` command to extract the messages: |
| | | |
| | | .. code-block:: bash |
| | |
| | | denotes the :term:`translation domain` of the translations that must |
| | | be performed to localize your application. By default, the |
| | | translation domain is the :term:`project` name of your |
| | | :mod:`pyramid` application. |
| | | :app:`Pyramid` application. |
| | | |
| | | To change the translation domain of the extracted messages in your |
| | | project, edit the ``setup.cfg`` file of your application, The default |
| | | ``setup.cfg`` file of a Paster-generated :mod:`pyramid` application |
| | | ``setup.cfg`` file of a Paster-generated :app:`Pyramid` application |
| | | has stanzas in it that look something like the following: |
| | | |
| | | .. code-block:: ini |
| | |
| | | One tool which may help with this is `Poedit |
| | | <http://www.poedit.net/>`_. |
| | | |
| | | Note that :mod:`pyramid` itself ignores the existence of all |
| | | Note that :app:`Pyramid` itself ignores the existence of all |
| | | ``.po`` files. For a running application to have translations |
| | | available, a ``.mo`` file must exist. See |
| | | :ref:`compiling_message_catalog`. |
| | |
| | | This will create a ``.mo`` file for each ``.po`` file in your |
| | | application. As long as the :term:`translation directory` in which |
| | | the ``.mo`` file ends up in is configured into your application, these |
| | | translations will be available to :mod:`pyramid`. |
| | | translations will be available to :app:`Pyramid`. |
| | | |
| | | .. index:: |
| | | single: localizer |
| | |
| | | Performing Date Formatting and Currency Formatting |
| | | -------------------------------------------------- |
| | | |
| | | :mod:`pyramid` does not itself perform date and currency formatting |
| | | :app:`Pyramid` does not itself perform date and currency formatting |
| | | for different locales. However, :term:`Babel` can help you do this |
| | | via the :class:`babel.core.Locale` class. The `Babel documentation |
| | | for this class |
| | |
| | | information about how to install Babel. |
| | | |
| | | The :class:`babel.core.Locale` class requires a :term:`locale name` as |
| | | an argument to its constructor. You can use :mod:`pyramid` APIs to |
| | | an argument to its constructor. You can use :app:`Pyramid` APIs to |
| | | obtain the locale name for a request to pass to the |
| | | :class:`babel.core.Locale` constructor; see |
| | | :ref:`obtaining_the_locale_name`. For example: |
| | |
| | | .. 1.2.3 |
| | | |
| | | The features represented by attributes of the ``i18n`` namespace of |
| | | Chameleon will also consult the :mod:`pyramid` translations. |
| | | Chameleon will also consult the :app:`Pyramid` translations. |
| | | See |
| | | `http://chameleon.repoze.org/docs/latest/i18n.html#the-i18n-namespace |
| | | <http://chameleon.repoze.org/docs/latest/i18n.html#the-i18n-namespace>`_. |
| | | |
| | | .. note:: |
| | | |
| | | Unlike when Chameleon is used outside of :mod:`pyramid`, when it |
| | | is used *within* :mod:`pyramid`, it does not support use of the |
| | | Unlike when Chameleon is used outside of :app:`Pyramid`, when it |
| | | is used *within* :app:`Pyramid`, it does not support use of the |
| | | ``zope.i18n`` translation framework. Applications which use |
| | | :mod:`pyramid` should use the features documented in this |
| | | :app:`Pyramid` should use the features documented in this |
| | | chapter rather than ``zope.i18n``. |
| | | |
| | | Third party :mod:`pyramid` template renderers might not provide |
| | | Third party :app:`Pyramid` template renderers might not provide |
| | | this support out of the box and may need special code to do an |
| | | equivalent. For those, you can always use the more manual translation |
| | | facility described in :ref:`performing_a_translation`. |
| | |
| | | Localization-Related Deployment Settings |
| | | ---------------------------------------- |
| | | |
| | | A :mod:`pyramid` application will have a ``default_locale_name`` |
| | | A :app:`Pyramid` application will have a ``default_locale_name`` |
| | | setting. This value represents the :term:`default locale name` used |
| | | when the :term:`locale negotiator` returns ``None``. Pass it to the |
| | | :mod:`pyramid.configuration.Configurator` constructor at startup |
| | |
| | | If this value is not supplied via the Configurator constructor or via |
| | | a Paste config file, it will default to ``en``. |
| | | |
| | | If this setting is supplied within the :mod:`pyramid` application |
| | | If this setting is supplied within the :app:`Pyramid` application |
| | | ``.ini`` file, it will be available as a settings key: |
| | | |
| | | .. code-block:: python |
| | |
| | | languages" as indicated by the union of all languages in all |
| | | translation directories on disk at the time of the call to the API. |
| | | |
| | | It is by design that :mod:`pyramid` doesn't supply such an API. |
| | | It is by design that :app:`Pyramid` doesn't supply such an API. |
| | | Instead, the application itself is responsible for knowing the "available |
| | | languages". The rationale is this: any particular application |
| | | deployment must always know which languages it should be translatable |
| | |
| | | Activating Translation |
| | | ---------------------- |
| | | |
| | | By default, a :mod:`pyramid` application performs no translation. |
| | | By default, a :app:`Pyramid` application performs no translation. |
| | | To turn translation on, you must: |
| | | |
| | | - add at least one :term:`translation directory` to your application. |
| | |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | :term:`gettext` is the underlying machinery behind the |
| | | :mod:`pyramid` translation machinery. A translation directory is a |
| | | :app:`Pyramid` translation machinery. A translation directory is a |
| | | directory organized to be useful to :term:`gettext`. A translation |
| | | directory usually includes a listing of language directories, each of |
| | | which itself includes an ``LC_MESSAGES`` directory. Each |
| | |
| | | Adding a :term:`translation directory` registers all of its |
| | | constituent :term:`message catalog` files (all of the ``.mo`` files |
| | | found within all ``LC_MESSAGES`` directories within each locale |
| | | directory in the translation directory) within your :mod:`pyramid` |
| | | directory in the translation directory) within your :app:`Pyramid` |
| | | application to be available to use for translation services. |
| | | |
| | | You can add a translation directory imperatively by using the |
| | |
| | | |
| | | When the *default locale negotiator* (see |
| | | :ref:`default_locale_negotiator`) is in use, you can inform |
| | | :mod:`pyramid` of the current locale name by doing any of these |
| | | :app:`Pyramid` of the current locale name by doing any of these |
| | | things before any translations need to be performed: |
| | | |
| | | - Set the ``_LOCALE_`` attribute of the request to a valid locale name |
| | |
| | | return locale_name |
| | | |
| | | If a locale negotiator returns ``None``, it signifies to |
| | | :mod:`pyramid` that the default application locale name should be |
| | | :app:`Pyramid` that the default application locale name should be |
| | | used. |
| | | |
| | | You may add your newly created locale negotiator to your application's |
| | |
| | | .. _installing_chapter: |
| | | |
| | | Installing :mod:`pyramid` |
| | | Installing :app:`Pyramid` |
| | | ============================ |
| | | |
| | | .. index:: |
| | |
| | | ------------------ |
| | | |
| | | You will need `Python <http://python.org>`_ version 2.4 or better to |
| | | run :mod:`pyramid`. |
| | | run :app:`Pyramid`. |
| | | |
| | | .. sidebar:: Python Versions |
| | | |
| | | As of this writing, :mod:`pyramid` has been tested under Python |
| | | As of this writing, :app:`Pyramid` has been tested under Python |
| | | 2.4.6, Python 2.5.4 and Python 2.6.2, and Python 2.7. To ensure |
| | | backwards compatibility, development of :mod:`pyramid` is |
| | | backwards compatibility, development of :app:`Pyramid` is |
| | | currently done primarily under Python 2.4 and Python 2.5. |
| | | :mod:`pyramid` does not run under any version of Python before |
| | | :app:`Pyramid` does not run under any version of Python before |
| | | 2.4, and does not yet run under Python 3.X. |
| | | |
| | | :mod:`pyramid` is known to run on all popular Unix-like systems |
| | | :app:`Pyramid` is known to run on all popular Unix-like systems |
| | | such as Linux, MacOS X, and FreeBSD as well as on Windows platforms. |
| | | It is also known to run on Google's App Engine and :term:`Jython`. |
| | | |
| | | :mod:`pyramid` installation does not require the compilation of any |
| | | :app:`Pyramid` installation does not require the compilation of any |
| | | C code, so you need only a Python interpreter that meets the |
| | | requirements mentioned. |
| | | |
| | |
| | | |
| | | It's useful to use a Python interpreter that *isn't* the "system" |
| | | Python interpreter to develop your software. The authors of |
| | | :mod:`pyramid` tend not to use the system Python for development |
| | | :app:`Pyramid` tend not to use the system Python for development |
| | | purposes; always a self-compiled one. Compiling Python is usually |
| | | easy, and often the "system" Python is compiled with options that |
| | | aren't optimal for web development. |
| | |
| | | |
| | | .. _installing_unix: |
| | | |
| | | Installing :mod:`pyramid` on a UNIX System |
| | | Installing :app:`Pyramid` on a UNIX System |
| | | --------------------------------------------- |
| | | |
| | | It is best practice to install :mod:`pyramid` into a "virtual" |
| | | It is best practice to install :app:`Pyramid` into a "virtual" |
| | | Python environment in order to obtain isolation from any "system" |
| | | packages you've got installed in your Python version. This can be |
| | | done by using the :term:`virtualenv` package. Using a virtualenv will |
| | | also prevent :mod:`pyramid` from globally installing versions of |
| | | also prevent :app:`Pyramid` from globally installing versions of |
| | | packages that are not compatible with your system Python. |
| | | |
| | | To set up a virtualenv in which to install :mod:`pyramid`, first |
| | | To set up a virtualenv in which to install :app:`Pyramid`, first |
| | | ensure that :term:`setuptools` is installed. Invoke ``import |
| | | setuptools`` within the Python interpreter you'd like to run |
| | | :mod:`pyramid` under: |
| | | :app:`Pyramid` under: |
| | | |
| | | .. code-block:: text |
| | | |
| | |
| | | .. warning:: Using ``--no-site-packages`` when generating your |
| | | virtualenv is *very important*. This flag provides the necessary |
| | | isolation for running the set of packages required by |
| | | :mod:`pyramid`. If you do not specify ``--no-site-packages``, |
| | | it's possible that :mod:`pyramid` will not install properly into |
| | | :app:`Pyramid`. If you do not specify ``--no-site-packages``, |
| | | it's possible that :app:`Pyramid` will not install properly into |
| | | the virtualenv, or, even if it does, may not run properly, |
| | | depending on the packages you've already got installed into your |
| | | Python's "main" site-packages dir. |
| | |
| | | You should perform any following commands that mention a "bin" |
| | | directory from within the ``env`` virtualenv dir. |
| | | |
| | | Installing :mod:`pyramid` Into the Virtual Python Environment |
| | | Installing :app:`Pyramid` Into the Virtual Python Environment |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | After you've got your ``env`` virtualenv installed, you may install |
| | | :mod:`pyramid` itself using the following commands from within the |
| | | :app:`Pyramid` itself using the following commands from within the |
| | | virtualenv (``env``) directory: |
| | | |
| | | .. code-block:: text |
| | |
| | | |
| | | .. _installing_windows: |
| | | |
| | | Installing :mod:`pyramid` on a Windows System |
| | | Installing :app:`Pyramid` on a Windows System |
| | | ------------------------------------------------- |
| | | |
| | | #. Install, or find `Python 2.6 |
| | |
| | | environment wired to use the virtualenv. |
| | | |
| | | #. Use ``easy_install`` pointed at the "current" index to get |
| | | :mod:`pyramid` and its direct dependencies installed: |
| | | :app:`Pyramid` and its direct dependencies installed: |
| | | |
| | | .. code-block:: text |
| | | |
| | |
| | | .. index:: |
| | | single: installing on Google App Engine |
| | | |
| | | Installing :mod:`pyramid` on Google App Engine |
| | | Installing :app:`Pyramid` on Google App Engine |
| | | ------------------------------------------------- |
| | | |
| | | :ref:`appengine_tutorial` documents the steps required to install a |
| | | :mod:`pyramid` application on Google App Engine. |
| | | :app:`Pyramid` application on Google App Engine. |
| | | |
| | | Installing :mod:`pyramid` on Jython |
| | | Installing :app:`Pyramid` on Jython |
| | | -------------------------------------- |
| | | |
| | | :mod:`pyramid` is known to work under :term:`Jython` version 2.5.1. |
| | | :app:`Pyramid` is known to work under :term:`Jython` version 2.5.1. |
| | | Install :term:`Jython`, and then follow the installation steps for |
| | | :mod:`pyramid` on your platform described in one of the sections |
| | | :app:`Pyramid` on your platform described in one of the sections |
| | | entitled :ref:`installing_unix` or :ref:`installing_windows` above, |
| | | replacing the ``python`` command with ``jython`` as necessary. The |
| | | steps are exactly the same except you should use the ``jython`` |
| | | command name instead of the ``python`` command name. |
| | | |
| | | One caveat exists to using :mod:`pyramid` under Jython: the |
| | | One caveat exists to using :app:`Pyramid` under Jython: the |
| | | :term:`Chameleon` templating engine, which is the default templating |
| | | engine for :mod:`pyramid` does not work on Jython. |
| | | engine for :app:`Pyramid` does not work on Jython. |
| | | |
| | | The ``pyramid_jinja2`` distribution provides templating for |
| | | :mod:`pyramid` using the :term:`Jinja2` templating system. You may |
| | | :app:`Pyramid` using the :term:`Jinja2` templating system. You may |
| | | install it like so using the ``easy_install`` command for Jython: |
| | | |
| | | .. code-block:: python |
| | |
| | | $ easy_install pyramid_jinja2 |
| | | |
| | | Once this is done, you can use this command to get started with a |
| | | :mod:`pyramid` sample application that uses the Jinja2 templating |
| | | :app:`Pyramid` sample application that uses the Jinja2 templating |
| | | engine: |
| | | |
| | | .. code-block:: python |
| | |
| | | What Gets Installed |
| | | ------------------- |
| | | |
| | | When you ``easy_install`` :mod:`pyramid`, various Zope libraries, |
| | | When you ``easy_install`` :app:`Pyramid`, various Zope libraries, |
| | | various Chameleon libraries, WebOb, Paste, PasteScript, and |
| | | PasteDeploy libraries are installed. |
| | | |
| | | Additionally, as chronicled in :ref:`project_narr`, PasteScript (aka |
| | | *paster*) templates will be registered that make it easy to start a |
| | | new :mod:`pyramid` project. |
| | | new :app:`Pyramid` project. |
| | |
| | | single: frameworks vs. libraries |
| | | single: framework |
| | | |
| | | :mod:`pyramid` Introduction |
| | | :app:`Pyramid` Introduction |
| | | ============================== |
| | | |
| | | If they are judged only by differences in user interface, most web |
| | |
| | | applications probably won't serve the same set of customers. However, |
| | | although they're not very similar on the surface, both a |
| | | ledger-serving application and a song-serving application can be |
| | | written using :mod:`pyramid`. |
| | | written using :app:`Pyramid`. |
| | | |
| | | :mod:`pyramid` is a very general open source Python web |
| | | :app:`Pyramid` is a very general open source Python web |
| | | *framework*. As a framework, its primary job is to make it easier for |
| | | a developer to create an arbitrary web application. The type of |
| | | application being created isn't really important; it could be a |
| | | spreadsheet, a corporate intranet, or an "oh-so-Web-2.0" social |
| | | networking platform. :mod:`pyramid` is general enough that it can |
| | | networking platform. :app:`Pyramid` is general enough that it can |
| | | be used in a wide variety of circumstances. |
| | | |
| | | .. sidebar:: Frameworks vs. Libraries |
| | |
| | | own via a set of libraries if the framework provides a set of |
| | | facilities that fits your application requirements. |
| | | |
| | | The first release of the predecessor to :mod:`pyramid` (named |
| | | The first release of the predecessor to :app:`Pyramid` (named |
| | | :mod:`repoze.bfg`) was made in July of 2008. Since its first release, |
| | | we've tried to ensure that it maintains the following attributes: |
| | | |
| | | Simplicity |
| | | :mod:`pyramid` attempts to be a *"pay only for what you eat"* |
| | | :app:`Pyramid` attempts to be a *"pay only for what you eat"* |
| | | framework which delivers results even if you have only partial |
| | | knowledge. Other frameworks may expect you to understand many |
| | | concepts and technologies fully before you can be truly productive. |
| | | :mod:`pyramid` doesn't force you to use any particular technology |
| | | :app:`Pyramid` doesn't force you to use any particular technology |
| | | to produce an application, and we try to keep the core set of |
| | | concepts you need to understand to a minimum. |
| | | |
| | | A Sense of Fun |
| | | Developing a :mod:`pyramid` application should not feel |
| | | Developing a :app:`Pyramid` application should not feel |
| | | "enterprisey". We like to keep things down-to-earth. |
| | | |
| | | Minimalism |
| | | :mod:`pyramid` provides only the very basics: *URL to code |
| | | :app:`Pyramid` provides only the very basics: *URL to code |
| | | mapping*, *templating*, *security*, and *resources*. There is not |
| | | much more to the framework than these pieces: you are expected to |
| | | provide the rest. |
| | | |
| | | Documentation |
| | | Because :mod:`pyramid` is minimal, it's relatively easy to keep |
| | | Because :app:`Pyramid` is minimal, it's relatively easy to keep |
| | | its documentation up-to-date, which is helpful to bring new |
| | | developers up to speed. It's our goal that nothing remain |
| | | undocumented about :mod:`pyramid`. |
| | | undocumented about :app:`Pyramid`. |
| | | |
| | | Speed |
| | | :mod:`pyramid` is faster than many other popular Python web |
| | | :app:`Pyramid` is faster than many other popular Python web |
| | | frameworks for common tasks such as templating and simple response |
| | | generation. The "hardware is cheap" mantra has its limits when |
| | | you're responsible for managing a great many machines: the fewer you |
| | | need, the less pain you'll have. |
| | | |
| | | Familiarity |
| | | The :mod:`pyramid` framework is a canonization of practices that |
| | | The :app:`Pyramid` framework is a canonization of practices that |
| | | "fit the brains" of its authors. |
| | | |
| | | Trustability |
| | | :mod:`pyramid` is developed conservatively and tested |
| | | :app:`Pyramid` is developed conservatively and tested |
| | | exhaustively. *If it ain't tested, it's broke.* Every release of |
| | | :mod:`pyramid` has 100% statement coverage via unit tests. |
| | | :app:`Pyramid` has 100% statement coverage via unit tests. |
| | | |
| | | Openness |
| | | Like :term:`Python`, the :mod:`pyramid` software is distributed |
| | | Like :term:`Python`, the :app:`Pyramid` software is distributed |
| | | under a `permissive open source license |
| | | <http://repoze.org/license.html>`_. |
| | | |
| | |
| | | What Is The Pylons Project? |
| | | --------------------------- |
| | | |
| | | :mod:`pyramid` is a member of the collection of software published under the |
| | | :app:`Pyramid` is a member of the collection of software published under the |
| | | Pylons Project. :Pylons software is written by a loose-knit community of |
| | | contributors. The `Pylons Project website <http://docs.pylonshq.com>`_ |
| | | includes details about how :mod:`pyramid` relates to the Pylons Project. |
| | | includes details about how :app:`Pyramid` relates to the Pylons Project. |
| | | |
| | | .. index:: |
| | | single: pyramid and other frameworks |
| | |
| | | single: Django |
| | | single: MVC |
| | | |
| | | :mod:`pyramid` and Other Web Frameworks |
| | | :app:`Pyramid` and Other Web Frameworks |
| | | ------------------------------------------ |
| | | |
| | | Until the end of 2010, :mod:`pyramid` was known as :mod:`repoze.bfg`; it was |
| | | merged into the Pylons project as :mod:`pyramid` in November of that year. |
| | | Until the end of 2010, :app:`Pyramid` was known as :mod:`repoze.bfg`; it was |
| | | merged into the Pylons project as :app:`Pyramid` in November of that year. |
| | | |
| | | :mod:`pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version |
| | | 1.0) and :term:`Django`. As a result, :mod:`pyramid` borrows several |
| | | :app:`Pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version |
| | | 1.0) and :term:`Django`. As a result, :app:`Pyramid` borrows several |
| | | concepts and features from each, combining them into a unique web |
| | | framework. |
| | | |
| | | Many features of :mod:`pyramid` trace their origins back to |
| | | :term:`Zope`. Like Zope applications, :mod:`pyramid` applications |
| | | Many features of :app:`Pyramid` trace their origins back to |
| | | :term:`Zope`. Like Zope applications, :app:`Pyramid` applications |
| | | can be configured via a set of declarative configuration files. Like |
| | | Zope applications, :mod:`pyramid` applications can be easily |
| | | Zope applications, :app:`Pyramid` applications can be easily |
| | | extended: if you obey certain constraints, the application you produce |
| | | can be reused, modified, re-integrated, or extended by third-party |
| | | developers without forking the original application. The concepts of |
| | | :term:`traversal` and declarative security in :mod:`pyramid` were |
| | | :term:`traversal` and declarative security in :app:`Pyramid` were |
| | | pioneered first in Zope. |
| | | |
| | | The :mod:`pyramid` concept of :term:`URL dispatch` is inspired by the |
| | | The :app:`Pyramid` concept of :term:`URL dispatch` is inspired by the |
| | | :term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons |
| | | version 1.0, :mod:`pyramid` is mostly policy-free. It makes no |
| | | version 1.0, :app:`Pyramid` is mostly policy-free. It makes no |
| | | assertions about which database you should use, and its built-in |
| | | templating facilities are included only for convenience. In essence, |
| | | it only supplies a mechanism to map URLs to :term:`view` code, along |
| | |
| | | use third-party components that fit your needs in your applications. |
| | | |
| | | The concepts of :term:`view` and :term:`model` are used by |
| | | :mod:`pyramid` mostly as they would be by Django. |
| | | :mod:`pyramid` has a documentation culture more like Django's than |
| | | :app:`Pyramid` mostly as they would be by Django. |
| | | :app:`Pyramid` has a documentation culture more like Django's than |
| | | like Zope's. |
| | | |
| | | Like :term:`Pylons` version 1.0, but unlike :term:`Zope`, a |
| | | :mod:`pyramid` application developer may use completely imperative |
| | | :app:`Pyramid` application developer may use completely imperative |
| | | code to perform common framework configuration tasks such as adding a |
| | | view or a route. In Zope, :term:`ZCML` is typically required for |
| | | similar purposes. In :term:`Grok`, a Zope-based web framework, |
| | | :term:`decorator` objects and class-level declarations are used for |
| | | this purpose. :mod:`pyramid` supports :term:`ZCML` and |
| | | this purpose. :app:`Pyramid` supports :term:`ZCML` and |
| | | decorator-based configuration, but does not require either. See |
| | | :ref:`configuration_narr` for more information. |
| | | |
| | | Also unlike :term:`Zope` and unlike other "full-stack" frameworks such |
| | | as :term:`Django`, :mod:`pyramid` makes no assumptions about which |
| | | as :term:`Django`, :app:`Pyramid` makes no assumptions about which |
| | | persistence mechanisms you should use to build an application. Zope |
| | | applications are typically reliant on :term:`ZODB`; :mod:`pyramid` |
| | | applications are typically reliant on :term:`ZODB`; :app:`Pyramid` |
| | | allows you to build :term:`ZODB` applications, but it has no reliance |
| | | on the ZODB software. Likewise, :term:`Django` tends to assume that |
| | | you want to store your application's data in a relational database. |
| | | :mod:`pyramid` makes no such assumption; it allows you to use a |
| | | :app:`Pyramid` makes no such assumption; it allows you to use a |
| | | relational database but doesn't encourage or discourage the decision. |
| | | |
| | | Other Python web frameworks advertise themselves as members of a class |
| | | of web frameworks named `model-view-controller |
| | | <http://en.wikipedia.org/wiki/Model–view–controller>`_ frameworks. |
| | | Insofar as this term has been claimed to represent a class of web |
| | | frameworks, :mod:`pyramid` also generally fits into this class. |
| | | frameworks, :app:`Pyramid` also generally fits into this class. |
| | | |
| | | .. sidebar:: You Say :mod:`pyramid` is MVC, But Where's The Controller? |
| | | .. sidebar:: You Say :app:`Pyramid` is MVC, But Where's The Controller? |
| | | |
| | | The :mod:`pyramid` authors believe that the MVC pattern just |
| | | doesn't really fit the web very well. In a :mod:`pyramid` |
| | | The :app:`Pyramid` authors believe that the MVC pattern just |
| | | doesn't really fit the web very well. In a :app:`Pyramid` |
| | | application, there are models, which store data, and views, which |
| | | present the data stored in models. However, no facility provided |
| | | by the framework actually maps to the concept of a "controller". |
| | | So :mod:`pyramid` is actually an "MV" framework rather than an |
| | | So :app:`Pyramid` is actually an "MV" framework rather than an |
| | | "MVC" framework. "MVC", however, is close enough as a general |
| | | classification moniker for purposes of comparison with other web |
| | | frameworks. |
| | |
| | | |
| | | A :term:`model` class is typically a simple Python class defined in a |
| | | module. References to these classes and instances of such classes are |
| | | omnipresent in :mod:`pyramid`: |
| | | omnipresent in :app:`Pyramid`: |
| | | |
| | | - Model instances make up the graph that :mod:`pyramid` is |
| | | - Model instances make up the graph that :app:`Pyramid` is |
| | | willing to walk over when :term:`traversal` is used. |
| | | |
| | | - The ``context`` and ``containment`` arguments to |
| | |
| | | different notion of the definition of a "model". When using the API |
| | | of common ORM packages, its conception of "model" is almost |
| | | certainly not the same conception of "model" used by |
| | | :mod:`pyramid`. In particular, it can be unnatural to think of |
| | | :mod:`pyramid` model objects as "models" if you develop your |
| | | :app:`Pyramid`. In particular, it can be unnatural to think of |
| | | :app:`Pyramid` model objects as "models" if you develop your |
| | | application using :term:`traversal` and a relational database. When |
| | | you develop such applications, the object graph *might* be composed |
| | | completely of "model" objects (as defined by the ORM) but it also |
| | | might not be. The things that :mod:`pyramid` refers to as |
| | | might not be. The things that :app:`Pyramid` refers to as |
| | | "models" in such an application may instead just be stand-ins that |
| | | perform a query and generate some wrapper *for* an ORM "model" or |
| | | set of ORM models. This naming overlap is slightly unfortunate. |
| | | However, many :mod:`pyramid` applications (especially ones which |
| | | However, many :app:`Pyramid` applications (especially ones which |
| | | use :term:`ZODB`) do indeed traverse a graph full of literal model |
| | | nodes. Each node in the graph is a separate persistent object that |
| | | is stored within a database. This was the use case considered when |
| | |
| | | ------------------------------------------------- |
| | | |
| | | When :term:`traversal` is used (as opposed to a purely :term:`url |
| | | dispatch` based application), :mod:`pyramid` expects to be able to |
| | | dispatch` based application), :app:`Pyramid` expects to be able to |
| | | traverse a graph composed of model instances. Traversal begins at a |
| | | root model, and descends into the graph recursively via each found |
| | | model's ``__getitem__`` method. :mod:`pyramid` imposes the |
| | | model's ``__getitem__`` method. :app:`Pyramid` imposes the |
| | | following policy on model instance nodes in the graph: |
| | | |
| | | - Nodes which contain other nodes (aka "container" nodes) must supply |
| | |
| | | :mod:`repoze.bfg.traversalwrapper` package (available via `SVN |
| | | <http://svn.repoze.org/repoze.bfg.traversalwrapper>`_), then |
| | | register its ``ModelGraphTraverser`` as the traversal policy, rather |
| | | than the default :mod:`pyramid` traverser. The package contains |
| | | than the default :app:`Pyramid` traverser. The package contains |
| | | instructions. |
| | | |
| | | Once :mod:`pyramid` is configured with this feature, you will no |
| | | Once :app:`Pyramid` is configured with this feature, you will no |
| | | longer need to manage the ``__parent__`` and ``__name__`` attributes |
| | | on graph objects "by hand". Instead, as necessary, during traversal |
| | | :mod:`pyramid` will wrap each object (even the root object) in a |
| | | :app:`Pyramid` will wrap each object (even the root object) in a |
| | | ``LocationProxy`` which will dynamically assign a ``__name__`` and a |
| | | ``__parent__`` to the traversed object (based on the last traversed |
| | | object and the name supplied to ``__getitem__``). The root object |
| | |
| | | of a view must ensure that the model instances that make up the model |
| | | graph are "location aware". |
| | | |
| | | In order for :mod:`pyramid` location, security, URL-generation, and |
| | | In order for :app:`Pyramid` location, security, URL-generation, and |
| | | traversal functions (such as the functions exposed in |
| | | :ref:`location_module`, :ref:`traversal_module`, and :ref:`url_module` |
| | | as well as certain functions in :ref:`security_module` ) to work |
| | |
| | | single: model API functions |
| | | single: url generation (traversal) |
| | | |
| | | :mod:`pyramid` API Functions That Act Against Models |
| | | :app:`Pyramid` API Functions That Act Against Models |
| | | ------------------------------------------------------- |
| | | |
| | | A model instance is used as the :term:`context` argument provided to a |
| | |
| | | .. _project_narr: |
| | | |
| | | Creating a :mod:`pyramid` Project |
| | | Creating a :app:`Pyramid` Project |
| | | ==================================== |
| | | |
| | | It's possible to create a :mod:`pyramid` application completely |
| | | It's possible to create a :app:`Pyramid` application completely |
| | | manually, but it's usually more convenient to use a template to |
| | | generate a basic :mod:`pyramid` application structure. |
| | | generate a basic :app:`Pyramid` application structure. |
| | | |
| | | :mod:`pyramid` comes with templates that you can use to generate a |
| | | :app:`Pyramid` comes with templates that you can use to generate a |
| | | project. Each template makes different configuration assumptions |
| | | about what type of application you're trying to construct. |
| | | |
| | |
| | | |
| | | .. _additional_paster_templates: |
| | | |
| | | Paster Templates Included with :mod:`pyramid` |
| | | Paster Templates Included with :app:`Pyramid` |
| | | ------------------------------------------------ |
| | | |
| | | The convenience ``paster`` templates included with :mod:`pyramid` |
| | | The convenience ``paster`` templates included with :app:`Pyramid` |
| | | differ from each other on a number of axes: |
| | | |
| | | - the persistence mechanism they offer (no persistence mechanism, |
| | |
| | | |
| | | In :ref:`installing_chapter`, you created a virtual Python |
| | | environment via the ``virtualenv`` command. To start a |
| | | :mod:`pyramid` :term:`project`, use the ``paster`` facility |
| | | :app:`Pyramid` :term:`project`, use the ``paster`` facility |
| | | installed within the virtualenv. In :ref:`installing_chapter` we |
| | | called the virtualenv directory ``env``; the following command |
| | | assumes that our current working directory is that directory. |
| | |
| | | |
| | | The ``MyProject`` project directory contains an additional subdirectory named |
| | | ``myproject`` (note the case difference) representing a Python |
| | | :term:`package` which holds very simple :mod:`pyramid` sample code. This is |
| | | :term:`package` which holds very simple :app:`Pyramid` sample code. This is |
| | | where you'll edit your application's Python code and templates. |
| | | |
| | | .. index:: |
| | |
| | | |
| | | Once you've installed your program for development using ``setup.py |
| | | develop``, you can use an interactive Python shell to examine your |
| | | :mod:`pyramid` application :term:`model` and :term:`view` objects from |
| | | :app:`Pyramid` application :term:`model` and :term:`view` objects from |
| | | a Python prompt. To do so, use the ``paster`` shell command with the |
| | | ``pshell`` argument: |
| | | |
| | |
| | | |
| | | You should always use a section name argument that refers to the |
| | | actual ``app`` section within the Paste configuration file that points |
| | | at your :mod:`pyramid` application *without any middleware wrapping*. |
| | | at your :app:`Pyramid` application *without any middleware wrapping*. |
| | | In particular, a section name is inappropriate as the second argument |
| | | to ``pshell`` if the configuration section it names is a ``pipeline`` |
| | | rather than an ``app``. For example, if you have the following |
| | |
| | | Starting server in PID 16601. |
| | | serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 |
| | | |
| | | By default, :mod:`pyramid` applications generated from a ``paster`` |
| | | By default, :app:`Pyramid` applications generated from a ``paster`` |
| | | template will listen on TCP port 6543. |
| | | |
| | | During development, it's often useful to run ``paster serve`` using |
| | | its ``--reload`` option. When ``--reload`` is passed to ``paster |
| | | serve``, changes to any Python module your project uses will cause the |
| | | server to restart. This typically makes development easier, as |
| | | changes to Python code made within a :mod:`pyramid` application is |
| | | changes to Python code made within a :app:`Pyramid` application is |
| | | not put into effect until the server restarts. |
| | | |
| | | For example: |
| | |
| | | Using an Alternate WSGI Server |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | The code generated by :mod:`pyramid` ``paster`` templates assumes |
| | | The code generated by :app:`Pyramid` ``paster`` templates assumes |
| | | that you will be using the ``paster serve`` command to start your |
| | | application while you do development. However, ``paster serve`` is by |
| | | no means the only way to start up and serve a :mod:`pyramid` |
| | | no means the only way to start up and serve a :app:`Pyramid` |
| | | application. As we saw in :ref:`configuration_narr`, ``paster serve`` |
| | | needn't be invoked at all to run a :mod:`pyramid` application. The |
| | | use of ``paster serve`` to run a :mod:`pyramid` application is |
| | | needn't be invoked at all to run a :app:`Pyramid` application. The |
| | | use of ``paster serve`` to run a :app:`Pyramid` application is |
| | | purely conventional based on the output of its ``paster`` templates. |
| | | |
| | | Any :term:`WSGI` server is capable of running a :mod:`pyramid` |
| | | Any :term:`WSGI` server is capable of running a :app:`Pyramid` |
| | | application. Some WSGI servers don't require the :term:`PasteDeploy` |
| | | framework's ``paster serve`` command to do server process management |
| | | at all. Each :term:`WSGI` server has its own documentation about how |
| | |
| | | |
| | | One popular production alternative to a ``paster``-invoked server is |
| | | :term:`mod_wsgi`. You can also use :term:`mod_wsgi` to serve your |
| | | :mod:`pyramid` application using the Apache web server rather than |
| | | :app:`Pyramid` application using the Apache web server rather than |
| | | any "pure-Python" server that is started as a result of ``paster |
| | | serve``. See :ref:`modwsgi_tutorial` for details. However, it is |
| | | usually easier to *develop* an application using a ``paster serve`` |
| | |
| | | The Project Structure |
| | | --------------------- |
| | | |
| | | Our generated :mod:`pyramid` ``pyramid_starter`` application is a setuptools |
| | | Our generated :app:`Pyramid` ``pyramid_starter`` application is a setuptools |
| | | :term:`project` (named ``MyProject``), which contains a Python |
| | | :term:`package` (which is *also* named ``myproject``, but lowercased; the |
| | | paster template generates a project which contains a package that shares its |
| | | name except for case). All :mod:`pyramid` ``paster`` -generated projects |
| | | name except for case). All :app:`Pyramid` ``paster`` -generated projects |
| | | share a similar structure. |
| | | |
| | | The ``MyProject`` project we've generated has the following directory |
| | |
| | | your application by requiring more settings in this section. |
| | | |
| | | The ``reload_templates`` setting in the ``[app:main]`` section is a |
| | | :mod:`pyramid` -specific setting which is passed into the |
| | | :app:`Pyramid` -specific setting which is passed into the |
| | | framework. If it exists, and its value is ``true``, :term:`Chameleon` |
| | | template changes will not require an application restart to be |
| | | detected. See :ref:`reload_templates_section` for more information. |
| | |
| | | turned on. |
| | | |
| | | The ``debug_templates`` setting in the ``[app:main]`` section is a |
| | | :mod:`pyramid` -specific setting which is passed into the |
| | | :app:`Pyramid` -specific setting which is passed into the |
| | | framework. If it exists, and its value is ``true``, :term:`Chameleon` |
| | | template exceptions will contained more detailed and helpful |
| | | information about the error than when this value is ``false``. See |
| | |
| | | turned on. |
| | | |
| | | Various other settings may exist in this section having to do with |
| | | debugging or influencing runtime behavior of a :mod:`pyramid` |
| | | debugging or influencing runtime behavior of a :app:`Pyramid` |
| | | application. See :ref:`environment_chapter` for more information |
| | | about these settings. |
| | | |
| | |
| | | |
| | | .. note:: |
| | | |
| | | In general, :mod:`pyramid` applications generated from ``paster |
| | | In general, :app:`Pyramid` applications generated from ``paster |
| | | templates`` should be threading-aware. It is not required that a |
| | | :mod:`pyramid` application be nonblocking as all application code |
| | | :app:`Pyramid` application be nonblocking as all application code |
| | | will run in its own thread, provided by the server you're using. |
| | | |
| | | See the :term:`PasteDeploy` documentation for more information about |
| | |
| | | application. |
| | | |
| | | These are purely conventions established by the ``paster`` template: |
| | | :mod:`pyramid` doesn't insist that you name things in any |
| | | :app:`Pyramid` doesn't insist that you name things in any |
| | | particular way. |
| | | |
| | | .. index:: |
| | |
| | | #. Line 2 imports the ``get_root`` function from |
| | | :mod:`myproject.models` that we use later. |
| | | |
| | | #. Lines 4-17 define a function that returns a :mod:`pyramid` |
| | | #. Lines 4-17 define a function that returns a :app:`Pyramid` |
| | | WSGI application. This function is meant to be called |
| | | by the :term:`PasteDeploy` framework as a result of running |
| | | ``paster serve``. |
| | |
| | | ``views.py`` |
| | | ~~~~~~~~~~~~ |
| | | |
| | | Much of the heavy lifting in a :mod:`pyramid` application comes in |
| | | Much of the heavy lifting in a :app:`Pyramid` application comes in |
| | | the form of *view callables*. A :term:`view callable` is the main |
| | | tool of a :mod:`pyramid` web application developer; it is a bit of |
| | | tool of a :app:`Pyramid` web application developer; it is a bit of |
| | | code which accepts a :term:`request` and which returns a |
| | | :term:`response`. |
| | | |
| | |
| | | #. Line 4 defines an instance of MyModel as the root. |
| | | |
| | | #. Line 6 is a "root factory" function that will be called by the |
| | | :mod:`pyramid` *Router* for each request when it wants to find |
| | | :app:`Pyramid` *Router* for each request when it wants to find |
| | | the root of the object graph. Conventionally this is called |
| | | ``get_root``. |
| | | |
| | | In a "real" application, the root object would not be such a simple |
| | | object. Instead, it would be an object that could access some |
| | | persistent data store, such as a database. :mod:`pyramid` doesn't |
| | | persistent data store, such as a database. :app:`Pyramid` doesn't |
| | | make any assumption about which sort of datastore you'll want to use, |
| | | so the sample application uses an instance of |
| | | :class:`myproject.models.MyModel` to represent the root. |
| | |
| | | This sample ``tests.py`` file has a single unit test defined within |
| | | it. This test is executed when you run ``python setup.py test``. You |
| | | may add more tests here as you build your application. You are not |
| | | required to write tests to use :mod:`pyramid`, this file is simply |
| | | required to write tests to use :app:`Pyramid`, this file is simply |
| | | provided as convenience and example. |
| | | |
| | | See :ref:`unittesting_chapter` for more information about writing |
| | | :mod:`pyramid` unit tests. |
| | | :app:`Pyramid` unit tests. |
| | |
| | | in it (if it possessed an ``__init__.py`` it would *be* a package). |
| | | |
| | | The use of resources is quite common in most web development projects. |
| | | For example, when you create a :mod:`pyramid` application using one |
| | | For example, when you create a :app:`Pyramid` application using one |
| | | of the available "paster" templates, as described in |
| | | :ref:`creating_a_project`, the directory representing the application |
| | | contains a Python :term:`package`. Within that Python package, there |
| | |
| | | Understanding Resources |
| | | ----------------------- |
| | | |
| | | Let's imagine you've created a :mod:`pyramid` application that uses |
| | | Let's imagine you've created a :app:`Pyramid` application that uses |
| | | a :term:`Chameleon` ZPT template via the |
| | | :func:`pyramid.chameleon_zpt.render_template_to_response` API. For |
| | | example, the application might address the resource named |
| | |
| | | from pyramid.chameleon_zpt import render_template_to_response |
| | | render_template_to_response('templates/some_template.pt') |
| | | |
| | | "Under the hood", when this API is called, :mod:`pyramid` attempts |
| | | "Under the hood", when this API is called, :app:`Pyramid` attempts |
| | | to make sense out of the string ``templates/some_template.pt`` |
| | | provided by the developer. To do so, it first finds the "current" |
| | | package. The "current" package is the Python package in which the |
| | | ``views.py`` module which contains this code lives. This would be the |
| | | ``myapp`` package, according to our example so far. By resolving the |
| | | current package, :mod:`pyramid` has enough information to locate |
| | | current package, :app:`Pyramid` has enough information to locate |
| | | the actual template file. These are the elements it needs: |
| | | |
| | | - The *package name* (``myapp``) |
| | | |
| | | - The *resource name* (``templates/some_template.pt``) |
| | | |
| | | :mod:`pyramid` uses the :term:`pkg_resources` API to resolve the |
| | | :app:`Pyramid` uses the :term:`pkg_resources` API to resolve the |
| | | package name and resource name to an absolute |
| | | (operating-system-specific) file name. It eventually passes this |
| | | resolved absolute filesystem path to the Chameleon templating engine, |
| | |
| | | -------------------- |
| | | |
| | | It can often be useful to override specific resources "from outside" a |
| | | given :mod:`pyramid` application. For example, you may wish to |
| | | reuse an existing :mod:`pyramid` application more or less |
| | | given :app:`Pyramid` application. For example, you may wish to |
| | | reuse an existing :app:`Pyramid` application more or less |
| | | unchanged. However, some specific template file owned by the |
| | | application might have inappropriate HTML, or some static resource |
| | | (such as a logo file or some CSS file) might not be appropriate. You |
| | |
| | | application), and you want to make arbitrary visual modifications to a |
| | | particular application deployment without forking the underlying code. |
| | | |
| | | To this end, :mod:`pyramid` contains a feature that makes it |
| | | To this end, :app:`Pyramid` contains a feature that makes it |
| | | possible to "override" one resource with one or more other resources. |
| | | In support of this feature, a :term:`ZCML` directive exists named |
| | | ``resource``. The ``resource`` directive allows you to *override* the |
| | |
| | | performing the following steps: |
| | | |
| | | - Create a new Python package. The easiest way to do this is to |
| | | create a new :mod:`pyramid` application using the "paster" |
| | | create a new :app:`Pyramid` application using the "paster" |
| | | template mechanism. See :ref:`creating_a_project` for more |
| | | information. |
| | | |
| | |
| | | - Change the ``configure.zcml`` in the new package to include one or |
| | | more ``resource`` ZCML directives (see :ref:`resource_directive` |
| | | below). The new package's ``configure.zcml`` should then include |
| | | the original :mod:`pyramid` application's ``configure.zcml`` via |
| | | the original :app:`Pyramid` application's ``configure.zcml`` via |
| | | an include statement, e.g. ``<include |
| | | package="theoriginalpackage"/>``. |
| | | |
| | |
| | | for more information about this setting. |
| | | |
| | | Note that overriding resources is not the only way to extend or modify |
| | | the behavior of an existing :mod:`pyramid` application. A "heavier |
| | | the behavior of an existing :app:`Pyramid` application. A "heavier |
| | | hammer" way to do the same thing is explained in |
| | | :ref:`extending_chapter`. The heavier hammer way allows you to |
| | | replace a :term:`view` wholesale rather than resources that might be |
| | |
| | | all the tasks described above within :term:`ZCML`. The ZCML |
| | | ``resource`` tag is a frontend to using ``override_resource``. |
| | | |
| | | An individual :mod:`pyramid` ``resource`` ZCML statement can |
| | | An individual :app:`Pyramid` ``resource`` ZCML statement can |
| | | override a single resource. For example: |
| | | |
| | | .. code-block:: xml |
| | |
| | | Request Processing |
| | | ================== |
| | | |
| | | Once a :mod:`pyramid` application is up and running, it is ready to |
| | | Once a :app:`Pyramid` application is up and running, it is ready to |
| | | accept requests and return responses. |
| | | |
| | | What happens from the time a :term:`WSGI` request enters a |
| | | :mod:`pyramid` application through to the point that |
| | | :mod:`pyramid` hands off a response back to WSGI for upstream |
| | | :app:`Pyramid` application through to the point that |
| | | :app:`Pyramid` hands off a response back to WSGI for upstream |
| | | processing? |
| | | |
| | | #. A user initiates a request from his browser to the hostname and |
| | | port number of the WSGI server used by the :mod:`pyramid` |
| | | port number of the WSGI server used by the :app:`Pyramid` |
| | | application. |
| | | |
| | | #. The WSGI server used by the :mod:`pyramid` application passes |
| | | #. The WSGI server used by the :app:`Pyramid` application passes |
| | | the WSGI environment to the ``__call__`` method of the |
| | | :mod:`pyramid` :term:`router` object. |
| | | :app:`Pyramid` :term:`router` object. |
| | | |
| | | #. A :term:`request` object is created based on the WSGI environment. |
| | | |
| | | #. The :term:`application registry` and the :term:`request` object |
| | | created in the last step are pushed on to the :term:`thread local` |
| | | stack that :mod:`pyramid` uses to allow the functions named |
| | | stack that :app:`Pyramid` uses to allow the functions named |
| | | :func:`pyramid.threadlocal.get_current_request` and |
| | | :func:`pyramid.threadlocal.get_current_registry` to work. |
| | | |
| | |
| | | subscribers. |
| | | |
| | | #. If any :term:`route` has been defined within application |
| | | configuration, the :mod:`pyramid` :term:`router` calls a |
| | | configuration, the :app:`Pyramid` :term:`router` calls a |
| | | :term:`URL dispatch` "route mapper." The job of the mapper is to |
| | | examine the request to determine whether any user-defined |
| | | :term:`route` matches the current WSGI environment. The |
| | |
| | | argument passed to the Configurator constructor was ``None``, a |
| | | default root factory is used to generate a root object. |
| | | |
| | | #. The :mod:`pyramid` router calls a "traverser" function with the |
| | | #. The :app:`Pyramid` router calls a "traverser" function with the |
| | | root object and the request. The traverser function attempts to |
| | | traverse the root object (using any existing ``__getitem__`` on the |
| | | root object and subobjects) to find a :term:`context`. If the root |
| | |
| | | #. A :class:`pyramid.events.ContextFound` :term:`event` is |
| | | sent to any subscribers. |
| | | |
| | | #. :mod:`pyramid` looks up a :term:`view` callable using the |
| | | #. :app:`Pyramid` looks up a :term:`view` callable using the |
| | | context, the request, and the view name. If a view callable |
| | | doesn't exist for this combination of objects (based on the type of |
| | | the context, the type of the request, and the value of the view |
| | | name, and any :term:`predicate` attributes applied to the view |
| | | configuration), :mod:`pyramid` raises a |
| | | configuration), :app:`Pyramid` raises a |
| | | :class:`pyramid.exceptions.NotFound` exception, which is meant |
| | | to be caught by a surrounding exception handler. |
| | | |
| | | #. If a view callable was found, :mod:`pyramid` attempts to call |
| | | #. If a view callable was found, :app:`Pyramid` attempts to call |
| | | the view function. |
| | | |
| | | #. If an :term:`authorization policy` is in use, and the view was |
| | | protected by a :term:`permission`, :mod:`pyramid` passes the |
| | | protected by a :term:`permission`, :app:`Pyramid` passes the |
| | | context, the request, and the view_name to a function which |
| | | determines whether the view being asked for can be executed by the |
| | | requesting user, based on credential information in the request and |
| | | security information attached to the context. If it returns |
| | | ``True``, :mod:`pyramid` calls the view callable to obtain a |
| | | ``True``, :app:`Pyramid` calls the view callable to obtain a |
| | | response. If it returns ``False``, it raises a |
| | | :class:`pyramid.exceptions.Forbidden` exception, which is meant |
| | | to be called by a surrounding exception handler. |
| | | |
| | | #. If any exception was raised within a :term:`root factory`, by |
| | | :term:`traversal`, by a :term:`view callable` or by |
| | | :mod:`pyramid` itself (such as when it raises |
| | | :app:`Pyramid` itself (such as when it raises |
| | | :class:`pyramid.exceptions.NotFound` or |
| | | :class:`pyramid.exceptions.Forbidden`), the router catches the |
| | | exception, and attaches it to the request as the ``exception`` |
| | |
| | | |
| | | #. The following steps occur only when a :term:`response` could be |
| | | successfully generated by a normal :term:`view callable` or an |
| | | :term:`exception view` callable. :mod:`pyramid` will attempt to execute |
| | | :term:`exception view` callable. :app:`Pyramid` will attempt to execute |
| | | any :term:`response callback` functions attached via |
| | | :meth:`pyramid.request.Request.add_response_callback`. A |
| | | :class:`pyramid.events.NewResponse` :term:`event` is then sent to any |
| | |
| | | ``headerlist`` attributes are then used to generate a WSGI response. The |
| | | response is sent back to the upstream WSGI server. |
| | | |
| | | #. :mod:`pyramid` will attempt to execute any :term:`finished |
| | | #. :app:`Pyramid` will attempt to execute any :term:`finished |
| | | callback` functions attached via |
| | | :meth:`pyramid.request.Request.add_finished_callback`. |
| | | |
| | |
| | | .. image:: router.png |
| | | |
| | | This is a very high-level overview that leaves out various details. |
| | | For more detail about subsystems invoked by the :mod:`pyramid` router |
| | | For more detail about subsystems invoked by the :app:`Pyramid` router |
| | | such as traversal, URL dispatch, views, and event processing, see |
| | | :ref:`contextfinding_chapter`, :ref:`views_chapter`, and |
| | | :ref:`events_chapter`. |
| | |
| | | Security |
| | | ======== |
| | | |
| | | :mod:`pyramid` provides an optional declarative authorization |
| | | :app:`Pyramid` provides an optional declarative authorization |
| | | system that prevents a :term:`view` from being invoked when the user |
| | | represented by credentials in the :term:`request` does not have an |
| | | appropriate level of access within a particular :term:`context`. |
| | |
| | | |
| | | Authorization is enabled by modifying your application to include an |
| | | :term:`authentication policy` and :term:`authorization policy`. |
| | | :mod:`pyramid` comes with a variety of implementations of these |
| | | policies. To provide maximal flexibility, :mod:`pyramid` also |
| | | :app:`Pyramid` comes with a variety of implementations of these |
| | | policies. To provide maximal flexibility, :app:`Pyramid` also |
| | | allows you to create custom authentication policies and authorization |
| | | policies. |
| | | |
| | |
| | | Enabling an Authorization Policy |
| | | -------------------------------- |
| | | |
| | | By default, :mod:`pyramid` enables no authorization policy. All |
| | | By default, :app:`Pyramid` enables no authorization policy. All |
| | | views are accessible by completely anonymous users. In order to begin |
| | | protecting views from execution based on security settings, you need |
| | | to enable an authorization policy. |
| | |
| | | authorization policy in effect is ignored. |
| | | |
| | | In support of making it easier to configure applications which are |
| | | "secure by default", :mod:`pyramid` allows you to configure a |
| | | "secure by default", :app:`Pyramid` allows you to configure a |
| | | *default* permission. If supplied, the default permission is used as |
| | | the permission string to all view registrations which don't otherwise |
| | | name a ``permission`` argument. |
| | |
| | | Assigning ACLs to your Model Objects |
| | | ------------------------------------ |
| | | |
| | | When the default :mod:`pyramid` :term:`authorization policy` |
| | | When the default :app:`Pyramid` :term:`authorization policy` |
| | | determines whether a user possesses a particular permission in a |
| | | :term:`context`, it examines the :term:`ACL` associated with the |
| | | context. An ACL is associated with a context by virtue of the |
| | |
| | | Changing the Forbidden View |
| | | --------------------------- |
| | | |
| | | When :mod:`pyramid` denies a view invocation due to an |
| | | When :app:`Pyramid` denies a view invocation due to an |
| | | authorization denial, the special ``forbidden`` view is invoked. "Out |
| | | of the box", this forbidden view is very plain. See |
| | | :ref:`changing_the_forbidden_view` within :ref:`hooks_chapter` for |
| | |
| | | Creating Your Own Authentication Policy |
| | | --------------------------------------- |
| | | |
| | | :mod:`pyramid` ships with a number of useful out-of-the-box |
| | | :app:`Pyramid` ships with a number of useful out-of-the-box |
| | | security policies (see :mod:`pyramid.authentication`). However, |
| | | creating your own authentication policy is often necessary when you |
| | | want to control the "horizontal and vertical" of how your users |
| | |
| | | -------------------------------------- |
| | | |
| | | An authorization policy is a policy that allows or denies access after |
| | | a user has been authenticated. By default, :mod:`pyramid` will use |
| | | a user has been authenticated. By default, :app:`Pyramid` will use |
| | | the :class:`pyramid.authorization.ACLAuthorizationPolicy` if an |
| | | authentication policy is activated and an authorization policy isn't |
| | | otherwise specified. |
| | |
| | | policy which allows the application to use an authorization mechanism |
| | | that does not involve :term:`ACL` objects. |
| | | |
| | | :mod:`pyramid` ships with only a single default authorization |
| | | :app:`Pyramid` ships with only a single default authorization |
| | | policy, so you'll need to create your own if you'd like to use a |
| | | different one. Creating and using your own authorization policy is a |
| | | matter of creating an instance of an object that implements the |
| | |
| | | --------------------------------- |
| | | |
| | | In order to use sessions, you must set up a :term:`session factory` |
| | | during your :mod:`pyramid` configuration. |
| | | during your :app:`Pyramid` configuration. |
| | | |
| | | A very basic, insecure sample session factory implementation is |
| | | provided in the :mod:`pyramid` core. It uses a cookie to store |
| | | provided in the :app:`Pyramid` core. It uses a cookie to store |
| | | session information. This implementation has the following |
| | | limitation: |
| | | |
| | |
| | | It is, however, digitally signed, and thus its data cannot easily be |
| | | tampered with. |
| | | |
| | | You can configure this session factory in your :mod:`pyramid` |
| | | You can configure this session factory in your :app:`Pyramid` |
| | | application by using the ``session_factory`` argument to the |
| | | :class:`pyramid.configuration.Configurator` class: |
| | | |
| | |
| | | --------------------------------- |
| | | |
| | | If none of the default or otherwise available sessioning |
| | | implementations for :mod:`pyramid` suit you, you may create your own |
| | | implementations for :app:`Pyramid` suit you, you may create your own |
| | | session object by implementing a :term:`session factory`. Your |
| | | session factory should return a :term:`session`. The interfaces for |
| | | both types are available in |
| | |
| | | Startup |
| | | ======= |
| | | |
| | | When you cause :mod:`pyramid` to start up in a console window, |
| | | When you cause :app:`Pyramid` to start up in a console window, |
| | | you'll see something much like this show up on the console: |
| | | |
| | | .. code-block:: text |
| | |
| | | ------------------- |
| | | |
| | | The easiest and best-documented way to start and serve a |
| | | :mod:`pyramid` application is to use the ``paster serve`` command |
| | | :app:`Pyramid` application is to use the ``paster serve`` command |
| | | against a :term:`PasteDeploy` ``.ini`` file. This uses the ``.ini`` |
| | | file to infer settings and starts a server listening on a port. For |
| | | the purposes of this discussion, we'll assume that you are using this |
| | | command to run your :mod:`pyramid` application. |
| | | command to run your :app:`Pyramid` application. |
| | | |
| | | Here's a high-level time-ordered overview of what happens when you |
| | | press ``return`` after running ``paster serve development.ini``. |
| | |
| | | the ``.ini`` file. This section represents the configuration of a |
| | | :term:`WSGI` application that will be served. If you're using a |
| | | simple application (e.g. an ``[app:main]`` section of a |
| | | default-generated :mod:`pyramid` project), the application |
| | | default-generated :app:`Pyramid` project), the application |
| | | :term:`entry point` or :term:`dotted Python name` will be named on |
| | | the ``use=`` line within the section's configuration. If, instead |
| | | of a simple application, you're using a WSGI :term:`pipeline` |
| | | (e.g. a ``[pipeline:main]`` section), the application named on the |
| | | "last" element will refer to your :mod:`pyramid` application. |
| | | "last" element will refer to your :app:`Pyramid` application. |
| | | If instead of a simple application or a pipeline, you're using a |
| | | Paste "composite" (e.g. ``[composite:main]``), refer to the |
| | | documentation for that particular composite to understand how to |
| | | make it refer to your :mod:`pyramid` application. |
| | | make it refer to your :app:`Pyramid` application. |
| | | |
| | | #. The application's *constructor* (named by the entry point reference |
| | | or dotted Python name on the ``use=`` line) is passed the key/value |
| | |
| | | constructor is meant to return a :term:`router` instance, which is |
| | | a :term:`WSGI` application. |
| | | |
| | | For :mod:`pyramid` applications, the constructor will be a function named |
| | | For :app:`Pyramid` applications, the constructor will be a function named |
| | | ``app`` in the ``__init__.py`` file within the :term:`package` in which |
| | | your application lives. If this function succeeds, it will return a |
| | | :mod:`pyramid` :term:`router` instance. Here's the contents of an example |
| | | :app:`Pyramid` :term:`router` instance. Here's the contents of an example |
| | | ``__init__.py`` module: |
| | | |
| | | .. literalinclude:: MyProject/myproject/__init__.py |
| | |
| | | #. The ``app`` function then calls various methods on the an instance of the |
| | | class :class:`pyramid.configuration.Configurator` method. The intent of |
| | | calling these methods is to populate an :term:`application registry`, |
| | | which represents the :mod:`pyramid` configuration related to the |
| | | which represents the :app:`Pyramid` configuration related to the |
| | | application. |
| | | |
| | | #. The :meth:`pyramid.configuration.Configurator.make_wsgi_app` method is |
| | |
| | | Static Resources |
| | | ================ |
| | | |
| | | :mod:`pyramid` makes it possible to serve up "static" (non-dynamic) |
| | | :app:`Pyramid` makes it possible to serve up "static" (non-dynamic) |
| | | resources from a directory on a filesystem. This chapter describes |
| | | how to configure :mod:`pyramid` to do so. |
| | | how to configure :app:`Pyramid` to do so. |
| | | |
| | | .. index:: |
| | | single: add_static_view |
| | |
| | | ------------------------ |
| | | |
| | | Use the :meth:`pyramid.configuration.Configurator.add_static_view` to |
| | | instruct :mod:`pyramid` to serve static resources such as JavaScript and CSS |
| | | instruct :app:`Pyramid` to serve static resources such as JavaScript and CSS |
| | | files. This mechanism makes static files available at a name relative to the |
| | | application root URL, e.g. ``/static``. |
| | | |
| | |
| | | Here's an example of a use of |
| | | :meth:`pyramid.configuration.Configurator.add_static_view` that will serve |
| | | files up under the ``/static`` URL from the ``/var/www/static`` directory of |
| | | the computer which runs the :mod:`pyramid` application using an absolute |
| | | the computer which runs the :app:`Pyramid` application using an absolute |
| | | path. |
| | | |
| | | .. code-block:: python |
| | |
| | | properly after the rename. |
| | | |
| | | URLs may also be generated by :func:`pyramid.url.static_url` to static |
| | | resources that live *outside* the :mod:`pyramid` application. This will |
| | | resources that live *outside* the :app:`Pyramid` application. This will |
| | | happen when the :meth:`pyramid.configuration.Configurator.add_static_view` |
| | | API associated with the path fed to :func:`pyramid.url.static_url` is a *URL* |
| | | instead of a view name. For example, the ``name`` argument may be |
| | |
| | | |
| | | The :class:`pyramid.view.static` helper class is used to perform |
| | | this task. This class creates an object that is capable acting as a |
| | | :mod:`pyramid` view callable which serves static resources from a |
| | | :app:`Pyramid` view callable which serves static resources from a |
| | | directory. For instance, to serve files within a directory located on |
| | | your filesystem at ``/path/to/static/dir`` mounted at the URL path |
| | | ``/static`` in your application, create an instance of the |
| | |
| | | context='mypackage.models.Root') |
| | | |
| | | In this case, ``mypackage.models.Root`` refers to the class of which your |
| | | :mod:`pyramid` application's root object is an instance. |
| | | :app:`Pyramid` application's root object is an instance. |
| | | |
| | | You can also omit the ``context`` argument if you want the name ``static`` to |
| | | be accessible as the static view against any model. This will also allow |
| | |
| | | ========= |
| | | |
| | | A :term:`template` is a file on disk which can be used to render |
| | | dynamic data provided by a :term:`view`. :mod:`pyramid` offers a |
| | | dynamic data provided by a :term:`view`. :app:`Pyramid` offers a |
| | | number of ways to perform templating tasks out of the box, and |
| | | provides add-on templating support through a set of bindings packages. |
| | | |
| | | Out of the box, :mod:`pyramid` provides templating via the :term:`Chameleon` |
| | | Out of the box, :app:`Pyramid` provides templating via the :term:`Chameleon` |
| | | and :term:`Mako` templating libraries. :term:`Chameleon` provides support for |
| | | two different types of templates: :term:`ZPT` templates and text templates. |
| | | |
| | | Before discussing how built-in templates are used in |
| | | detail, we'll discuss two ways to render templates within |
| | | :mod:`pyramid` in general: directly, and via renderer |
| | | :app:`Pyramid` in general: directly, and via renderer |
| | | configuration. |
| | | |
| | | .. index:: |
| | |
| | | ----------------------- |
| | | |
| | | The most straightforward way to use a template within |
| | | :mod:`pyramid` is to cause it to be rendered directly within a |
| | | :app:`Pyramid` is to cause it to be rendered directly within a |
| | | :term:`view callable`. You may use whatever API is supplied by a |
| | | given templating engine to do so. |
| | | |
| | | :mod:`pyramid` provides various APIs that allow you to render |
| | | :app:`Pyramid` provides various APIs that allow you to render |
| | | templates directly from within a view callable. For example, if there |
| | | is a :term:`Chameleon` ZPT template named ``foo.pt`` in a directory in |
| | | your application named ``templates``, you can render the template from |
| | |
| | | Application developers are encouraged instead to use the functions |
| | | available in the :mod:`pyramid.renderers` module to perform |
| | | rendering tasks. This set of functions works to render templates |
| | | for all renderer extensions registered with :mod:`pyramid`. |
| | | for all renderer extensions registered with :app:`Pyramid`. |
| | | |
| | | The ``sample_view`` :term:`view callable` above returns a |
| | | :term:`response` object which contains the body of the |
| | |
| | | path, it is treated as an absolute resource specification. |
| | | |
| | | In the examples above we pass in a keyword argument named ``request`` |
| | | representing the current :mod:`pyramid` request. Passing a request |
| | | representing the current :app:`Pyramid` request. Passing a request |
| | | keyword argument will cause the ``render_to_response`` function to |
| | | supply the renderer with more correct system values (see |
| | | :ref:`renderer_system_values`), because most of the information |
| | |
| | | return response |
| | | |
| | | Because :term:`view callable` functions are typically the only code in |
| | | :mod:`pyramid` that need to know anything about templates, and because view |
| | | :app:`Pyramid` that need to know anything about templates, and because view |
| | | functions are very simple Python, you can use whatever templating system you're |
| | | most comfortable with within :mod:`pyramid`. Install the templating system, |
| | | most comfortable with within :app:`Pyramid`. Install the templating system, |
| | | import its API functions into your views module, use those APIs to generate a |
| | | string, then return that string as the body of a :mod:`pyramid` |
| | | string, then return that string as the body of a :app:`Pyramid` |
| | | :term:`Response` object. |
| | | |
| | | For example, here's an example of using "raw" `Mako |
| | | <http://www.makotemplates.org/>`_ from within a :mod:`pyramid` :term:`view`: |
| | | <http://www.makotemplates.org/>`_ from within a :app:`Pyramid` :term:`view`: |
| | | |
| | | .. ignore-next-block |
| | | .. code-block:: python |
| | |
| | | |
| | | You probably wouldn't use this particular snippet in a project, because it's |
| | | easier to use the Mako renderer bindings which already exist in |
| | | :mod:`pyramid`. But if your favorite templating system is not supported as a |
| | | renderer extension for :mod:`pyramid`, you can create your own simple |
| | | :app:`Pyramid`. But if your favorite templating system is not supported as a |
| | | renderer extension for :app:`Pyramid`, you can create your own simple |
| | | combination as shown above. |
| | | |
| | | .. note:: |
| | | |
| | | If you use third-party templating languages without cooperating |
| | | :mod:`pyramid` bindings directly within view callables, the |
| | | :app:`Pyramid` bindings directly within view callables, the |
| | | auto-template-reload strategy explained in |
| | | :ref:`reload_templates_section` will not be available, nor will the |
| | | template resource overriding capability explained in |
| | | :ref:`overriding_resources_section` be available, nor will it be |
| | | possible to use any template using that language as a |
| | | :term:`renderer`. However, it's reasonably easy to write custom |
| | | templating system binding packages for use under :mod:`pyramid` so |
| | | templating system binding packages for use under :app:`Pyramid` so |
| | | that templates written in the language can be used as renderers. |
| | | See :ref:`adding_and_overriding_renderers` for instructions on how |
| | | to create your own template renderer and |
| | |
| | | values are provided in a dictionary to the renderer and include: |
| | | |
| | | ``context`` |
| | | The current :mod:`pyramid` context if ``request`` was provided as |
| | | The current :app:`Pyramid` context if ``request`` was provided as |
| | | a keyword argument or ``None``. |
| | | |
| | | ``request`` |
| | |
| | | it possible to address template resources which live in another package. |
| | | |
| | | Not just any template from any arbitrary templating system may be used as a |
| | | renderer. Bindings must exist specifically for :mod:`pyramid` to use a |
| | | templating language template as a renderer. Currently, :mod:`pyramid` has |
| | | renderer. Bindings must exist specifically for :app:`Pyramid` to use a |
| | | templating language template as a renderer. Currently, :app:`Pyramid` has |
| | | built-in support for two Chameleon templating languages: ZPT and text, and |
| | | the Mako templating system. See :ref:`built_in_renderers` for a discussion |
| | | of their details. :mod:`pyramid` also supports the use of :term:`Jinja2` |
| | | of their details. :app:`Pyramid` also supports the use of :term:`Jinja2` |
| | | templates as renderers. See :ref:`available_template_system_bindings`. |
| | | |
| | | .. sidebar:: Why Use A Renderer via View Configuration |
| | |
| | | :term:`Chameleon` ZPT Templates |
| | | ------------------------------- |
| | | |
| | | Like :term:`Zope`, :mod:`pyramid` uses :term:`ZPT` (Zope Page |
| | | Like :term:`Zope`, :app:`Pyramid` uses :term:`ZPT` (Zope Page |
| | | Templates) as its default templating language. However, |
| | | :mod:`pyramid` uses a different implementation of the :term:`ZPT` |
| | | :app:`Pyramid` uses a different implementation of the :term:`ZPT` |
| | | specification than Zope does: the :term:`Chameleon` templating |
| | | engine. The Chameleon engine complies largely with the `Zope Page |
| | | Template <http://wiki.zope.org/ZPT/FrontPage>`_ template |
| | |
| | | ~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Here's what a simple :term:`Chameleon` ZPT template used under |
| | | :mod:`pyramid` might look like: |
| | | :app:`Pyramid` might look like: |
| | | |
| | | .. code-block:: xml |
| | | :linenos: |
| | |
| | | single: ZPT macros |
| | | single: Chameleon ZPT macros |
| | | |
| | | Using ZPT Macros in :mod:`pyramid` |
| | | Using ZPT Macros in :app:`Pyramid` |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | When a :term:`renderer` is used to render a template, |
| | | :mod:`pyramid` makes at least two top-level names available to the |
| | | :app:`Pyramid` makes at least two top-level names available to the |
| | | template by default: ``context`` and ``request``. One of the common |
| | | needs in ZPT-based templates is to use one template's "macros" from within |
| | | a different template. In Zope, this is typically handled by |
| | | retrieving the template from the ``context``. But having a hold of |
| | | the context in :mod:`pyramid` is not helpful: templates cannot |
| | | usually be retrieved from models. To use macros in :mod:`pyramid`, |
| | | the context in :app:`Pyramid` is not helpful: templates cannot |
| | | usually be retrieved from models. To use macros in :app:`Pyramid`, |
| | | you need to make the macro template itself available to the rendered |
| | | template by passing the template in which the macro is defined (or even |
| | | the macro itself) *into* the rendered template. To make a macro |
| | |
| | | Templating with :term:`Chameleon` Text Templates |
| | | ------------------------------------------------ |
| | | |
| | | :mod:`pyramid` also allows for the use of templates which are |
| | | :app:`Pyramid` also allows for the use of templates which are |
| | | composed entirely of non-XML text via :term:`Chameleon`. To do so, |
| | | you can create templates that are entirely composed of text except for |
| | | ``${name}`` -style substitution points. |
| | |
| | | --------------------------------------- |
| | | |
| | | The exceptions raised by Chameleon templates when a rendering fails |
| | | are sometimes less than helpful. :mod:`pyramid` allows you to |
| | | are sometimes less than helpful. :app:`Pyramid` allows you to |
| | | configure your application development environment so that exceptions |
| | | generated by Chameleon during template compilation and execution will |
| | | contain nicer debugging information. |
| | |
| | | Templating With Mako Templates |
| | | ------------------------------ |
| | | |
| | | :term:`Mako` is a templating system written by Mike Bayer. :mod:`pyramid` |
| | | :term:`Mako` is a templating system written by Mike Bayer. :app:`Pyramid` |
| | | has built-in bindings for the Mako templating system. The language |
| | | definition documentation for Mako templates is available from `the Mako |
| | | website <http://www.makotemplates.org/>`_. |
| | |
| | | A Sample Mako Template |
| | | ~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Here's what a simple :term:`Mako` template used under :mod:`pyramid` might |
| | | Here's what a simple :term:`Mako` template used under :app:`Pyramid` might |
| | | look like: |
| | | |
| | | .. code-block:: xml |
| | |
| | | |
| | | It's often convenient to see changes you make to a template file |
| | | appear immediately without needing to restart the application process. |
| | | :mod:`pyramid` allows you to configure your application development |
| | | :app:`Pyramid` allows you to configure your application development |
| | | environment so that a change to a template will be automatically |
| | | detected, and the template will be reloaded on the next rendering. |
| | | |
| | |
| | | Available Add-On Template System Bindings |
| | | ----------------------------------------- |
| | | |
| | | Jinja2 template bindings are available for :mod:`pyramid` in the |
| | | Jinja2 template bindings are available for :app:`Pyramid` in the |
| | | ``pyramid_jinja2`` package. It lives in the Pylons version control |
| | | repository at `http://github.com/Pylons/pyramid_jinja2 |
| | | <http://github.com/Pylons/pyramid_jinja2>`_. At the time of this writing, it |
| | |
| | | may receive a different value than another thread or process when that |
| | | variable is "thread local". |
| | | |
| | | When a request is processed, :mod:`pyramid` makes two :term:`thread |
| | | When a request is processed, :app:`Pyramid` makes two :term:`thread |
| | | local` variables available to the application: a "registry" and a |
| | | "request". |
| | | |
| | | Why and How :mod:`pyramid` Uses Thread Local Variables |
| | | Why and How :app:`Pyramid` Uses Thread Local Variables |
| | | --------------------------------------------------------- |
| | | |
| | | How are thread locals beneficial to :mod:`pyramid` and application |
| | | developers who use :mod:`pyramid`? Well, usually they're decidedly |
| | | How are thread locals beneficial to :app:`Pyramid` and application |
| | | developers who use :app:`Pyramid`? Well, usually they're decidedly |
| | | **not**. Using a global or a thread local variable in any application |
| | | usually makes it a lot harder to understand for a casual reader. Use |
| | | of a thread local or a global is usually just a way to avoid passing |
| | |
| | | bad idea, at least if code readability counts as an important concern. |
| | | |
| | | For historical reasons, however, thread local variables are indeed |
| | | consulted by various :mod:`pyramid` API functions. For example, |
| | | consulted by various :app:`Pyramid` API functions. For example, |
| | | the implementation of the :mod:`pyramid.security` function named |
| | | :func:`pyramid.security.authenticated_userid` retrieves the thread |
| | | local :term:`application registry` as a matter of course to find an |
| | |
| | | :func:`pyramid.threadlocal.get_current_registry` function to |
| | | retrieve the application registry, from which it looks up the |
| | | authentication policy; it then uses the authentication policy to |
| | | retrieve the authenticated user id. This is how :mod:`pyramid` |
| | | retrieve the authenticated user id. This is how :app:`Pyramid` |
| | | allows arbitrary authentication policies to be "plugged in". |
| | | |
| | | When they need to do so, :mod:`pyramid` internals use two API |
| | | When they need to do so, :app:`Pyramid` internals use two API |
| | | functions to retrieve the :term:`request` and :term:`application |
| | | registry`: :func:`pyramid.threadlocal.get_current_request` and |
| | | :func:`pyramid.threadlocal.get_current_registry`. The former |
| | |
| | | |
| | | These values are thread locals rather than true globals because one |
| | | Python process may be handling multiple simultaneous requests or even |
| | | multiple :mod:`pyramid` applications. If they were true globals, |
| | | :mod:`pyramid` could not handle multiple simultaneous requests or |
| | | allow more than one :mod:`pyramid` application instance to exist in |
| | | multiple :app:`Pyramid` applications. If they were true globals, |
| | | :app:`Pyramid` could not handle multiple simultaneous requests or |
| | | allow more than one :app:`Pyramid` application instance to exist in |
| | | a single Python process. |
| | | |
| | | Because one :mod:`pyramid` application is permitted to call |
| | | *another* :mod:`pyramid` application from its own :term:`view` code |
| | | Because one :app:`Pyramid` application is permitted to call |
| | | *another* :app:`Pyramid` application from its own :term:`view` code |
| | | (perhaps as a :term:`WSGI` app with help from the |
| | | :func:`pyramid.wsgi.wsgiapp2` decorator), these variables are |
| | | managed in a *stack* during normal system operations. The stack |
| | |
| | | and pop the threadlocal stack when the system is under test. See |
| | | :ref:`test_setup_and_teardown` for the definitions of these functions. |
| | | |
| | | Scripts which use :mod:`pyramid` machinery but never actually start |
| | | Scripts which use :app:`Pyramid` machinery but never actually start |
| | | a WSGI server or receive requests via HTTP such as scripts which use |
| | | the :mod:`pyramid.scripting` API will never cause any Router code |
| | | to be executed. However, the :mod:`pyramid.scripting` APIs also |
| | |
| | | - Neither ``get_current_request`` nor ``get_current_registry`` should |
| | | ever be called within application-specific forks of third-party |
| | | library code. The library you've forked almost certainly has |
| | | nothing to do with :mod:`pyramid`, and making it dependent on |
| | | :mod:`pyramid` (rather than making your :mod:`pyramid` |
| | | nothing to do with :app:`Pyramid`, and making it dependent on |
| | | :app:`Pyramid` (rather than making your :mod:`pyramid` |
| | | application depend upon it) means you're forming a dependency in the |
| | | wrong direction. |
| | | |
| | |
| | | |
| | | The contents of ``myfile`` are now printed on the user's behalf. |
| | | |
| | | :mod:`pyramid` is very much like this inexperienced UNIX user as it |
| | | :app:`Pyramid` is very much like this inexperienced UNIX user as it |
| | | uses :term:`traversal` against an object graph. In this analogy, we |
| | | can map the ``cat`` program to the :mod:`pyramid` concept of a |
| | | can map the ``cat`` program to the :app:`Pyramid` concept of a |
| | | :term:`view callable`: it is a program that can be run against some |
| | | :term:`context` as the result of :term:`view lookup`. The file being |
| | | operated on in this analogy is the :term:`context` object; the context |
| | |
| | | |
| | | The analogy we've used is not *exactly* correct, because, while the |
| | | naive user already knows which command he wants to invoke before he |
| | | starts "traversing" (``cat``), :mod:`pyramid` needs to obtain that |
| | | starts "traversing" (``cat``), :app:`Pyramid` needs to obtain that |
| | | information from the path being traversed itself. In |
| | | :term:`traversal`, the "command" meant to be invoked is a :term:`view |
| | | callable`. A view callable is derived via :term:`view lookup` from |
| | |
| | | |
| | | The combination of the :term:`context` object and the :term:`view |
| | | name` found via traversal is used later in the same request by a |
| | | separate :mod:`pyramid` subsystem -- the :term:`view lookup` |
| | | separate :app:`Pyramid` subsystem -- the :term:`view lookup` |
| | | subsystem -- to find a :term:`view callable` later within the same |
| | | request. How :mod:`pyramid` performs view lookup is explained |
| | | request. How :app:`Pyramid` performs view lookup is explained |
| | | within the :ref:`views_chapter` chapter. |
| | | |
| | | .. index:: |
| | |
| | | ---------------- |
| | | |
| | | When your application uses :term:`traversal` to resolve URLs to code, |
| | | your application must supply an *object graph* to :mod:`pyramid`. |
| | | your application must supply an *object graph* to :app:`Pyramid`. |
| | | This graph is represented by a :term:`root` object. |
| | | |
| | | In order to supply a root object for an application, at system startup |
| | | time, the :mod:`pyramid` :term:`Router` is configured with a |
| | | time, the :app:`Pyramid` :term:`Router` is configured with a |
| | | callback known as a :term:`root factory`. The root factory is |
| | | supplied by the application developer as the ``root_factory`` argument |
| | | to the application's :term:`Configurator`. |
| | |
| | | |
| | | Using the ``root_factory`` argument to a |
| | | :class:`pyramid.configuration.Configurator` constructor tells your |
| | | :mod:`pyramid` application to call this root factory to generate a |
| | | :app:`Pyramid` application to call this root factory to generate a |
| | | root object whenever a request enters the application. This root |
| | | factory is also known as the global root factory. A root factory can |
| | | alternately be passed to the ``Configurator`` as a :term:`dotted |
| | |
| | | object is often an instance of a class which has a ``__getitem__`` |
| | | method. |
| | | |
| | | If no :term:`root factory` is passed to the :mod:`pyramid` |
| | | If no :term:`root factory` is passed to the :app:`Pyramid` |
| | | :term:`Configurator` constructor, or the ``root_factory`` is specified |
| | | as the value ``None``, a *default* root factory is used. The default |
| | | root factory always returns an object that has no child nodes. |
| | |
| | | |
| | | Items contained within the object graph are sometimes analogous to the |
| | | concept of :term:`model` objects used by many other frameworks (and |
| | | :mod:`pyramid` APIs often refers to them as "models", as well). |
| | | :app:`Pyramid` APIs often refers to them as "models", as well). |
| | | They are typically instances of Python classes. |
| | | |
| | | The object graph consists of *container* nodes and *leaf* nodes. |
| | |
| | | The Traversal Algorithm |
| | | ----------------------- |
| | | |
| | | This section will attempt to explain the :mod:`pyramid` traversal |
| | | This section will attempt to explain the :app:`Pyramid` traversal |
| | | algorithm. We'll provide a description of the algorithm, a diagram of |
| | | how the algorithm works, and some example traversal scenarios that |
| | | might help you understand how the algorithm operates against a |
| | |
| | | We'll also talk a bit about :term:`view lookup`. The |
| | | :ref:`views_chapter` chapter discusses :term:`view lookup` in detail, |
| | | and it is the canonical source for information about views. |
| | | Technically, :term:`view lookup` is a :mod:`pyramid` subsystem that |
| | | Technically, :term:`view lookup` is a :app:`Pyramid` subsystem that |
| | | is separated from traversal entirely. However, we'll describe the |
| | | fundamental behavior of view lookup in the examples in the next few |
| | | sections to give you an idea of how traversal and view lookup |
| | |
| | | application, the system uses this algorithm to find a :term:`context` |
| | | and a :term:`view name`. |
| | | |
| | | #. The request for the page is presented to the :mod:`pyramid` |
| | | #. The request for the page is presented to the :app:`Pyramid` |
| | | :term:`router` in terms of a standard :term:`WSGI` request, which |
| | | is represented by a WSGI environment and a WSGI ``start_response`` |
| | | callable. |
| | |
| | | Once :term:`context` and :term:`view name` and associated attributes |
| | | such as the :term:`subpath` are located, the job of :term:`traversal` |
| | | is finished. It passes back the information it obtained to its |
| | | caller, the :mod:`pyramid` :term:`Router`, which subsequently |
| | | caller, the :app:`Pyramid` :term:`Router`, which subsequently |
| | | invokes :term:`view lookup` with the context and view name |
| | | information. |
| | | |
| | |
| | | the class ``Bar``. |
| | | |
| | | Let's say that view lookup finds no matching view type. In this |
| | | circumstance, the :mod:`pyramid` :term:`router` returns the result |
| | | circumstance, the :app:`Pyramid` :term:`router` returns the result |
| | | of the :term:`not found view` and the request ends. |
| | | |
| | | However, for this graph:: |
| | |
| | | ``context`` attribute of the request object, |
| | | e.g. ``request.context``. The :term:`view name` is available as |
| | | the ``view_name`` attribute of the request object, |
| | | e.g. ``request.view_name``. Other :mod:`pyramid` -specific |
| | | e.g. ``request.view_name``. Other :app:`Pyramid` -specific |
| | | request attributes are also available as described in |
| | | :ref:`special_request_attributes`. |
| | | |
| | |
| | | ---------- |
| | | |
| | | A tutorial showing how :term:`traversal` can be used within a |
| | | :mod:`pyramid` application exists in :ref:`bfg_wiki_tutorial`. |
| | | :app:`Pyramid` application exists in :ref:`bfg_wiki_tutorial`. |
| | | |
| | | See the :ref:`views_chapter` chapter for detailed information about |
| | | :term:`view lookup`. |
| | |
| | | expected to when your application is run in production. |
| | | |
| | | The suggested mechanism for unit and integration testing of a |
| | | :mod:`pyramid` application is the Python :mod:`unittest` module. |
| | | :app:`Pyramid` application is the Python :mod:`unittest` module. |
| | | Although this module is named :mod:`unittest`, it is actually capable |
| | | of driving both unit and integration tests. A good :mod:`unittest` |
| | | tutorial is available within `Dive Into Python |
| | | <http://diveintopython.org/unit_testing/index.html>`_ by Mark Pilgrim. |
| | | |
| | | :mod:`pyramid` provides a number of facilities that make unit and |
| | | :app:`Pyramid` provides a number of facilities that make unit and |
| | | integration tests easier to write. The facilities become particularly |
| | | useful when your code calls into :mod:`pyramid` -related framework |
| | | useful when your code calls into :app:`Pyramid` -related framework |
| | | functions. |
| | | |
| | | .. index:: |
| | |
| | | Test Set Up and Tear Down |
| | | -------------------------- |
| | | |
| | | :mod:`pyramid` uses a "global" (actually :term:`thread local`) data |
| | | :app:`Pyramid` uses a "global" (actually :term:`thread local`) data |
| | | structure to hold on to two items: the current :term:`request` and the |
| | | current :term:`application registry`. These data structures are |
| | | available via the :func:`pyramid.threadlocal.get_current_request` |
| | |
| | | these functions and the data structures they return. |
| | | |
| | | If your code uses these ``get_current_*`` functions or calls |
| | | :mod:`pyramid` code which uses ``get_current_*`` functions, you |
| | | :app:`Pyramid` code which uses ``get_current_*`` functions, you |
| | | will need to construct a :term:`Configurator` and call its ``begin`` |
| | | method within the ``setUp`` method of your unit test and call the same |
| | | configurator's ``end`` method within the ``tearDown`` method of your |
| | |
| | | testing, :func:`pyramid.threadlocal.get_current_request` will |
| | | return ``None``. We use a "dummy" request implementation supplied by |
| | | :class:`pyramid.testing.DummyRequest` because it's easier to |
| | | construct than a "real" :mod:`pyramid` request object. |
| | | construct than a "real" :app:`Pyramid` request object. |
| | | |
| | | What? |
| | | ~~~~~ |
| | |
| | | or "dummy" feature in place of the "real" feature that the code would |
| | | call if it was being run normally. |
| | | |
| | | For example, let's imagine you want to unit test a :mod:`pyramid` |
| | | For example, let's imagine you want to unit test a :app:`Pyramid` |
| | | view function. |
| | | |
| | | .. code-block:: python |
| | |
| | | |
| | | Without invoking any startup code or using the testing API, an attempt |
| | | to run this view function in a unit test will result in an error. |
| | | When a :mod:`pyramid` application starts normally, it will populate |
| | | When a :app:`Pyramid` application starts normally, it will populate |
| | | a :term:`application registry` using :term:`configuration declaration` |
| | | calls made against a :term:`Configurator` (sometimes deferring to the |
| | | application's ``configure.zcml`` :term:`ZCML` file via ``load_zcml``). |
| | |
| | | (e.g. with an :meth:`pyramid.configuration.Configurator.add_view` |
| | | :term:`configuration declaration` or ``view`` declarations in |
| | | :term:`ZCML`), like when you invoke application code via a unit test, |
| | | :mod:`pyramid` API functions will tend to fail. |
| | | :app:`Pyramid` API functions will tend to fail. |
| | | |
| | | The testing API provided by :mod:`pyramid` allows you to simulate |
| | | The testing API provided by :app:`Pyramid` allows you to simulate |
| | | various application registry registrations for use under a unit |
| | | testing framework without needing to invoke the actual application |
| | | configuration implied by its ``run.py``. For example, if you wanted |
| | |
| | | renderer.assert_(say='Yo') |
| | | |
| | | In the above example, we create a ``MyTest`` test case that inherits |
| | | from :mod:`unittest.TestCase`. If it's in our :mod:`pyramid` |
| | | from :mod:`unittest.TestCase`. If it's in our :app:`Pyramid` |
| | | application, it will be found when ``setup.py test`` is run. It has |
| | | two test methods. |
| | | |
| | |
| | | We then create a :class:`pyramid.testing.DummyRequest` object which |
| | | simulates a WebOb request object API. A |
| | | :class:`pyramid.testing.DummyRequest` is a request object that |
| | | requires less setup than a "real" :mod:`pyramid` request. We call |
| | | requires less setup than a "real" :app:`Pyramid` request. We call |
| | | the function being tested with the manufactured request. When the |
| | | function is called, |
| | | :func:`pyramid.chameleon_zpt.render_template_to_response` will call |
| | |
| | | ``tearDown``; these methods make sure you're using a "fresh" |
| | | :term:`application registry` per test run. |
| | | |
| | | See the :ref:`testing_module` chapter for the entire :mod:`pyramid` |
| | | See the :ref:`testing_module` chapter for the entire :app:`Pyramid` |
| | | -specific testing API. This chapter describes APIs for registering a |
| | | security policy, registering models at paths, registering event |
| | | listeners, registering views and view permissions, and classes |
| | |
| | | Creating Integration Tests |
| | | -------------------------- |
| | | |
| | | In :mod:`pyramid`, a *unit test* typically relies on "mock" or |
| | | In :app:`Pyramid`, a *unit test* typically relies on "mock" or |
| | | "dummy" implementations to give the code under test only enough |
| | | context to run. |
| | | |
| | | "Integration testing" implies another sort of testing. In the context |
| | | of a :mod:`pyramid`, integration test, the test logic tests the |
| | | of a :app:`Pyramid`, integration test, the test logic tests the |
| | | functionality of some code *and* its integration with the rest of the |
| | | :mod:`pyramid` framework. |
| | | :app:`Pyramid` framework. |
| | | |
| | | In :mod:`pyramid` applications that use :term:`ZCML`, you can |
| | | In :app:`Pyramid` applications that use :term:`ZCML`, you can |
| | | create an integration test by *loading its ZCML* in the test's setup |
| | | code. This causes the entire :mod:`pyramid` environment to be set |
| | | code. This causes the entire :app:`Pyramid` environment to be set |
| | | up and torn down as if your application was running "for real". This |
| | | is a heavy-hammer way of making sure that your tests have enough |
| | | context to run properly, and it tests your code's integration with the |
| | | rest of :mod:`pyramid`. |
| | | rest of :app:`Pyramid`. |
| | | |
| | | Let's demonstrate this by showing an integration test for a view. The |
| | | below test assumes that your application's package name is ``myapp``, |
| | |
| | | URL Dispatch |
| | | ============ |
| | | |
| | | The URL dispatch feature of :mod:`pyramid` allows you to either |
| | | The URL dispatch feature of :app:`Pyramid` allows you to either |
| | | augment or replace :term:`traversal` as a :term:`context finding` |
| | | mechanism, allowing URL pattern matching to have the "first crack" at |
| | | resolving a given URL to :term:`context` and :term:`view name`. |
| | |
| | | dispatch exclusively allows you to avoid thinking about your |
| | | application in terms of "contexts" and "view names" entirely. |
| | | |
| | | Many applications don't need :mod:`pyramid` features -- such as |
| | | Many applications don't need :app:`Pyramid` features -- such as |
| | | declarative security via an :term:`authorization policy` -- that |
| | | benefit from having any visible separation between :term:`context |
| | | finding` and :term:`view lookup`. To this end, URL dispatch provides |
| | | a handy syntax that allows you to effectively map URLs *directly* to |
| | | :term:`view` code in such a way that you needn't think about your |
| | | application in terms of "context finding" at all. This makes developing |
| | | a :mod:`pyramid` application seem more like developing an |
| | | a :app:`Pyramid` application seem more like developing an |
| | | application in a system that is "context-free", such as :term:`Pylons` |
| | | or :term:`Django`. |
| | | |
| | |
| | | ------------------------------- |
| | | |
| | | If route configuration is present in an application, the |
| | | :mod:`pyramid` :term:`Router` checks every incoming request against |
| | | :app:`Pyramid` :term:`Router` checks every incoming request against |
| | | an ordered set of URL matching patterns present in a *route map*. |
| | | |
| | | If any route pattern matches the information in the :term:`request` |
| | | provided to :mod:`pyramid`, a route-specific :term:`context` and |
| | | provided to :app:`Pyramid`, a route-specific :term:`context` and |
| | | :term:`view name` will be generated. In this circumstance, |
| | | :mod:`pyramid` will shortcut :term:`traversal`, and will invoke |
| | | :app:`Pyramid` will shortcut :term:`traversal`, and will invoke |
| | | :term:`view lookup` using the context and view name generated by URL |
| | | dispatch. If the matched route names a :term:`view callable` in its |
| | | configuration, that view callable will be invoked when view lookup is |
| | | performed. |
| | | |
| | | However, if no route pattern matches the information in the |
| | | :term:`request` provided to :mod:`pyramid`, it will fail over to |
| | | :term:`request` provided to :app:`Pyramid`, it will fail over to |
| | | using :term:`traversal` to perform context finding and view lookup. |
| | | |
| | | Route Configuration |
| | |
| | | :term:`Route configuration` is the act of adding a new :term:`route` |
| | | to an application. A route has a *pattern*, representing a pattern |
| | | meant to match against the ``PATH_INFO`` portion of a URL, and a |
| | | *name*, which is used by developers within a :mod:`pyramid` |
| | | *name*, which is used by developers within a :app:`Pyramid` |
| | | application to uniquely identify a particular route when generating a |
| | | URL. It also optionally has a ``factory``, a set of :term:`route |
| | | predicate` parameters, and a set of :term:`view` parameters. |
| | |
| | | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| | | |
| | | When a ``view`` attribute is attached to a route configuration, |
| | | :mod:`pyramid` ensures that a :term:`view configuration` is |
| | | :app:`Pyramid` ensures that a :term:`view configuration` is |
| | | registered that will always be found when the route pattern is matched |
| | | during a request. To do so: |
| | | |
| | |
| | | to service requests that match the route pattern. |
| | | |
| | | In this way, we supply a shortcut to the developer. Under the hood, |
| | | :mod:`pyramid` still consumes the :term:`context finding` and |
| | | :term:`view lookup` subsystems provided by :mod:`pyramid`, but in a |
| | | :app:`Pyramid` still consumes the :term:`context finding` and |
| | | :term:`view lookup` subsystems provided by :app:`Pyramid`, but in a |
| | | way which does not require that a developer understand either of them |
| | | if he doesn't want or need to. It also means that we can allow a |
| | | developer to combine :term:`URL dispatch` and :term:`traversal` in |
| | |
| | | Route Pattern Syntax |
| | | ~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | The syntax of the pattern matching language used by :mod:`pyramid` |
| | | The syntax of the pattern matching language used by :app:`Pyramid` |
| | | URL dispatch in the *pattern* argument is straightforward; it is close |
| | | to that of the :term:`Routes` system used by :term:`Pylons`. |
| | | |
| | |
| | | related to each particular route. |
| | | |
| | | Supplying a different context for each route is useful when you're |
| | | trying to use a :mod:`pyramid` :term:`authorization policy` to |
| | | trying to use a :app:`Pyramid` :term:`authorization policy` to |
| | | provide declarative "context-sensitive" security checks; each context |
| | | can maintain a separate :term:`ACL`, as in |
| | | :ref:`using_security_with_urldispatch`. It is also useful when you |
| | |
| | | ``factory`` |
| | | A Python object (often a function or a class) or a :term:`dotted |
| | | Python name` to such an object that will generate a |
| | | :mod:`pyramid` :term:`context` object when this route |
| | | :app:`Pyramid` :term:`context` object when this route |
| | | matches. For example, ``mypackage.models.MyFactoryClass``. If this |
| | | argument is not specified, the traversal root factory will be used. |
| | | |
| | |
| | | the ``PATH_INFO`` present in the WSGI environment provided during a |
| | | request against a URL path pattern. |
| | | |
| | | The way that :mod:`pyramid` does this is very simple. When a |
| | | The way that :app:`Pyramid` does this is very simple. When a |
| | | request enters the system, for each route configuration declaration |
| | | present in the system, :mod:`pyramid` checks the ``PATH_INFO`` |
| | | present in the system, :app:`Pyramid` checks the ``PATH_INFO`` |
| | | against the pattern declared. |
| | | |
| | | If any route matches, the route matching process stops. The |
| | |
| | | routes. |
| | | |
| | | If no route matches after all route patterns are exhausted, |
| | | :mod:`pyramid` falls back to :term:`traversal` to do :term:`context |
| | | :app:`Pyramid` falls back to :term:`traversal` to do :term:`context |
| | | finding` and :term:`view lookup`. |
| | | |
| | | .. index:: |
| | |
| | | config.add_route('user', 'users/:user', view='mypackage.views.user_view') |
| | | config.add_route('tag', 'tags/:tags', view='mypackage.views.tag_view') |
| | | |
| | | The above configuration will allow :mod:`pyramid` to service URLs |
| | | The above configuration will allow :app:`Pyramid` to service URLs |
| | | in these forms: |
| | | |
| | | .. code-block:: text |
| | |
| | | Custom Not Found View With Slash Appended Routes |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | There can only be one :term:`Not Found view` in any :mod:`pyramid` |
| | | There can only be one :term:`Not Found view` in any :app:`Pyramid` |
| | | application. Even if you use |
| | | :func:`pyramid.view.append_slash_notfound_view` as the Not Found |
| | | view, :mod:`pyramid` still must generate a ``404 Not Found`` |
| | | view, :app:`Pyramid` still must generate a ``404 Not Found`` |
| | | response when it cannot redirect to a slash-appended URL; this not |
| | | found response will be visible to site users. |
| | | |
| | |
| | | you can cause a subscriber to be fired when a new request is detected; |
| | | the subscriber can do this work. |
| | | |
| | | For example, let's say you have a ``mypackage`` :mod:`pyramid` |
| | | For example, let's say you have a ``mypackage`` :app:`Pyramid` |
| | | application package that uses SQLAlchemy, and you'd like the current |
| | | SQLAlchemy database session to be removed after each request. Put the |
| | | following in the ``mypackage.run`` module: |
| | |
| | | .. note:: This is only an example. In particular, it is not necessary |
| | | to cause ``DBSession.remove`` to be called as the result of an |
| | | event listener in an application generated from any |
| | | :mod:`pyramid` paster template, because these all use the |
| | | :app:`Pyramid` paster template, because these all use the |
| | | ``repoze.tm2`` middleware. The cleanup done by |
| | | ``DBSession.remove`` is unnecessary when ``repoze.tm2`` middleware |
| | | is in the WSGI pipeline. |
| | |
| | | |
| | | .. _using_security_with_urldispatch: |
| | | |
| | | Using :mod:`pyramid` Security With URL Dispatch |
| | | Using :app:`Pyramid` Security With URL Dispatch |
| | | -------------------------------------------------- |
| | | |
| | | :mod:`pyramid` provides its own security framework which consults an |
| | | :app:`Pyramid` provides its own security framework which consults an |
| | | :term:`authorization policy` before allowing any application code to |
| | | be called. This framework operates in terms of an access control |
| | | list, which is stored as an ``__acl__`` attribute of a context object. |
| | |
| | | self.__acl__ = [ (Allow, 'editor', 'view') ] |
| | | |
| | | If the route ``archives/:article`` is matched, and the article number |
| | | is ``1``, :mod:`pyramid` will generate an ``Article`` |
| | | is ``1``, :app:`Pyramid` will generate an ``Article`` |
| | | :term:`context` with an ACL on it that allows the ``editor`` principal |
| | | the ``view`` permission. Obviously you can do more generic things |
| | | than inspect the routes match dict to see if the ``article`` argument |
| | |
| | | not very ambitious. |
| | | |
| | | .. note:: See :ref:`security_chapter` for more information about |
| | | :mod:`pyramid` security and ACLs. |
| | | :app:`Pyramid` security and ACLs. |
| | | |
| | | References |
| | | ---------- |
| | | |
| | | A tutorial showing how :term:`URL dispatch` can be used to create a |
| | | :mod:`pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`. |
| | | :app:`Pyramid` application exists in :ref:`bfg_sql_wiki_tutorial`. |
| | | |
| | |
| | | Virtual Hosting |
| | | =============== |
| | | |
| | | "Virtual hosting" is, loosely, the act of serving a :mod:`pyramid` |
| | | application or a portion of a :mod:`pyramid` application under a |
| | | "Virtual hosting" is, loosely, the act of serving a :app:`Pyramid` |
| | | application or a portion of a :app:`Pyramid` application under a |
| | | URL space that it does not "naturally" inhabit. |
| | | |
| | | :mod:`pyramid` provides facilities for serving an application under |
| | | :app:`Pyramid` provides facilities for serving an application under |
| | | a URL "prefix", as well as serving a *portion* of a :term:`traversal` |
| | | based application under a root URL. |
| | | |
| | | Hosting an Application Under a URL Prefix |
| | | ----------------------------------------- |
| | | |
| | | :mod:`pyramid` supports a common form of virtual hosting whereby you |
| | | can host a :mod:`pyramid` application as a "subset" of some other site |
| | | :app:`Pyramid` supports a common form of virtual hosting whereby you |
| | | can host a :app:`Pyramid` application as a "subset" of some other site |
| | | (e.g. under ``http://example.com/mypyramidapplication/`` as opposed to |
| | | under ``http://example.com/``). |
| | | |
| | |
| | | hosting translation for you "under the hood". |
| | | |
| | | If you use the ``urlmap`` composite application "in front" of a |
| | | :mod:`pyramid` application or if you use :term:`mod_wsgi` to serve |
| | | up a :mod:`pyramid` application, nothing special needs to be done |
| | | :app:`Pyramid` application or if you use :term:`mod_wsgi` to serve |
| | | up a :app:`Pyramid` application, nothing special needs to be done |
| | | within the application for URLs to be generated that contain a |
| | | prefix. :mod:`paste.urlmap` and :term:`mod_wsgi` manipulate the |
| | | :term:`WSGI` environment in such a way that the ``PATH_INFO`` and |
| | |
| | | use = egg:Paste#urlmap |
| | | /pyramidapp = mypyramidapp |
| | | |
| | | This "roots" the :mod:`pyramid` application at the prefix |
| | | This "roots" the :app:`Pyramid` application at the prefix |
| | | ``/pyramidapp`` and serves up the composite as the "main" application |
| | | in the file. |
| | | |
| | |
| | | |
| | | WSGIScriptAlias /pyramidapp /Users/chrism/projects/modwsgi/env/pyramid.wsgi |
| | | |
| | | In the above configuration, we root a :mod:`pyramid` application at |
| | | In the above configuration, we root a :app:`Pyramid` application at |
| | | ``/pyramidapp`` within the Apache configuration. |
| | | |
| | | .. index:: |
| | |
| | | Virtual Root Support |
| | | -------------------- |
| | | |
| | | :mod:`pyramid` also supports "virtual roots", which can be used in |
| | | :app:`Pyramid` also supports "virtual roots", which can be used in |
| | | :term:`traversal` -based (but not :term:`URL dispatch` -based) |
| | | applications. |
| | | |
| | | Virtual root support is useful when you'd like to host some model in a |
| | | :mod:`pyramid` object graph as an application under a URL pathname |
| | | :app:`Pyramid` object graph as an application under a URL pathname |
| | | that does not include the model path itself. For example, you might |
| | | want to serve the object at the traversal path ``/cms`` as an |
| | | application reachable via ``http://example.com/`` (as opposed to |
| | |
| | | <http://httpd.apache.org/docs/2.2/mod/mod_headers.html>`_ module be |
| | | available in the Apache environment you're using. |
| | | |
| | | For a :mod:`pyramid` application running under :term:`mod_wsgi`, |
| | | For a :app:`Pyramid` application running under :term:`mod_wsgi`, |
| | | the same can be achieved using ``SetEnv``: |
| | | |
| | | .. code-block:: apache |
| | |
| | | virtual root has been specified). |
| | | |
| | | :ref:`modwsgi_tutorial` has detailed information about using |
| | | :term:`mod_wsgi` to serve :mod:`pyramid` applications. |
| | | :term:`mod_wsgi` to serve :app:`Pyramid` applications. |
| | | |
| | |
| | | Views |
| | | ===== |
| | | |
| | | The primary job of any :mod:`pyramid` application is is to find and |
| | | The primary job of any :app:`Pyramid` application is is to find and |
| | | invoke a :term:`view callable` when a :term:`request` reaches the |
| | | application. View callables are bits of code written by you -- the |
| | | application developer -- which do something interesting in response to |
| | |
| | | |
| | | .. note:: |
| | | |
| | | A :mod:`pyramid` :term:`view callable` is often referred to in |
| | | A :app:`Pyramid` :term:`view callable` is often referred to in |
| | | conversational shorthand as a :term:`view`. In this documentation, |
| | | however, we need to use less ambiguous terminology because there |
| | | are significant differences between view *configuration*, the code |
| | |
| | | -------------- |
| | | |
| | | No matter how a view callable is eventually found, all view callables |
| | | used by :mod:`pyramid` must be constructed in the same way, and |
| | | used by :app:`Pyramid` must be constructed in the same way, and |
| | | must return the same kind of return value. |
| | | |
| | | Most view callables accept a single argument named ``request``. This argument |
| | | represents a :mod:`pyramid` :term:`Request` object. A request object |
| | | encapsulates a WSGI environment as represented to :mod:`pyramid` by the |
| | | represents a :app:`Pyramid` :term:`Request` object. A request object |
| | | encapsulates a WSGI environment as represented to :app:`Pyramid` by the |
| | | upstream :term:`WSGI` server. |
| | | |
| | | A view callable may always return a :mod:`Pyramid` :term:`Response` object |
| | |
| | | will be a :term:`model` object. |
| | | |
| | | request |
| | | A :mod:`pyramid` Request object representing the current WSGI |
| | | A :app:`Pyramid` Request object representing the current WSGI |
| | | request. |
| | | |
| | | The following types work as view callables in this style: |
| | |
| | | View Callable Responses |
| | | ~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | A view callable may always return an object that implements the :mod:`pyramid` |
| | | A view callable may always return an object that implements the :app:`Pyramid` |
| | | :term:`Response` interface. The easiest way to return something that |
| | | implements the :term:`Response` interface is to return a |
| | | :class:`pyramid.response.Response` object instance directly. For example: |
| | |
| | | return Response('OK') |
| | | |
| | | You don't need to always use :class:`pyramid.response.Response` to represent a |
| | | response. :mod:`pyramid` provides a range of different "exception" classes |
| | | response. :app:`Pyramid` provides a range of different "exception" classes |
| | | which can act as response objects too. For example, an instance of the class |
| | | :class:`pyramid.httpexceptions.HTTPFound` is also a valid response object (see |
| | | :ref:`http_redirect`). A view can actually return any object that has the |
| | |
| | | |
| | | Furthermore, a view needn't *always* return a Response object. If a view |
| | | happens to return something which does not implement the Pyramid Response |
| | | interface, :mod:`pyramid` will attempt to use a :term:`renderer` to construct a |
| | | interface, :app:`Pyramid` will attempt to use a :term:`renderer` to construct a |
| | | response. For example: |
| | | |
| | | .. code-block:: python |
| | |
| | | If the :term:`view callable` associated with a :term:`view configuration` |
| | | returns a Response object directly (an object with the attributes ``status``, |
| | | ``headerlist`` and ``app_iter``), any renderer associated with the view |
| | | configuration is ignored, and the response is passed back to :mod:`pyramid` |
| | | configuration is ignored, and the response is passed back to :app:`Pyramid` |
| | | unmolested. For example, if your view callable returns an instance of the |
| | | :class:`pyramid.httpexceptions.HTTPFound` class as a response, no renderer will |
| | | be employed. |
| | |
| | | Built-In Renderers |
| | | ~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Several built-in "renderers" exist in :mod:`pyramid`. These |
| | | Several built-in "renderers" exist in :app:`Pyramid`. These |
| | | renderers can be used in the ``renderer`` attribute of view |
| | | configurations. |
| | | |
| | |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Before a response that is constructed as the result of the use of a |
| | | :term:`renderer` is returned to :mod:`pyramid`, several attributes |
| | | :term:`renderer` is returned to :app:`Pyramid`, several attributes |
| | | of the request are examined which have the potential to influence |
| | | response behavior. |
| | | |
| | |
| | | Adding and Overriding Renderers |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | New templating systems and serializers can be associated with :mod:`pyramid` |
| | | New templating systems and serializers can be associated with :app:`Pyramid` |
| | | renderer names. To this end, configuration declarations can be made which |
| | | override an existing :term:`renderer factory` and which add a new renderer |
| | | factory. |
| | |
| | | |
| | | config.add_renderer('.zpt', 'pyramid.chameleon_zpt.renderer_factory') |
| | | |
| | | After you do this, :mod:`pyramid` will treat templates ending in both the |
| | | After you do this, :app:`Pyramid` will treat templates ending in both the |
| | | ``.pt`` and ``.zpt`` filename extensions as Chameleon ZPT templates. |
| | | |
| | | To override the default mapping in which files with a ``.pt`` extension are |
| | |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Usually when a Python exception is raised within a view callable, |
| | | :mod:`pyramid` allows the exception to propagate all the way out to |
| | | :app:`Pyramid` allows the exception to propagate all the way out to |
| | | the :term:`WSGI` server which invoked the application. |
| | | |
| | | However, for convenience, two special exceptions exist which are |
| | | always handled by :mod:`pyramid` itself. These are |
| | | always handled by :app:`Pyramid` itself. These are |
| | | :exc:`pyramid.exceptions.NotFound` and |
| | | :exc:`pyramid.exceptions.Forbidden`. Both are exception classes |
| | | which accept a single positional constructor argument: a ``message``. |
| | |
| | | agent which performed the request. |
| | | |
| | | In all cases, the message provided to the exception constructor is |
| | | made available to the view which :mod:`pyramid` invokes as |
| | | made available to the view which :app:`Pyramid` invokes as |
| | | ``request.exception.args[0]``. |
| | | |
| | | .. index:: |
| | |
| | | developers to convert arbitrary exceptions to responses. |
| | | |
| | | To register a view that should be called whenever a particular |
| | | exception is raised from with :mod:`pyramid` view code, use the |
| | | exception is raised from with :app:`Pyramid` view code, use the |
| | | exception class or one of its superclasses as the ``context`` of a |
| | | view configuration which points at a view callable you'd like to |
| | | generate a response. |
| | |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Most web applications need to accept form submissions from web |
| | | browsers and various other clients. In :mod:`pyramid`, form |
| | | browsers and various other clients. In :app:`Pyramid`, form |
| | | submission handling logic is always part of a :term:`view`. For a |
| | | general overview of how to handle form submission data using the |
| | | :term:`WebOb` API, see :ref:`webob_chapter` and `"Query and POST |
| | | variables" within the WebOb documentation |
| | | <http://pythonpaste.org/webob/reference.html#query-post-variables>`_. |
| | | :mod:`pyramid` defers to WebOb for its request and response |
| | | :app:`Pyramid` defers to WebOb for its request and response |
| | | implementations, and handling form submission data is a property of |
| | | the request implementation. Understanding WebOb's request API is the |
| | | key to understanding how to process form submission data. |
| | | |
| | | There are some defaults that you need to be aware of when trying to handle form |
| | | submission data in a :mod:`pyramid` view. Because having high-order |
| | | submission data in a :app:`Pyramid` view. Because having high-order |
| | | (non-ASCII) characters in data contained within form submissions is exceedingly |
| | | common, and because the UTF-8 encoding is the most common encoding used on the |
| | | web for non-ASCII character data, and because working and storing Unicode |
| | | values is much saner than working with and storing bytestrings, :mod:`pyramid` |
| | | values is much saner than working with and storing bytestrings, :app:`Pyramid` |
| | | configures the :term:`WebOb` request machinery to attempt to decode form |
| | | submission values into Unicode from the UTF-8 character set implicitly. This |
| | | implicit decoding happens when view code obtains form field values via the |
| | |
| | | :ref:`request_module` for details about these APIs). |
| | | |
| | | For example, let's assume that the following form page is served up to |
| | | a browser client, and its ``action`` points at some :mod:`pyramid` |
| | | a browser client, and its ``action`` points at some :app:`Pyramid` |
| | | view code: |
| | | |
| | | .. code-block:: xml |
| | |
| | | </form> |
| | | </html> |
| | | |
| | | The ``myview`` view code in the :mod:`pyramid` application *must* |
| | | The ``myview`` view code in the :app:`Pyramid` application *must* |
| | | expect that the values returned by ``request.params`` will be of type |
| | | ``unicode``, as opposed to type ``str``. The following will work to |
| | | accept a form post from the above form: |
| | |
| | | lastname = request.params['lastname'].decode('utf-8') |
| | | |
| | | For implicit decoding to work reliably, you should ensure that every form you |
| | | render that posts to a :mod:`pyramid` view is rendered via a response that has |
| | | render that posts to a :app:`Pyramid` view is rendered via a response that has |
| | | a ``;charset=UTF-8`` in its ``Content-Type`` header; or, as in the form above, |
| | | with a ``meta http-equiv`` tag that implies that the charset is UTF-8 within |
| | | the HTML ``head`` of the page containing the form. This must be done |
| | |
| | | |
| | | .. note:: Only the *values* of request params obtained via |
| | | ``request.params``, ``request.GET`` or ``request.POST`` are decoded |
| | | to Unicode objects implicitly in the :mod:`pyramid` default |
| | | to Unicode objects implicitly in the :app:`Pyramid` default |
| | | configuration. The keys are still strings. |
| | | |
| | | .. index:: |
| | |
| | | ----------------------------------------------- |
| | | |
| | | A developer makes a :term:`view callable` available for use within a |
| | | :mod:`pyramid` application via :term:`view configuration`. A view |
| | | :app:`Pyramid` application via :term:`view configuration`. A view |
| | | configuration associates a view callable with a set of statements |
| | | about the set of circumstances which must be true for the view |
| | | callable to be invoked. |
| | |
| | | |
| | | The ``renderer`` attribute is optional. If it is not defined, the |
| | | "null" renderer is assumed (no rendering is performed and the value |
| | | is passed back to the upstream :mod:`pyramid` machinery |
| | | is passed back to the upstream :app:`Pyramid` machinery |
| | | unmolested). Note that if the view callable itself returns a |
| | | :term:`response` (see :ref:`the_response`), the specified renderer |
| | | implementation is never called. |
| | |
| | | configuration`, like ZCML, but in decorator form. |
| | | :class:`pyramid.view.view_config` can be used to associate :term:`view |
| | | configuration` information -- as done via the equivalent imperative code or |
| | | ZCML -- with a function that acts as a :mod:`pyramid` view callable. All |
| | | ZCML -- with a function that acts as a :app:`Pyramid` view callable. All |
| | | arguments to the :meth:`pyramid.configuration.Configurator.add_view` method |
| | | (save for the ``view`` argument) are available in decorator form and mean |
| | | precisely the same thing. |
| | | |
| | | An example of the :class:`pyramid.view.view_config` decorator might |
| | | reside in a :mod:`pyramid` application module ``views.py``: |
| | | reside in a :app:`Pyramid` application module ``views.py``: |
| | | |
| | | .. ignore-next-block |
| | | .. code-block:: python |
| | |
| | | route name / containment. |
| | | |
| | | The mere existence of a ``@view_config`` decorator doesn't suffice to perform |
| | | view configuration. To make :mod:`pyramid` process your |
| | | view configuration. To make :app:`Pyramid` process your |
| | | :class:`pyramid.view.view_config` declarations, you *must* do use the |
| | | ``scan`` method of a :class:`pyramid.configuration.Configurator`: |
| | | |
| | |
| | | View Lookup and Invocation |
| | | -------------------------- |
| | | |
| | | :term:`View lookup` is the :mod:`pyramid` subsystem responsible for |
| | | :term:`View lookup` is the :app:`Pyramid` subsystem responsible for |
| | | finding an invoking a :term:`view callable`. The view lookup |
| | | subsystem is passed a :term:`context`, a :term:`view name`, and the |
| | | :term:`request` object. These three bits of information are referred |
| | |
| | | found and evaluated before a view with two, for example. All |
| | | predicates must match for the associated view to be called. |
| | | |
| | | This does not mean however, that :mod:`pyramid` "stops looking" |
| | | This does not mean however, that :app:`Pyramid` "stops looking" |
| | | when it finds a view registration with predicates that don't match. |
| | | If one set of view predicates does not match, the "next most specific" |
| | | view (if any) view is consulted for predicates, and so on, until a |
| | |
| | | environment will be invoked. |
| | | |
| | | If no view can be found which has predicates which allow it to be |
| | | matched up with the request, :mod:`pyramid` will return an error to |
| | | matched up with the request, :app:`Pyramid` will return an error to |
| | | the user's browser, representing a "not found" (404) page. See |
| | | :ref:`changing_the_notfound_view` for more information about changing |
| | | the default notfound view. |
| | |
| | | .. note:: This chapter is adapted from a portion of the :term:`WebOb` |
| | | documentation, originally written by Ian Bicking. |
| | | |
| | | :mod:`pyramid` uses the :term:`WebOb` package to supply |
| | | :app:`Pyramid` uses the :term:`WebOb` package to supply |
| | | :term:`request` and :term:`response` object implementations. The |
| | | :term:`request` object that is passed to a :mod:`pyramid` |
| | | :term:`request` object that is passed to a :app:`Pyramid` |
| | | :term:`view` is an instance of the :class:`pyramid.request.Request` |
| | | class, which is a subclass of :class:`webob.Request`. The |
| | | :term:`response` returned from a :mod:`pyramid` :term:`view` |
| | | :term:`response` returned from a :app:`Pyramid` :term:`view` |
| | | :term:`renderer` is an instance of the :mod:`webob.Response` class. |
| | | Users can also return an instance of :mod:`webob.Response` directly |
| | | from a view as necessary. |
| | | |
| | | WebOb is a project separate from :mod:`pyramid` with a separate set |
| | | WebOb is a project separate from :app:`Pyramid` with a separate set |
| | | of authors and a fully separate `set of documentation |
| | | <http://pythonpaste.org/webob/>`_. |
| | | |
| | |
| | | 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 :mod:`pyramid` |
| | | cover that use case in this document, as users of :app:`Pyramid` |
| | | don't typically need to use the WSGI-related features of WebOb |
| | | directly. The `reference documentation |
| | | <http://pythonpaste.org/webob/reference.html>`_ shows many examples of |
| | |
| | | <http://python.org/doc/current/lib/datetime-datetime.html>`_ object |
| | | (or None if the header is was not provided). |
| | | |
| | | .. note:: Full API documentation for the :mod:`pyramid` request |
| | | .. note:: Full API documentation for the :app:`Pyramid` request |
| | | object is available in :ref:`request_module`. |
| | | |
| | | .. index:: |
| | |
| | | |
| | | .. _special_request_attributes: |
| | | |
| | | Special Attributes Added to the Request by :mod:`pyramid` |
| | | Special Attributes Added to the Request by :app:`Pyramid` |
| | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| | | |
| | | In addition to the standard :term:`WebOb` attributes, :mod:`pyramid` |
| | | In addition to the standard :term:`WebOb` attributes, :app:`Pyramid` |
| | | adds special attributes to every request: ``context``, ``registry``, |
| | | ``root``, ``subpath``, ``traversed``, ``view_name``, ``virtual_root`` |
| | | , ``virtual_root_path``, ``session``, and ``tmpl_context``. These |
| | |
| | | - The `WebOb documentation <http://pythonpaste.org/webob>`_ . All |
| | | methods and attributes of a ``webob.Request`` documented within the |
| | | WebOb documentation will work against request objects created by |
| | | :mod:`pyramid`. |
| | | :app:`Pyramid`. |
| | | |
| | | .. index:: |
| | | single: response object |
| | |
| | | Response |
| | | ~~~~~~~~ |
| | | |
| | | The :mod:`pyramid` response object can be imported as |
| | | The :app:`Pyramid` response object can be imported as |
| | | :class:`pyramid.response.Response`. This import location is merely a facade |
| | | for its original location: ``webob.Response``. |
| | | |
| | |
| | | To facilitate error responses like ``404 Not Found``, the module |
| | | :mod:`webob.exc` contains classes for each kind of error response. These |
| | | include boring but appropriate error bodies. The exceptions exposed by this |
| | | module, when used under :mod:`pyramid`, should be imported from the |
| | | module, when used under :app:`Pyramid`, should be imported from the |
| | | :mod:`pyramid.httpexceptions` "facade" module. This import location is merely |
| | | a facade for the original location of these exceptions: ``webob.exc``. |
| | | |
| | |
| | | |
| | | .. _zca_chapter: |
| | | |
| | | Using the Zope Component Architecture in :mod:`pyramid` |
| | | Using the Zope Component Architecture in :app:`Pyramid` |
| | | ========================================================== |
| | | |
| | | Under the hood, :mod:`pyramid` uses a :term:`Zope Component |
| | | Under the hood, :app:`Pyramid` uses a :term:`Zope Component |
| | | Architecture` component registry as its :term:`application registry`. |
| | | The Zope Component Architecture is referred to colloquially as the |
| | | "ZCA." |
| | |
| | | code is high. |
| | | |
| | | While the ZCA is an excellent tool with which to build a *framework* |
| | | such as :mod:`pyramid`, it is not always the best tool with which |
| | | such as :app:`Pyramid`, it is not always the best tool with which |
| | | to build an *application* due to the opacity of the ``zope.component`` |
| | | APIs. Accordingly, :mod:`pyramid` tends to hide the the presence |
| | | APIs. Accordingly, :app:`Pyramid` tends to hide the the presence |
| | | of the ZCA from application developers. You needn't understand the |
| | | ZCA to create a :mod:`pyramid` application; its use is effectively |
| | | ZCA to create a :app:`Pyramid` application; its use is effectively |
| | | only a framework implementation detail. |
| | | |
| | | However, developers who are already used to writing :term:`Zope` |
| | | applications often still wish to use the ZCA while building a |
| | | :mod:`pyramid` application; :mod:`pyramid` makes this possible. |
| | | :app:`Pyramid` application; :mod:`pyramid` makes this possible. |
| | | |
| | | .. index:: |
| | | single: get_current_registry |
| | |
| | | single: getSiteManager |
| | | single: ZCA global API |
| | | |
| | | Using the ZCA Global API in a :mod:`pyramid` Application |
| | | Using the ZCA Global API in a :app:`Pyramid` Application |
| | | ----------------------------------------------------------- |
| | | |
| | | :term:`Zope` uses a single ZCA registry -- the "global" ZCA registry |
| | |
| | | |
| | | Most production Zope applications are relatively large, making it |
| | | impractical due to memory constraints to run more than one Zope |
| | | application per Python process. However, a :mod:`pyramid` |
| | | application per Python process. However, a :app:`Pyramid` |
| | | application may be very small and consume very little memory, so it's |
| | | a reasonable goal to be able to run more than one BFG application per |
| | | process. |
| | | |
| | | In order to make it possible to run more than one :mod:`pyramid` |
| | | application in a single process, :mod:`pyramid` defaults to using a |
| | | In order to make it possible to run more than one :app:`Pyramid` |
| | | application in a single process, :app:`Pyramid` defaults to using a |
| | | separate ZCA registry *per application*. |
| | | |
| | | While this services a reasonable goal, it causes some issues when |
| | | trying to use patterns which you might use to build a typical |
| | | :term:`Zope` application to build a :mod:`pyramid` application. |
| | | :term:`Zope` application to build a :app:`Pyramid` application. |
| | | Without special help, ZCA "global" APIs such as |
| | | ``zope.component.getUtility`` and ``zope.component.getSiteManager`` |
| | | will use the ZCA "global" registry. Therefore, these APIs |
| | | will appear to fail when used in a :mod:`pyramid` application, |
| | | will appear to fail when used in a :app:`Pyramid` application, |
| | | because they'll be consulting the ZCA global registry rather than the |
| | | component registry associated with your :mod:`pyramid` application. |
| | | component registry associated with your :app:`Pyramid` application. |
| | | |
| | | There are three ways to fix this: by disusing the ZCA global API |
| | | entirely, by using |
| | |
| | | |
| | | If you are willing to disuse the "global" ZCA APIs and use the method |
| | | interface of a registry instead, you need only know how to obtain the |
| | | :mod:`pyramid` component registry. |
| | | :app:`Pyramid` component registry. |
| | | |
| | | There are two ways of doing so: |
| | | |
| | | - use the :func:`pyramid.threadlocal.get_current_registry` |
| | | function within :mod:`pyramid` view or model code. This will |
| | | always return the "current" :mod:`pyramid` application registry. |
| | | function within :app:`Pyramid` view or model code. This will |
| | | always return the "current" :app:`Pyramid` application registry. |
| | | |
| | | - use the attribute of the :term:`request` object named ``registry`` |
| | | in your :mod:`pyramid` view code, eg. ``request.registry``. This |
| | | in your :app:`Pyramid` view code, eg. ``request.registry``. This |
| | | is the ZCA component registry related to the running |
| | | :mod:`pyramid` application. |
| | | :app:`Pyramid` application. |
| | | |
| | | See :ref:`threadlocals_chapter` for more information about |
| | | :func:`pyramid.threadlocal.get_current_registry`. |
| | |
| | | Enabling the ZCA Global API by Using ``hook_zca`` |
| | | +++++++++++++++++++++++++++++++++++++++++++++++++ |
| | | |
| | | Consider the following bit of idiomatic :mod:`pyramid` startup code: |
| | | Consider the following bit of idiomatic :app:`Pyramid` startup code: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | |
| | | from pyramid.threadlocal import get_current_registry |
| | | getSiteManager.sethook(get_current_registry) |
| | | |
| | | This causes the ZCA global API to start using the :mod:`pyramid` |
| | | application registry in threads which are running a :mod:`pyramid` |
| | | This causes the ZCA global API to start using the :app:`Pyramid` |
| | | application registry in threads which are running a :app:`Pyramid` |
| | | request. |
| | | |
| | | Calling ``hook_zca`` is usually sufficient to "fix" the problem of |
| | | being able to use the global ZCA API within a :mod:`pyramid` |
| | | being able to use the global ZCA API within a :app:`Pyramid` |
| | | application. However, it also means that a Zope application that is |
| | | running in the same process may start using the :mod:`pyramid` |
| | | running in the same process may start using the :app:`Pyramid` |
| | | global registry instead of the Zope global registry, effectively |
| | | inverting the original problem. In such a case, follow the steps in |
| | | the next section, :ref:`using_the_zca_global_registry`. |
| | |
| | | Enabling the ZCA Global API by Using The ZCA Global Registry |
| | | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| | | |
| | | You can tell your :mod:`pyramid` application to use the ZCA global |
| | | You can tell your :app:`Pyramid` application to use the ZCA global |
| | | registry at startup time instead of constructing a new one: |
| | | |
| | | .. code-block:: python |
| | |
| | | normally executed when a registry is constructed rather than created, |
| | | but we must call it "by hand" when we pass an explicit registry. |
| | | |
| | | At this point, :mod:`pyramid` will use the ZCA global registry |
| | | At this point, :app:`Pyramid` will use the ZCA global registry |
| | | rather than creating a new application-specific registry; since by |
| | | default the ZCA global API will use this registry, things will work as |
| | | you might expect a Zope app to when you use the global ZCA API. |
| | |
| | | they should actually be calling ``zope.component.getSiteManager``. |
| | | |
| | | ``zope.component.getSiteManager`` can be overridden by |
| | | :mod:`pyramid` via |
| | | :app:`Pyramid` via |
| | | :meth:`pyramid.configuration.Configurator.hook_zca`, while |
| | | ``zope.component.getGlobalSiteManager`` cannot. Directives that use |
| | | ``zope.component.getGlobalSiteManager`` are effectively broken; no |
| | |
| | | populate. |
| | | |
| | | You cannot use ZCML directives which use |
| | | ``zope.component.getGlobalSiteManager`` within a :mod:`pyramid` |
| | | ``zope.component.getGlobalSiteManager`` within a :app:`Pyramid` |
| | | application without passing the ZCA global registry to the |
| | | :term:`Configurator` constructor at application startup, as per |
| | | :ref:`using_the_zca_global_registry`. |
| | |
| | | |
| | | .. _converting_a_bfg_app: |
| | | |
| | | Converting a :mod:`repoze.bfg` Application to :mod:`pyramid` |
| | | Converting a :mod:`repoze.bfg` Application to :app:`Pyramid` |
| | | ============================================================ |
| | | |
| | | Prior iterations of :mod:`pyramid` were released as a package named |
| | | Prior iterations of :app:`Pyramid` were released as a package named |
| | | :mod:`repoze.bfg`. :mod:`repoze.bfg` users are encouraged to upgrade |
| | | their deployments to :mod:`pyramid`, as, after the first final release |
| | | of :mod:`pyramid`, further feature development on :mod:`repoze.bfg` |
| | | their deployments to :app:`Pyramid`, as, after the first final release |
| | | of :app:`Pyramid`, further feature development on :mod:`repoze.bfg` |
| | | will cease. |
| | | |
| | | Most existing :mod:`repoze.bfg` applications can be converted to a |
| | | :mod:`pyramid` application in a completely automated fashion. |
| | | :app:`Pyramid` application in a completely automated fashion. |
| | | However, if your application depends on packages which are not "core" |
| | | parts of :mod:`repoze.bfg` but which nonetheless have ``repoze.bfg`` |
| | | in their names (e.g. ``repoze.bfg.skins``, |
| | |
| | | of ``repoze.bfg.jinja2``. If an analogue does not seem to exist for a |
| | | ``repoze.bfg`` add-on package that your application uses, please email |
| | | the `Pylons-devel <http://groups.google.com/group/pylons-devel>`_ |
| | | maillist; we'll convert the package to a :mod:`pyramid` analogue for |
| | | maillist; we'll convert the package to a :app:`Pyramid` analogue for |
| | | you. |
| | | |
| | | Here's how to convert a :mod:`repoze.bfg` application to a |
| | | :mod:`pyramid` application: |
| | | :app:`Pyramid` application: |
| | | |
| | | #. Ensure that your application works under :mod:`repoze.bfg` *version |
| | | 1.3 or better*. See |
| | |
| | | ``bfgenv`` above will be the virtualenv into which you've installed |
| | | :mod:`repoze.bfg` 1.3. |
| | | |
| | | #. Install :mod:`pyramid` into a *separate* virtualenv as per the |
| | | instructions in :ref:`installing_chapter`. The :mod:`pyramid` |
| | | #. Install :app:`Pyramid` into a *separate* virtualenv as per the |
| | | instructions in :ref:`installing_chapter`. The :app:`Pyramid` |
| | | virtualenv should be separate from the one you've used to install |
| | | :mod:`repoze.bfg`. A quick way to do this: |
| | | |
| | |
| | | $ svn co http://my.server/my/bfg/application/trunk bfgapp |
| | | |
| | | #. Use the ``bfg2pyramid`` script present in the ``bin`` directory of |
| | | the :mod:`pyramid` virtualenv to convert all :mod:`repoze.bfg` |
| | | Python import statements into compatible :mod:`pyramid` import |
| | | the :app:`Pyramid` virtualenv to convert all :mod:`repoze.bfg` |
| | | Python import statements into compatible :app:`Pyramid` import |
| | | statements. ``bfg2pyramid`` will also fix ZCML directive usages of |
| | | common :mod:`repoze.bfg` directives. You invoke ``bfg2pyramid`` by |
| | | passing it the *path* of the copy of your application. The path |
| | |
| | | $ ~/pyramidenv/bfg2pyramid /tmp/bfgapp |
| | | |
| | | ``bfg2pyramid`` will convert the following :mod:`repoze.bfg` |
| | | application aspects to :mod:`pyramid` compatible analogues: |
| | | application aspects to :app:`Pyramid` compatible analogues: |
| | | |
| | | - Python ``import`` statements naming :mod:`repoze.bfg` APIs will |
| | | be converted to :mod:`pyramid` compatible ``import`` statements. |
| | | be converted to :app:`Pyramid` compatible ``import`` statements. |
| | | Every Python file beneath the top-level path will be visited and |
| | | converted recursively, except Python files which live in |
| | | directories which start with a ``.`` (dot). |
| | |
| | | - ZCML files which contain directives that have attributes which |
| | | name a ``repoze.bfg`` API module or attribute of an API module |
| | | (e.g. ``context="repoze.bfg.exceptions.NotFound"``) will be |
| | | converted to :mod:`pyramid` compatible ZCML attributes |
| | | converted to :app:`Pyramid` compatible ZCML attributes |
| | | (e.g. ``context="pyramid.exceptions.NotFound``). Every ZCML file |
| | | beneath the top-level path (files ending with ``.zcml``) will be |
| | | visited and converted recursively, except ZCML files which live |
| | |
| | | |
| | | #. Convert any ``install_requires`` dependencies your application has |
| | | on other add-on packages which have ``repoze.bfg`` in their names |
| | | to :mod:`pyramid` compatible analogues (e.g. ``repoze.bfg.jinja2`` |
| | | to :app:`Pyramid` compatible analogues (e.g. ``repoze.bfg.jinja2`` |
| | | should be replaced with ``pyramid_jinja2``). You may need to |
| | | adjust configuration options and/or imports in your |
| | | :mod:`repoze.bfg` application after replacing these add-ons. Read |
| | | the documentation of the :mod:`pyramid` add-on package for |
| | | the documentation of the :app:`Pyramid` add-on package for |
| | | information. |
| | | |
| | | #. *Only if you use ZCML and add-ons which use ZCML*: The default |
| | |
| | | <bfg:failingtag attr="foo"/> |
| | | </configure> |
| | | |
| | | #. Retest your application using :mod:`pyramid`. This might be as |
| | | #. Retest your application using :app:`Pyramid`. This might be as |
| | | easy as: |
| | | |
| | | .. code-block:: bash |
| | |
| | | .. _catalog_tutorial: |
| | | |
| | | Using :mod:`repoze.catalog` Within :mod:`pyramid` |
| | | Using :mod:`repoze.catalog` Within :app:`Pyramid` |
| | | ================================================= |
| | | |
| | | :mod:`repoze.catalog` is a ZODB-based system that can be used to index |
| | |
| | | extensible mechanism to show links in the CMF management UI that |
| | | invoke a particular behavior or which show a particular template. |
| | | |
| | | :mod:`pyramid` itself has no such concept, and no package provides |
| | | :app:`Pyramid` itself has no such concept, and no package provides |
| | | a direct replacement. Actions are such a generic concept that it's |
| | | simple to reimplement action-like navigation in a different way within |
| | | any given application. For example, a module-scope global dictionary |
| | |
| | | from the Zope 2 "catalog" based on the requesting user's ability to |
| | | view a particular cataloged object. |
| | | |
| | | :mod:`pyramid` itself has no cataloging facility, but an addon |
| | | :app:`Pyramid` itself has no cataloging facility, but an addon |
| | | package named :term:`repoze.catalog` offers similar functionality. |
| | | |
| | | Creating an Allowed Index |
| | |
| | | construct and enumerate content types using APIs defined on the types |
| | | tool. |
| | | |
| | | :mod:`pyramid` itself has no such concept, but an addon package named |
| | | :app:`Pyramid` itself has no such concept, but an addon package named |
| | | :term:`repoze.lemonade` has a barebones replacement. |
| | | |
| | | Factory Type Information |
| | |
| | | type name. Each type information object knows how to manufacture |
| | | content objects that match its type. |
| | | |
| | | :mod:`pyramid` certainly enforces none of these concepts in any |
| | | :app:`Pyramid` certainly enforces none of these concepts in any |
| | | particular way, but :term:`repoze.lemonade` does. |
| | | |
| | | ``repoze.lemonade`` Content |
| | |
| | | content-agnostic unit tests or if you need to get an |
| | | enumerated subset of content type information to aid in UI |
| | | generation. That said, this *is* a tutorial about how to |
| | | get CMF-like features in :mod:`pyramid`, so we'll assume |
| | | get CMF-like features in :app:`Pyramid`, so we'll assume |
| | | the pattern is useful to readers. |
| | | |
| | | See the `repoze.lemonade package |
| | |
| | | Converting an Existing Zope/CMF Application to :mod:`pyramid` |
| | | Converting an Existing Zope/CMF Application to :app:`Pyramid` |
| | | ================================================================ |
| | | |
| | | The Zope `Content Management Framework |
| | | <http://www.zope.org/Products/CMF/>`_ (aka CMF) is a layer on top of |
| | | :term:`Zope` 2 that provides facilities for creating content-driven |
| | | websites. It's reasonably easy to convert a modern Zope/CMF |
| | | application to :mod:`pyramid`. |
| | | application to :app:`Pyramid`. |
| | | |
| | | The main difference between CMF and :mod:`pyramid` is that |
| | | :mod:`pyramid` does not advertise itself as a system into which you |
| | | The main difference between CMF and :app:`Pyramid` is that |
| | | :app:`Pyramid` does not advertise itself as a system into which you |
| | | can plug arbitrary "packages" that extend a system-supplied management |
| | | user interface. You *could* build a CMF-like layer on top of |
| | | :mod:`pyramid` (as CMF is built on Zope) but none currently exists. |
| | | :app:`Pyramid` (as CMF is built on Zope) but none currently exists. |
| | | For those sorts of high-extensibility, highly-regularized-UI systems, |
| | | CMF is still the better choice. |
| | | |
| | | :mod:`pyramid` (and other more lightweight systems) is often a |
| | | :app:`Pyramid` (and other more lightweight systems) is often a |
| | | better choice when you're building the a user interface from scratch, |
| | | which often happens when the paradigms of some CMF-provided user |
| | | interface don't match the requirements of an application very closely. |
| | |
| | | particular skin to provide the site with additional features. |
| | | |
| | | To override static resources using a "search path" much like a set of |
| | | skin layers, :mod:`pyramid` provides the concept of |
| | | skin layers, :app:`Pyramid` provides the concept of |
| | | :term:`resource` overrides. See :ref:`overriding_resources_section` |
| | | for more information about resource overrides. |
| | | |
| | |
| | | In CMF, the "workflow tool" allows developers to design state machines |
| | | which imply transition between content states. |
| | | |
| | | :mod:`pyramid` itself has no such concept, but the |
| | | :app:`Pyramid` itself has no such concept, but the |
| | | :term:`repoze.workflow` package provides a simple state machine |
| | | implementation that can act as a barebones workflow tool. See its |
| | | documentation for more information. |
| | |
| | | .. _appengine_tutorial: |
| | | |
| | | Running :mod:`pyramid` on Google's App Engine |
| | | Running :app:`Pyramid` on Google's App Engine |
| | | ================================================ |
| | | |
| | | It is possible to run a :mod:`pyramid` application on Google's `App |
| | | It is possible to run a :app:`Pyramid` application on Google's `App |
| | | Engine <http://code.google.com/appengine/>`_. Content from this |
| | | tutorial was contributed by YoungKing, based on the |
| | | `"appengine-monkey" tutorial for Pylons |
| | |
| | | ``pyramidapp/app/`` which is the directory you will upload to |
| | | appengine. |
| | | |
| | | #. Install :mod:`pyramid` into the virtualenv |
| | | #. Install :app:`Pyramid` into the virtualenv |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ cd pyramidapp/ |
| | | $ bin/easy_install pyramid |
| | | |
| | | This will install :mod:`pyramid` in the environment. |
| | | This will install :app:`Pyramid` in the environment. |
| | | |
| | | #. Create your application |
| | | |
| | | We'll use the standard way to create a :mod:`pyramid` |
| | | We'll use the standard way to create a :app:`Pyramid` |
| | | application, but we'll have to move some files around when we are |
| | | done. The below commands assume your current working directory is |
| | | the ``pyramidapp`` virtualenv directory you created in the third step |
| | |
| | | |
| | | $ bin/pip zip pytz-2009g-py2.5.egg |
| | | |
| | | Note that it requires the whole egg file name. For a :mod:`pyramid` app, the |
| | | Note that it requires the whole egg file name. For a :app:`Pyramid` app, the |
| | | following packages are good candidates to be zipped. |
| | | |
| | | - Chameleon |
| | |
| | | .. _modwsgi_tutorial: |
| | | |
| | | Running a :mod:`pyramid` Application under ``mod_wsgi`` |
| | | Running a :app:`Pyramid` Application under ``mod_wsgi`` |
| | | ========================================================== |
| | | |
| | | :term:`mod_wsgi` is an Apache module developed by Graham Dumpleton. |
| | |
| | | server. |
| | | |
| | | This guide will outline broad steps that can be used to get a |
| | | :mod:`pyramid` application running under Apache via ``mod_wsgi``. |
| | | :app:`Pyramid` application running under Apache via ``mod_wsgi``. |
| | | This particular tutorial was developed under Apple's Mac OS X platform |
| | | (Snow Leopard, on a 32-bit Mac), but the instructions should be |
| | | largely the same for all systems, delta specific path information for |
| | | commands and files. |
| | | |
| | | .. note:: Unfortunately these instructions almost certainly won't work |
| | | for deploying a :mod:`pyramid` application on a Windows system |
| | | using ``mod_wsgi``. If you have experience with :mod:`pyramid` |
| | | for deploying a :app:`Pyramid` application on a Windows system |
| | | using ``mod_wsgi``. If you have experience with :app:`Pyramid` |
| | | and ``mod_wsgi`` on Windows systems, please help us document |
| | | this experience by submitting documentation to the `mailing list |
| | | <http://lists.repoze.org/listinfo/repoze-dev>`_. |
| | |
| | | $ cd modwsgi |
| | | $ /usr/local/bin/virtualenv --no-site-packages env |
| | | |
| | | #. Install :mod:`pyramid` into the newly created virtualenv: |
| | | #. Install :app:`Pyramid` into the newly created virtualenv: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ cd ~/modwsgi/env |
| | | $ bin/easy_install pyramid |
| | | |
| | | #. Create and install your :mod:`pyramid` application. For the |
| | | #. Create and install your :app:`Pyramid` application. For the |
| | | purposes of this tutorial, we'll just be using the ``bfg_starter`` |
| | | application as a baseline application. Substitute your existing |
| | | :mod:`pyramid` application as necessary if you already have |
| | | :app:`Pyramid` application as necessary if you already have |
| | | one. |
| | | |
| | | .. code-block:: text |
| | |
| | | |
| | | :term:`mod_wsgi` has many knobs and a great variety of deployment |
| | | modes. This is just one representation of how you might use it to |
| | | serve up a :mod:`pyramid` application. See the `mod_wsgi |
| | | serve up a :app:`Pyramid` application. See the `mod_wsgi |
| | | configuration documentation |
| | | <http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines>`_ for |
| | | more in-depth configuration information. |
| | |
| | | we'll change our application to allow people whom are members of a |
| | | *group* named ``group:editors`` to add and edit wiki pages but we'll |
| | | continue allowing anyone with access to the server to view pages. |
| | | :mod:`pyramid` provides facilities for *authorization* and |
| | | :app:`Pyramid` provides facilities for *authorization* and |
| | | *authentication*. We'll make use of both features to provide security |
| | | to our application. |
| | | |
| | |
| | | Configuring a ``pyramid`` Authentication Policy |
| | | -------------------------------------------------- |
| | | |
| | | For any :mod:`pyramid` application to perform authorization, we |
| | | For any :app:`Pyramid` application to perform authorization, we |
| | | need to add a ``security.py`` module and we'll need to change our |
| | | :term:`application registry` to add an :term:`authentication policy` |
| | | and a :term:`authorization policy`. |
| | |
| | | ``AuthTktAuthenticationPolicy`` and an ``ACLAuthorizationPolicy`` to |
| | | enable declarative security checking. We'll also add a new view |
| | | stanza, which specifies a :term:`forbidden view`. This configures our |
| | | login view to show up when :mod:`pyramid` detects that a view |
| | | login view to show up when :app:`Pyramid` detects that a view |
| | | invocation can not be authorized. When you're done, your |
| | | ``configure.zcml`` will look like so: |
| | | |
| | |
| | | ----------------------------------- |
| | | |
| | | We need to give our root model object an :term:`ACL`. This ACL will |
| | | be sufficient to provide enough information to the :mod:`pyramid` |
| | | be sufficient to provide enough information to the :app:`Pyramid` |
| | | security machinery to challenge a user who doesn't have appropriate |
| | | credentials when he attempts to invoke the ``add_page`` or |
| | | ``edit_page`` views. |
| | |
| | | |
| | | It's only happenstance that we're assigning this ACL at class scope. |
| | | An ACL can be attached to an object *instance* too; this is how "row |
| | | level security" can be achieved in :mod:`pyramid` applications. We |
| | | level security" can be achieved in :app:`Pyramid` applications. We |
| | | actually only need *one* ACL for the entire system, however, because |
| | | our security requirements are simple, so this feature is not |
| | | demonstrated. |
| | |
| | | Background |
| | | ========== |
| | | |
| | | This version of the :mod:`pyramid` wiki tutorial presents a |
| | | :mod:`pyramid` application that uses technologies which will be |
| | | This version of the :app:`Pyramid` wiki tutorial presents a |
| | | :app:`Pyramid` application that uses technologies which will be |
| | | familiar to someone with :term:`Zope` experience. It uses |
| | | :term:`ZODB` as a persistence mechanism and :term:`traversal` to map |
| | | URLs to code. It can also be followed by people without any prior |
| | |
| | | machine with development tools (Mac OS X with XCode, any Linux or BSD |
| | | variant, etc) *or* he will need a Windows system of any kind. |
| | | |
| | | This tutorial targets :mod:`pyramid` version 1.0. |
| | | This tutorial targets :app:`Pyramid` version 1.0. |
| | | |
| | | Have fun! |
| | |
| | | |
| | | The starter files generated by the ``pyramid_zodb`` template are basic, |
| | | but they provide a good orientation for the high-level patterns common |
| | | to most :term:`traversal` -based :mod:`pyramid` (and :term:`ZODB` |
| | | to most :term:`traversal` -based :app:`Pyramid` (and :term:`ZODB` |
| | | based) projects. |
| | | |
| | | The source code for this tutorial stage can be browsed via |
| | |
| | | Content Models with ``models.py`` |
| | | --------------------------------- |
| | | |
| | | :mod:`pyramid` often uses the word :term:`model` when talking about |
| | | :app:`Pyramid` often uses the word :term:`model` when talking about |
| | | content resources arranged in the hierarchical *object graph* |
| | | consulted by :term:`traversal`. The ``models.py`` file is where the |
| | | ``pyramid_zodb`` Paster template put the classes that implement our |
| | |
| | | |
| | | #. *Lines 6-12*. ``appmaker`` is used to return the *application |
| | | root* object. It is called on *every request* to the |
| | | :mod:`pyramid` application. It also performs bootstrapping by |
| | | :app:`Pyramid` application. It also performs bootstrapping by |
| | | *creating* an application root (inside the ZODB root object) if one |
| | | does not already exist. |
| | | |
| | |
| | | ``None`` at class scope, and should have a ``__parent__`` attribute |
| | | set to ``None`` at class scope as well. If a model has a |
| | | ``__parent__`` attribute of ``None`` in a traversal-based |
| | | :mod:`pyramid` application, it means that it's the :term:`root` |
| | | :app:`Pyramid` application, it means that it's the :term:`root` |
| | | model. The ``__name__`` of the root model is also always ``None``. |
| | | |
| | | Then we'll add a ``Page`` class. This class should inherit from the |
| | |
| | | Defining Views |
| | | ============== |
| | | |
| | | A :term:`view callable` in a traversal-based :mod:`pyramid` |
| | | A :term:`view callable` in a traversal-based :app:`Pyramid` |
| | | application is typically a simple Python function that accepts two |
| | | parameters: :term:`context`, and :term:`request`. A view callable is |
| | | assumed to return a :term:`response` object. |
| | | |
| | | .. note:: A :mod:`pyramid` view can also be defined as callable |
| | | .. note:: A :app:`Pyramid` view can also be defined as callable |
| | | which accepts *one* arguments: a :term:`request`. You'll see this |
| | | one-argument pattern used in other :mod:`pyramid` tutorials and |
| | | one-argument pattern used in other :app:`Pyramid` tutorials and |
| | | applications. Either calling convention will work in any |
| | | :mod:`pyramid` application; the calling conventions can be used |
| | | :app:`Pyramid` application; the calling conventions can be used |
| | | interchangeably as necessary. In :term:`traversal` based |
| | | applications, such as this tutorial, the context is used frequently |
| | | within the body of a view method, so it makes sense to use the |
| | |
| | | to avoid the visual "noise". |
| | | |
| | | We're going to define several :term:`view callable` functions then |
| | | wire them into :mod:`pyramid` using some :term:`view |
| | | wire them into :app:`Pyramid` using some :term:`view |
| | | configuration` via :term:`ZCML`. |
| | | |
| | | The source code for this tutorial stage can be browsed via |
| | |
| | | view callable. In the ``view_wiki`` view callable, we return a |
| | | :term:`response` object. In the ``view_page`` view callable, we |
| | | return a *dictionary*. It is *always* fine to return a |
| | | :term:`response` object from a :mod:`pyramid` view. Returning a |
| | | :term:`response` object from a :app:`Pyramid` view. Returning a |
| | | dictionary is allowed only when there is a :term:`renderer` associated |
| | | with the view callable in the view configuration. |
| | | |
| | |
| | | when we want to add a page object. The ``context`` of the |
| | | ``add_page`` view is always a Wiki object (*not* a Page object). |
| | | |
| | | The request :term:`subpath` in :mod:`pyramid` is the sequence of |
| | | The request :term:`subpath` in :app:`Pyramid` is the sequence of |
| | | names that are found *after* the view name in the URL segments given |
| | | in the ``PATH_INFO`` of the WSGI request as the result of |
| | | :term:`traversal`. If our add view is invoked via, |
| | |
| | | |
| | | Most view callables we've added expected to be rendered via a |
| | | :term:`template`. Each template is a :term:`Chameleon` template. The |
| | | default templating system in :mod:`pyramid` is a variant of |
| | | default templating system in :app:`Pyramid` is a variant of |
| | | :term:`ZPT` provided by Chameleon. These templates will live in the |
| | | ``templates`` directory of our tutorial package. |
| | | |
| | |
| | | it by using the ``setup.py sdist`` command. The following commands |
| | | assume your current working directory is the ``tutorial`` package |
| | | we've created and that the parent directory of the ``tutorial`` |
| | | package is a virtualenv representing a :mod:`pyramid` environment. |
| | | package is a virtualenv representing a :app:`Pyramid` environment. |
| | | |
| | | On UNIX: |
| | | |
| | |
| | | ZODB + Traversal Wiki Tutorial (For Developers Familiar with Zope) |
| | | ================================================================== |
| | | |
| | | This tutorial introduces a :term:`traversal` -based :mod:`pyramid` |
| | | This tutorial introduces a :term:`traversal` -based :app:`Pyramid` |
| | | application to a developer familiar with Python. It will be most familiar to |
| | | developers with previous :term:`Zope` experience. When we're done with the |
| | | tutorial, the developer will have created a basic Wiki application with |
| | |
| | | #. (Optional) Consider using ``source bin/activate`` to make your |
| | | shell environment wired to use the virtualenv. |
| | | |
| | | #. Use ``easy_install`` to get :mod:`pyramid` and its direct |
| | | #. Use ``easy_install`` to get :app:`Pyramid` and its direct |
| | | dependencies installed: |
| | | |
| | | .. code-block:: bash |
| | |
| | | #. (Optional) Consider using ``bin\activate.bat`` to make your shell |
| | | environment wired to use the virtualenv. |
| | | |
| | | #. Use ``easy_install`` to get :mod:`pyramid` and its direct |
| | | #. Use ``easy_install`` to get :app:`Pyramid` and its direct |
| | | dependencies installed: |
| | | |
| | | .. code-block:: bat |
| | |
| | | Making a Project |
| | | ================ |
| | | |
| | | Your next step is to create a project. :mod:`pyramid` supplies a |
| | | Your next step is to create a project. :app:`Pyramid` supplies a |
| | | variety of templates to generate sample projects. For this tutorial, |
| | | we will use the :term:`ZODB` -oriented template named ``pyramid_zodb``. |
| | | |
| | |
| | | |
| | | .. note:: |
| | | |
| | | :mod:`pyramid` supports any persistent storage mechanism (e.g. a SQL |
| | | database or filesystem files, etc). :mod:`pyramid` also supports an |
| | | :app:`Pyramid` supports any persistent storage mechanism (e.g. a SQL |
| | | database or filesystem files, etc). :app:`Pyramid` also supports an |
| | | additional mechanism to map URLs to code (:term:`URL dispatch`). However, |
| | | for the purposes of this tutorial, we'll only be using traversal and ZODB. |
| | | |
| | |
| | | |
| | | In order for our decorators to be recognized, we must add a bit of |
| | | boilerplate to our ``configure.zcml`` file which tells |
| | | :mod:`pyramid` to kick off a :term:`scan` at startup time. Add the |
| | | :app:`Pyramid` to kick off a :term:`scan` at startup time. Add the |
| | | following tag anywhere beneath the ``<include |
| | | package="pyramid.includes">`` tag but before the ending |
| | | ``</configure>`` tag within ``configure.zcml``: |
| | |
| | | we'll change our application to allow only people whom possess a |
| | | specific username (`editor`) to add and edit wiki pages but we'll |
| | | continue allowing anyone with access to the server to view pages. |
| | | :mod:`pyramid` provides facilities for *authorization* and |
| | | :app:`Pyramid` provides facilities for *authorization* and |
| | | *authentication*. We'll make use of both features to provide security |
| | | to our application. |
| | | |
| | |
| | | We're going to start to use a custom :term:`root factory` within our |
| | | ``__init__.py`` file. The objects generated by the root factory will be |
| | | used as the :term:`context` of each request to our application. In |
| | | order for :mod:`pyramid` declarative security to work properly, the |
| | | order for :app:`Pyramid` declarative security to work properly, the |
| | | context object generated during a request must be decorated with |
| | | security declarations; when we begin to use a custom root factory to |
| | | generate our contexts, we can begin to make use of the declarative |
| | | security features of :mod:`pyramid`. |
| | | security features of :app:`Pyramid`. |
| | | |
| | | We'll modify our ``__init__.py``, passing in a :term:`root factory` to our |
| | | :term:`Configurator` constructor. We'll point it at a new class we create |
| | |
| | | self.__dict__.update(request.matchdict) |
| | | |
| | | The ``RootFactory`` class we've just added will be used by |
| | | :mod:`pyramid` to construct a ``context`` object. The context is |
| | | :app:`Pyramid` to construct a ``context`` object. The context is |
| | | attached to the request object passed to our view callables as the |
| | | ``context`` attribute. |
| | | |
| | |
| | | allows :data:`pyramid.security.Everyone` (a special principal) to |
| | | view all pages, while allowing only a :term:`principal` named |
| | | ``group:editors`` to edit and add pages. The ``__acl__`` attribute |
| | | attached to a context is interpreted specially by :mod:`pyramid` as |
| | | attached to a context is interpreted specially by :app:`Pyramid` as |
| | | an access control list during view callable execution. See |
| | | :ref:`assigning_acls` for more information about what an :term:`ACL` |
| | | represents. |
| | |
| | | Configuring an Authorization Policy |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | For any :mod:`pyramid` application to perform authorization, we need to add a |
| | | For any :app:`Pyramid` application to perform authorization, we need to add a |
| | | ``security.py`` module (we'll do that shortly) and we'll need to change our |
| | | ``__init__.py`` file to add an :term:`authentication policy` and an |
| | | :term:`authorization policy` which uses the ``security.py`` file for a |
| | |
| | | declarative security checking. We'll also change ``__init__.py`` to add a |
| | | :meth:`pyramid.configuration.Configurator.add_view` call to points at our |
| | | ``login`` :term:`view callable`, also known as a :term:`forbidden view`. |
| | | This configures our newly created login view to show up when :mod:`pyramid` |
| | | This configures our newly created login view to show up when :app:`Pyramid` |
| | | detects that a view invocation can not be authorized. Also, we'll add |
| | | ``view_permission`` arguments with the value ``edit`` to the ``edit_page`` |
| | | and ``add_page`` routes. This indicates that the view callables which these |
| | |
| | | Background |
| | | ========== |
| | | |
| | | This tutorial presents a :mod:`pyramid` application that uses |
| | | This tutorial presents a :app:`Pyramid` application that uses |
| | | technologies which will be familiar to someone with :term:`Pylons` |
| | | experience. It uses :term:`SQLAlchemy` as a persistence mechanism and |
| | | :term:`url dispatch` to map URLs to code. It can also be followed by |
| | |
| | | machine with development tools (Mac OS X with XCode, any Linux or BSD |
| | | variant, etc) *or* he will need a Windows system of any kind. |
| | | |
| | | This tutorial is targeted at :mod:`pyramid` version 1.0. |
| | | This tutorial is targeted at :app:`Pyramid` version 1.0. |
| | | |
| | | Have fun! |
| | |
| | | |
| | | The starter files generated by the ``pyramid_routesalchemy`` template |
| | | are basic, but they provide a good orientation for the high-level |
| | | patterns common to most :term:`url dispatch` -based :mod:`pyramid` |
| | | patterns common to most :term:`url dispatch` -based :app:`Pyramid` |
| | | projects. |
| | | |
| | | The source code for this tutorial stage can be browsed at |
| | |
| | | ============== |
| | | |
| | | A :term:`view callable` in a :term:`url dispatch` -based |
| | | :mod:`pyramid` application is typically a simple Python function that |
| | | :app:`Pyramid` application is typically a simple Python function that |
| | | accepts a single parameter named :term:`request`. A view callable is |
| | | assumed to return a :term:`response` object. |
| | | |
| | | .. note:: A :mod:`pyramid` view can also be defined as callable |
| | | .. note:: A :app:`Pyramid` view can also be defined as callable |
| | | which accepts *two* arguments: a :term:`context` and a |
| | | :term:`request`. You'll see this two-argument pattern used in |
| | | other :mod:`pyramid` tutorials and applications. Either calling |
| | | convention will work in any :mod:`pyramid` application; the |
| | | other :app:`Pyramid` tutorials and applications. Either calling |
| | | convention will work in any :app:`Pyramid` application; the |
| | | calling conventions can be used interchangeably as necessary. In |
| | | :term:`url dispatch` based applications, however, the context |
| | | object is rarely used in the view body itself, so within this |
| | |
| | | We then generate an edit URL (because it's easier to do here than in |
| | | the template), and we return a dictionary with a number of arguments. |
| | | The fact that this view returns a dictionary (as opposed to a |
| | | :term:`response` object) is a cue to :mod:`pyramid` that it should |
| | | :term:`response` object) is a cue to :app:`Pyramid` that it should |
| | | try to use a :term:`renderer` associated with the view configuration |
| | | to render a template. In our case, the template which will be |
| | | rendered will be the ``templates/view.pt`` template, as per the |
| | |
| | | (``templates/edit.pt``) for the add view as well as the page edit |
| | | view, so we create a dummy Page object in order to satisfy the edit |
| | | form's desire to have *some* page object exposed as ``page``, and |
| | | :mod:`pyramid` will render the template associated with this view |
| | | :app:`Pyramid` will render the template associated with this view |
| | | to a response. |
| | | |
| | | If the view execution *is* a result of a form submission (if the |
| | |
| | | |
| | | The views we've added all reference a :term:`template`. Each template |
| | | is a :term:`Chameleon` template. The default templating system in |
| | | :mod:`pyramid` is a variant of :term:`ZPT` provided by |
| | | :app:`Pyramid` is a variant of :term:`ZPT` provided by |
| | | :term:`Chameleon`. These templates will live in the ``templates`` |
| | | directory of our tutorial package. |
| | | |
| | |
| | | it by using the ``setup.py sdist`` command. The following commands |
| | | assume your current working directory is the ``tutorial`` package |
| | | we've created and that the parent directory of the ``tutorial`` |
| | | package is a virtualenv representing a :mod:`pyramid` environment. |
| | | package is a virtualenv representing a :app:`Pyramid` environment. |
| | | |
| | | On UNIX: |
| | | |
| | |
| | | =============================================================================== |
| | | |
| | | This tutorial introduces a :term:`SQLAlchemy` and :term:`url dispatch` -based |
| | | :mod:`pyramid` application to a developer familiar with Python, and will be |
| | | :app:`Pyramid` application to a developer familiar with Python, and will be |
| | | most familiar to developers who have used the :term:`Pylons` 1.X web |
| | | framework. When the tutorial is finished, the developer will have created a |
| | | basic Wiki application with authentication. |
| | |
| | | #. (Optional) Consider using ``source bin/activate`` to make your |
| | | shell environment wired to use the virtualenv. |
| | | |
| | | #. Use ``easy_install`` to get :mod:`pyramid` and its direct |
| | | #. Use ``easy_install`` to get :app:`Pyramid` and its direct |
| | | dependencies installed: |
| | | |
| | | .. code-block:: text |
| | |
| | | #. (Optional) Consider using ``bin\activate.bat`` to make your shell |
| | | environment wired to use the virtualenv. |
| | | |
| | | #. Use ``easy_install`` to get :mod:`pyramid` and its direct |
| | | #. Use ``easy_install`` to get :app:`Pyramid` and its direct |
| | | dependencies installed: |
| | | |
| | | .. code-block:: text |
| | |
| | | Making a Project |
| | | ================ |
| | | |
| | | Your next step is to create a project. :mod:`pyramid` supplies a |
| | | Your next step is to create a project. :app:`Pyramid` supplies a |
| | | variety of templates to generate sample projects. We will use the |
| | | ``pyramid_routesalchemy`` template, which generates an application |
| | | that uses :term:`SQLAlchemy` and :term:`URL dispatch`. |
| | |
| | | |
| | | .. note:: |
| | | |
| | | :mod:`pyramid` supports any persistent storage mechanism (e.g. object |
| | | :app:`Pyramid` supports any persistent storage mechanism (e.g. object |
| | | database or filesystem files, etc). It also supports an additional |
| | | mechanism to map URLs to code (:term:`traversal`). However, for the |
| | | purposes of this tutorial, we'll only be using url dispatch and |
| | |
| | | =================== |
| | | |
| | | :term:`ZODB` is a Python object persistence mechanism. :term:`ZODB` |
| | | works well as a storage mechanism for :mod:`pyramid` applications, |
| | | works well as a storage mechanism for :app:`Pyramid` applications, |
| | | especially in applications that use :term:`traversal`. |
| | | |
| | | :term:`ZEO` is an extension to ZODB which allows more than one process |
| | | to simultaneously communicate with a ZODB storage. Making a ZODB |
| | | database accessible to more than one process means that you can debug |
| | | your application objects at the same time that a :mod:`pyramid` |
| | | your application objects at the same time that a :app:`Pyramid` |
| | | server that accesses the database is running, and will also allow your |
| | | application to run under multiprocess configurations, such as those |
| | | exposed by :term:`mod_wsgi`. |
| | | |
| | | The easiest way to get started with ZODB in a :mod:`pyramid` application is |
| | | The easiest way to get started with ZODB in a :app:`Pyramid` application is |
| | | to use the ZODB ``pyramid_zodb`` paster template. See |
| | | :ref:`additional_paster_templates` for more information about using this |
| | | template. However, the Paster template does not set up a ZEO-capable |
| | |
| | | Installing Dependencies |
| | | ----------------------- |
| | | |
| | | #. Edit your :mod:`pyramid` application's ``setup.py`` file, adding |
| | | #. Edit your :app:`Pyramid` application's ``setup.py`` file, adding |
| | | the following packages to the ``install_requires`` of the |
| | | application: |
| | | |
| | |
| | | </blobstorage> |
| | | |
| | | #. For the purposes of this tutorial we'll assume that you want your |
| | | :mod:`pyramid` application's :term:`root` object to be a |
| | | :app:`Pyramid` application's :term:`root` object to be a |
| | | "folderish" object. To achieve this, change your application's |
| | | ``models.py`` file to look like the below: |
| | | |
| | |
| | | usage documentation <http://docs.repoze.org/session/usage.html>`_. |
| | | If you don't want to use ZODB to do sessioning, you might choose to |
| | | use a relational/filestorage sessioning system such as `Beaker |
| | | <http://pypi.python.org/pypi/Beaker>`_. :mod:`pyramid` is fully |
| | | <http://pypi.python.org/pypi/Beaker>`_. :app:`Pyramid` is fully |
| | | compatible with this system too. |
| | | |
| | | Installing Dependencies |
| | | ----------------------- |
| | | |
| | | #. Edit your :mod:`pyramid` application's ``setup.py`` file, adding |
| | | #. Edit your :app:`Pyramid` application's ``setup.py`` file, adding |
| | | the following packages to the ``install_requires`` of the |
| | | application: |
| | | |
| | |
| | | =============== |
| | | |
| | | Comprehensive reference material for every ZCML directive provided by |
| | | :mod:`pyramid` is available within this chapter. The ZCML directive |
| | | :app:`Pyramid` is available within this chapter. The ZCML directive |
| | | documentation is organized alphabetically by directive name. |
| | | |
| | | .. toctree:: |
| | |
| | | ------------- |
| | | |
| | | Because :term:`ZCML` is XML, and because XML requires a single root |
| | | tag for each document, every ZCML file used by :mod:`pyramid` must |
| | | tag for each document, every ZCML file used by :app:`Pyramid` must |
| | | contain a ``configure`` container directive, which acts as the root |
| | | XML tag. It is a "container" directive because its only job is to |
| | | contain other directives. |
| | |
| | | Using the ``http://pylonshq.com/pyramid`` namespace as the default XML |
| | | namespace isn't strictly necessary; you can use a different default |
| | | namespace as the default. However, if you do, the declaration tags |
| | | which are defined by :mod:`pyramid` such as the ``view`` declaration |
| | | which are defined by :app:`Pyramid` such as the ``view`` declaration |
| | | tag will need to be defined in such a way that the XML parser that |
| | | :mod:`pyramid` uses knows which namespace the :mod:`pyramid` tags are |
| | | :app:`Pyramid` uses knows which namespace the :mod:`pyramid` tags are |
| | | associated with. For example, the following files are all completely |
| | | equivalent: |
| | | |
| | |
| | | ``forbidden`` |
| | | ------------- |
| | | |
| | | When :mod:`pyramid` can't authorize execution of a view based on |
| | | When :app:`Pyramid` can't authorize execution of a view based on |
| | | the :term:`authorization policy` in use, it invokes a :term:`forbidden |
| | | view`. The default forbidden response has a 401 status code and is |
| | | very plain, but it can be overridden as necessary using the |
| | |
| | | |
| | | .. warning:: |
| | | |
| | | The ``forbidden`` ZCML directive is deprecated in :mod:`pyramid` |
| | | The ``forbidden`` ZCML directive is deprecated in :app:`Pyramid` |
| | | version 1.3. Instead, you should use the :ref:`view_directive` |
| | | directive with a ``context`` that names the |
| | | :exc:`pyramid.exceptions.Forbidden` class. See |
| | |
| | | |
| | | .. warning:: |
| | | |
| | | The ``notfound`` ZCML directive is deprecated in :mod:`pyramid` |
| | | The ``notfound`` ZCML directive is deprecated in :app:`Pyramid` |
| | | version 1.0. Instead, you should use the :ref:`view_directive` |
| | | directive with a ``context`` that names the |
| | | :exc:`pyramid.exceptions.NotFound` class. See |
| | | :ref:`changing_the_notfound_view` form more information. |
| | | |
| | | When :mod:`pyramid` can't map a URL to view code, it invokes a |
| | | When :app:`Pyramid` can't map a URL to view code, it invokes a |
| | | :term:`not found view`. The default not found view is very plain, but |
| | | the view callable used can be configured via the ``notfound`` ZCML |
| | | tag. |
| | |
| | | |
| | | ``factory`` |
| | | The :term:`dotted Python name` to a function that will generate a |
| | | :mod:`pyramid` context object when this route matches. |
| | | :app:`Pyramid` context object when this route matches. |
| | | e.g. ``mypackage.models.MyFactoryClass``. If this argument is not |
| | | specified, a default root factory will be used. |
| | | |
| | |
| | | |
| | | To make use of :term:`configuration decoration` decorators, you must |
| | | perform a :term:`scan`. A scan finds these decorators in code. The |
| | | ``scan`` ZCML directive tells :mod:`pyramid` to begin such a scan. |
| | | ``scan`` ZCML directive tells :app:`Pyramid` to begin such a scan. |
| | | |
| | | Attributes |
| | | ~~~~~~~~~~ |
| | |
| | | |
| | | Use of the ``static`` ZCML directive or allows you to serve static |
| | | resources (such as JavaScript and CSS files) within a |
| | | :mod:`pyramid` application. This mechanism makes static files |
| | | :app:`Pyramid` application. This mechanism makes static files |
| | | available at a name relative to the application root URL. |
| | | |
| | | Attributes |
| | |
| | | -------------- |
| | | |
| | | The ``subscriber`` ZCML directive configures an :term:`subscriber` |
| | | callable to listen for events broadcast by the :mod:`pyramid` web |
| | | callable to listen for events broadcast by the :app:`Pyramid` web |
| | | framework. |
| | | |
| | | Attributes |
| | |
| | | ``view`` |
| | | -------- |
| | | |
| | | A ``view`` declaration directs :mod:`pyramid` to create a single |
| | | A ``view`` declaration directs :app:`Pyramid` to create a single |
| | | :term:`view configuration` registration in the current |
| | | :term:`application registry`. |
| | | |
| | |
| | | |
| | | |
| | | class RepozeWho1AuthenticationPolicy(CallbackAuthenticationPolicy): |
| | | """ A :mod:`pyramid` :term:`authentication policy` which |
| | | """ A :app:`Pyramid` :term:`authentication policy` which |
| | | obtains data from the :mod:`repoze.who` 1.X WSGI 'API' (the |
| | | ``repoze.who.identity`` key in the WSGI environment). |
| | | |
| | |
| | | return identifier.forget(request.environ, identity) |
| | | |
| | | class RemoteUserAuthenticationPolicy(CallbackAuthenticationPolicy): |
| | | """ A :mod:`pyramid` :term:`authentication policy` which |
| | | """ A :app:`Pyramid` :term:`authentication policy` which |
| | | obtains data from the ``REMOTE_USER`` WSGI environment variable. |
| | | |
| | | Constructor Arguments |
| | |
| | | return [] |
| | | |
| | | class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy): |
| | | """ A :mod:`pyramid` :term:`authentication policy` which |
| | | """ A :app:`Pyramid` :term:`authentication policy` which |
| | | obtains data from an :class:`paste.auth.auth_tkt` cookie. |
| | | |
| | | Constructor Arguments |
| | |
| | | package-relative path, an absolute path, or a :term:`resource |
| | | specification`. |
| | | |
| | | .. warning:: This API is deprecated in :mod:`pyramid` 1.0. Use |
| | | .. warning:: This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.get_renderer` instead. |
| | | """ |
| | | package = caller_package() |
| | |
| | | The ``path`` argument may be a package-relative path, an absolute |
| | | path, or a :term:`resource specification`. |
| | | |
| | | .. warning:: This API is deprecated in :mod:`pyramid` 1.0. Use |
| | | .. warning:: This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | the ``implementation()`` method of a template renderer retrieved via |
| | | :func:`pyramid.renderers.get_renderer` instead. |
| | | """ |
| | |
| | | names to the template, and so may be used within the template |
| | | itself. Returns a string. |
| | | |
| | | .. warning:: This API is deprecated in :mod:`pyramid` 1.0. Use |
| | | .. warning:: This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.render` instead. |
| | | """ |
| | | package = caller_package() |
| | |
| | | itself. Returns a :term:`Response` object with the body as the |
| | | template result. |
| | | |
| | | .. warning:: This API is deprecated in :mod:`pyramid` 1.0. Use |
| | | .. warning:: This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.render_to_response` instead. |
| | | """ |
| | | package = caller_package() |
| | |
| | | package-relative path, an absolute path, or a :term:`resource |
| | | specification`. |
| | | |
| | | .. warning:: This API is deprecated in :mod:`pyramid` 1.0. Use |
| | | .. warning:: This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.get_renderer` instead. |
| | | """ |
| | | package = caller_package() |
| | |
| | | The ``path`` argument may be a package-relative path, an absolute |
| | | path, or a :term:`resource specification`. |
| | | |
| | | .. warning:: This API is deprecated in :mod:`pyramid` 1.0. Use |
| | | .. warning:: This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | the ``implementation()`` method of a template renderer retrieved via |
| | | :func:`pyramid.renderers.get_renderer` instead. |
| | | """ |
| | |
| | | names to the template, and so may be used within the template |
| | | itself. Returns a string. |
| | | |
| | | .. warning:: This API is deprecated in :mod:`pyramid` 1.0. Use |
| | | .. warning:: This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.render` instead. |
| | | """ |
| | | package = caller_package() |
| | |
| | | itself. Returns a :term:`Response` object with the body as the |
| | | template result. |
| | | |
| | | .. warning:: This API is deprecated in :mod:`pyramid` 1.0. Use |
| | | .. warning:: This API is deprecated in :app:`Pyramid` 1.0. Use |
| | | :func:`pyramid.renderers.render_to_response` instead. |
| | | """ |
| | | package = caller_package() |
| | |
| | | |
| | | class Configurator(object): |
| | | """ |
| | | A Configurator is used to configure a :mod:`pyramid` |
| | | A Configurator is used to configure a :app:`Pyramid` |
| | | :term:`application registry`. |
| | | |
| | | The Configurator accepts a number of arguments: ``registry``, |
| | |
| | | logs to stderr will be used. If it is passed, it should be an |
| | | instance of the :class:`logging.Logger` (PEP 282) standard library |
| | | class or a :term:`dotted Python name` to same. The debug logger |
| | | is used by :mod:`pyramid` itself to log warnings and |
| | | is used by :app:`Pyramid` itself to log warnings and |
| | | authorization debugging information. |
| | | |
| | | If ``locale_negotiator`` is passed, it should be a :term:`locale |
| | |
| | | self.registry.registerUtility(factory, IDefaultRootFactory) # b/c |
| | | |
| | | def _set_authentication_policy(self, policy, _info=u''): |
| | | """ Add a :mod:`pyramid` :term:`authentication policy` to |
| | | """ Add a :app:`Pyramid` :term:`authentication policy` to |
| | | the current configuration.""" |
| | | policy = self.maybe_dotted(policy) |
| | | self.registry.registerUtility(policy, IAuthenticationPolicy, |
| | | info=_info) |
| | | |
| | | def _set_authorization_policy(self, policy, _info=u''): |
| | | """ Add a :mod:`pyramid` :term:`authorization policy` to |
| | | """ Add a :app:`Pyramid` :term:`authorization policy` to |
| | | the current configuration state (also accepts a :term:`dotted |
| | | Python name`.""" |
| | | policy = self.maybe_dotted(policy) |
| | |
| | | :term:`Configurator` constructor, no initial 'setup' is |
| | | performed against the registry. This is because the registry |
| | | you pass in may have already been initialized for use under |
| | | :mod:`pyramid` via a different configurator. However, in |
| | | :app:`Pyramid` via a different configurator. However, in |
| | | some circumstances, such as when you want to use the Zope |
| | | 'global` registry instead of a registry created as a result of |
| | | the Configurator constructor, or when you want to reset the |
| | | initial setup of a registry, you *do* want to explicitly |
| | | initialize the registry associated with a Configurator for use |
| | | under :mod:`pyramid`. Use ``setup_registry`` to do this |
| | | under :app:`Pyramid`. Use ``setup_registry`` to do this |
| | | initialization. |
| | | |
| | | ``setup_registry`` configures settings, a root factory, |
| | |
| | | the :term:`Zope Component Architecture` 'global' APIs such as |
| | | :func:`zope.component.getSiteManager`, |
| | | :func:`zope.component.getAdapter` and others to use the |
| | | :mod:`pyramid` :term:`application registry` rather than the |
| | | :app:`Pyramid` :term:`application registry` rather than the |
| | | Zope 'global' registry. If :mod:`zope.component` cannot be |
| | | imported, this method will raise an :exc:`ImportError`.""" |
| | | if getSiteManager is None: |
| | |
| | | This is API is useful to framework extenders who create |
| | | pluggable systems which need to register 'proxy' view |
| | | callables for functions, instances, or classes which meet the |
| | | requirements of being a :mod:`pyramid` view callable. For |
| | | requirements of being a :app:`Pyramid` view callable. For |
| | | example, a ``some_other_framework`` function in another |
| | | framework may want to allow a user to supply a view callable, |
| | | but he may want to wrap the view callable in his own before |
| | | registering the wrapper as a :mod:`pyramid` view callable. |
| | | Because a :mod:`pyramid` view callable can be any of a |
| | | registering the wrapper as a :app:`Pyramid` view callable. |
| | | Because a :app:`Pyramid` view callable can be any of a |
| | | number of valid objects, the framework extender will not know |
| | | how to call the user-supplied object. Running it through |
| | | ``derive_view`` normalizes it to a callable which accepts two |
| | |
| | | ``subscriber`` argument represents a callable object (or a |
| | | :term:`dotted Python name` which identifies a callable); it |
| | | will be called with a single object ``event`` whenever |
| | | :mod:`pyramid` emits an :term:`event` associated with the |
| | | :app:`Pyramid` emits an :term:`event` associated with the |
| | | ``iface``, which may be an :term:`interface` or a class or a |
| | | :term:`dotted Python name` to a global object representing an |
| | | interface or a class. Using the default ``iface`` value, |
| | |
| | | return self.registry.queryUtility(ISettings) |
| | | |
| | | def make_wsgi_app(self): |
| | | """ Returns a :mod:`pyramid` WSGI application representing |
| | | """ Returns a :app:`Pyramid` WSGI application representing |
| | | the current configuration state and sends a |
| | | :class:`pyramid.events.ApplicationCreated` |
| | | event to all listeners.""" |
| | |
| | | down below into *predicate* arguments and *non-predicate* |
| | | arguments. Predicate arguments narrow the circumstances in |
| | | which the view callable will be invoked when a request is |
| | | presented to :mod:`pyramid`; non-predicate arguments are |
| | | presented to :app:`Pyramid`; non-predicate arguments are |
| | | informational. |
| | | |
| | | Non-Predicate Arguments |
| | |
| | | The ``renderer`` attribute is optional. If it is not |
| | | defined, the "null" renderer is assumed (no rendering is |
| | | performed and the value is passed back to the upstream |
| | | :mod:`pyramid` machinery unmolested). |
| | | :app:`Pyramid` machinery unmolested). |
| | | |
| | | wrapper |
| | | |
| | |
| | | |
| | | A Python object (often a function or a class) or a |
| | | :term:`dotted Python name` which refers to the same object |
| | | that will generate a :mod:`pyramid` :term:`context` |
| | | that will generate a :app:`Pyramid` :term:`context` |
| | | object when this route matches. For example, |
| | | ``mypackage.models.MyFactoryClass``. If this argument is |
| | | not specified, a default root factory will be used. |
| | |
| | | replace the arguments it is passed when generating a URL |
| | | for the route. This is a feature not often used directly |
| | | by applications, it is meant to be hooked by frameworks |
| | | that use :mod:`pyramid` as a base. |
| | | that use :app:`Pyramid` as a base. |
| | | |
| | | Predicate Arguments |
| | | |
| | |
| | | continues. |
| | | |
| | | .. note:: For backwards compatibility purposes (as of |
| | | :mod:`pyramid` 1.0), a ``path`` keyword argument passed |
| | | :app:`Pyramid` 1.0), a ``path`` keyword argument passed |
| | | to this function will be used to represent the pattern |
| | | value if the ``pattern`` argument is ``None``. If both |
| | | ``path`` and ``pattern`` are passed, ``pattern`` wins. |
| | |
| | | |
| | | By default, ``categories`` is ``None`` which will execute |
| | | *all* Venusian decorator callbacks including |
| | | :mod:`pyramid`-related decorators such as |
| | | :app:`Pyramid`-related decorators such as |
| | | :class:`pyramid.view.view_config``. If this is not desirable |
| | | because the codebase has other Venusian-using decorators that |
| | | aren't meant to be invoked during a particular scan, use |
| | | ``('pyramid',)`` as a ``categories`` value to limit the execution |
| | | of decorator callbacks to only those registered by |
| | | :mod:`pyramid` itself. Or pass a sequence of Venusian scan |
| | | :app:`Pyramid` itself. Or pass a sequence of Venusian scan |
| | | categories as necessary (e.g. ``('pyramid', 'myframework')``) to |
| | | limit the decorators called to the set of categories required. |
| | | """ |
| | |
| | | |
| | | def add_renderer(self, name, factory, _info=u''): |
| | | """ |
| | | Add a :mod:`pyramid` :term:`renderer` factory to the |
| | | Add a :app:`Pyramid` :term:`renderer` factory to the |
| | | current configuration state. |
| | | |
| | | The ``name`` argument is the renderer name. |
| | |
| | | |
| | | def override_resource(self, to_override, override_with, |
| | | _info=u'', _override=None,): |
| | | """ Add a :mod:`pyramid` resource override to the current |
| | | """ Add a :app:`Pyramid` resource override to the current |
| | | configuration state. |
| | | |
| | | ``to_override`` is a :term:`resource specification` to the |
| | |
| | | """ Add a default forbidden view to the current configuration |
| | | state. |
| | | |
| | | .. warning:: This method has been deprecated in :mod:`pyramid` |
| | | .. warning:: This method has been deprecated in :app:`Pyramid` |
| | | 1.0. *Do not use it for new development; it should only be |
| | | used to support older code bases which depend upon it.* See |
| | | :ref:`changing_the_forbidden_view` to see how a forbidden |
| | |
| | | state. |
| | | |
| | | .. warning:: This method has been deprecated in |
| | | :mod:`pyramid` 1.0. *Do not use it for new development; |
| | | :app:`Pyramid` 1.0. *Do not use it for new development; |
| | | it should only be used to support older code bases which |
| | | depend upon it.* See :ref:`changing_the_notfound_view` to |
| | | see how a not found view should be registered in new |
| | |
| | | def set_request_factory(self, factory): |
| | | """ The object passed as ``factory`` should be an object (or a |
| | | :term:`dotted Python name` which refers to an object) which |
| | | will be used by the :mod:`pyramid` router to create all |
| | | will be used by the :app:`Pyramid` router to create all |
| | | request objects. This factory object must have the same |
| | | methods and attributes as the |
| | | :class:`pyramid.request.Request` class (particularly |
| | |
| | | def set_renderer_globals_factory(self, factory): |
| | | """ The object passed as ``factory`` should be an callable (or |
| | | a :term:`dotted Python name` which refers to an callable) that |
| | | will be used by the :mod:`pyramid` rendering machinery as a |
| | | will be used by the :app:`Pyramid` rendering machinery as a |
| | | renderers global factory (see :ref:`adding_renderer_globals`). |
| | | |
| | | The ``factory`` callable must accept a single argument named |
| | |
| | | def testing_securitypolicy(self, userid=None, groupids=(), |
| | | permissive=True): |
| | | """Unit/integration testing helper: Registers a pair of faux |
| | | :mod:`pyramid` security policies: a :term:`authentication |
| | | :app:`Pyramid` security policies: a :term:`authentication |
| | | policy` and a :term:`authorization policy`. |
| | | |
| | | The behavior of the registered :term:`authorization policy` |
| | |
| | | def make_app(root_factory, package=None, filename='configure.zcml', |
| | | settings=None, options=None, Configurator=Configurator): |
| | | """ Return a Router object, representing a fully configured |
| | | :mod:`pyramid` WSGI application. |
| | | :app:`Pyramid` WSGI application. |
| | | |
| | | .. warning:: Use of this function is deprecated as of |
| | | :mod:`pyramid` 1.0. You should instead use a |
| | | :app:`Pyramid` 1.0. You should instead use a |
| | | :class:`pyramid.configuration.Configurator` instance to |
| | | perform startup configuration as shown in |
| | | :ref:`configuration_narr`. |
| | |
| | | |
| | | class NewRequest(object): |
| | | """ An instance of this class is emitted as an :term:`event` |
| | | whenever :mod:`pyramid` begins to process a new request. The |
| | | whenever :app:`Pyramid` begins to process a new request. The |
| | | even instance has an attribute, ``request``, which is a |
| | | :term:`request` object. This event class implements the |
| | | :class:`pyramid.interfaces.INewRequest` interface.""" |
| | |
| | | |
| | | class NewResponse(object): |
| | | """ An instance of this class is emitted as an :term:`event` |
| | | whenever any :mod:`pyramid` :term:`view` or :term:`exception |
| | | whenever any :app:`Pyramid` :term:`view` or :term:`exception |
| | | view` returns a :term:`response`. |
| | | |
| | | The instance has two attributes:``request``, which is the request |
| | |
| | | |
| | | class ContextFound(object): |
| | | """ An instance of this class is emitted as an :term:`event` after |
| | | the :mod:`pyramid` :term:`router` finds a :term:`context` |
| | | the :app:`Pyramid` :term:`router` finds a :term:`context` |
| | | object (after it performs traversal) but before any view code is |
| | | executed. The instance has an attribute, ``request``, which is |
| | | the request object generated by :mod:`pyramid`. |
| | | the request object generated by :app:`Pyramid`. |
| | | |
| | | Notably, the request object will have an attribute named |
| | | ``context``, which is the context that will be provided to the |
| | |
| | | This class implements the |
| | | :class:`pyramid.interfaces.IContextFound` interface. |
| | | |
| | | .. note:: As of :mod:`pyramid` 1.0, for backwards compatibility |
| | | .. note:: As of :app:`Pyramid` 1.0, for backwards compatibility |
| | | purposes, this event may also be imported as |
| | | :class:`pyramid.events.AfterTraversal`. |
| | | """ |
| | |
| | | .. note:: For backwards compatibility purposes, this class can |
| | | also be imported as |
| | | :class:`pyramid.events.WSGIApplicationCreatedEvent`. This |
| | | was the name of the event class before :mod:`pyramid` 1.0. |
| | | was the name of the event class before :app:`Pyramid` 1.0. |
| | | |
| | | """ |
| | | implements(IApplicationCreated) |
| | |
| | | |
| | | class URLDecodeError(UnicodeDecodeError): |
| | | """ |
| | | This exception is raised when :mod:`pyramid` cannot |
| | | This exception is raised when :app:`Pyramid` cannot |
| | | successfully decode a URL or a URL path segment. This exception |
| | | it behaves just like the Python builtin |
| | | :exc:`UnicodeDecodeError`. It is a subclass of the builtin |
| | |
| | | # public API interfaces |
| | | |
| | | class IContextFound(Interface): |
| | | """ An event type that is emitted after :mod:`pyramid` finds a |
| | | """ An event type that is emitted after :app:`Pyramid` finds a |
| | | :term:`context` object but before it calls any view code. See the |
| | | documentation attached to :class:`pyramid.events.ContextFound` |
| | | for more information. |
| | | |
| | | .. note:: For backwards compatibility with versions of |
| | | :mod:`pyramid` before 1.0, this event interface can also be |
| | | :app:`Pyramid` before 1.0, this event interface can also be |
| | | imported as :class:`pyramid.interfaces.IAfterTraversal`. |
| | | """ |
| | | request = Attribute('The request object') |
| | |
| | | IAfterTraversal = IContextFound |
| | | |
| | | class INewRequest(Interface): |
| | | """ An event type that is emitted whenever :mod:`pyramid` |
| | | """ An event type that is emitted whenever :app:`Pyramid` |
| | | begins to process a new request. See the documentation attached |
| | | to :class:`pyramid.events.NewRequest` for more information.""" |
| | | request = Attribute('The request object') |
| | | |
| | | class INewResponse(Interface): |
| | | """ An event type that is emitted whenever any :mod:`pyramid` |
| | | """ An event type that is emitted whenever any :app:`Pyramid` |
| | | view returns a response. See the |
| | | documentation attached to :class:`pyramid.events.NewResponse` |
| | | for more information.""" |
| | |
| | | :class:`pyramid.events.ApplicationCreated` for more |
| | | information. |
| | | |
| | | .. note:: For backwards compatibility with :mod:`pyramid` |
| | | .. note:: For backwards compatibility with :app:`Pyramid` |
| | | versions before 1.0, this interface can also be imported as |
| | | :class:`pyramid.interfaces.IWSGIApplicationCreatedEvent`. |
| | | """ |
| | |
| | | """ An interface representing a WSGI response which is also an |
| | | exception object. Register an exception view using this interface |
| | | as a ``context`` to apply the registered view for all exception |
| | | types raised by :mod:`pyramid` internally |
| | | types raised by :app:`Pyramid` internally |
| | | (:class:`pyramid.exceptions.NotFound` and |
| | | :class:`pyramid.exceptions.Forbidden`).""" |
| | | |
| | |
| | | name = Attribute('The route name') |
| | | pattern = Attribute('The route pattern') |
| | | factory = Attribute( |
| | | 'The :term:`root factory` used by the :mod:`pyramid` router ' |
| | | 'The :term:`root factory` used by the :app:`Pyramid` router ' |
| | | 'when this route matches (or ``None``)') |
| | | predicates = Attribute( |
| | | 'A sequence of :term:`route predicate` objects used to ' |
| | |
| | | |
| | | _marker = object() |
| | | class PShellCommand(Command): |
| | | """Open an interactive shell with a :mod:`pyramid` app loaded. |
| | | """Open an interactive shell with a :app:`Pyramid` app loaded. |
| | | |
| | | This command accepts two positional arguments: |
| | | |
| | |
| | | Due to technical constraints, we can't yet display the WebOb |
| | | version number from which this documentation is autogenerated, but |
| | | it will be the 'prevailing WebOb version' at the time of the |
| | | release of this :mod:`pyramid` version. See |
| | | release of this :app:`Pyramid` version. See |
| | | http://http://pythonpaste.org/webob/ for further information. |
| | | """ |
| | | implements(IRequest) |
| | |
| | | """ |
| | | Add a callback to the set of callbacks to be called by the |
| | | :term:`router` at a point after a :term:`response` object is |
| | | successfully created. :mod:`pyramid` does not have a |
| | | successfully created. :app:`Pyramid` does not have a |
| | | global response object: this functionality allows an |
| | | application to register an action to be performed against the |
| | | response once one is created. |
| | |
| | | :class:`pyramid.events.NewResponse` event is sent. |
| | | |
| | | Errors raised by callbacks are not handled specially. They |
| | | will be propagated to the caller of the :mod:`pyramid` |
| | | will be propagated to the caller of the :app:`Pyramid` |
| | | router application. |
| | | |
| | | See also: :ref:`using_response_callbacks`. |
| | |
| | | immediately after all finished callbacks have been processed. |
| | | |
| | | Errors raised by finished callbacks are not handled specially. |
| | | They will be propagated to the caller of the :mod:`pyramid` |
| | | They will be propagated to the caller of the :app:`Pyramid` |
| | | router application. |
| | | |
| | | See also: :ref:`using_finished_callbacks`. |
| | |
| | | def __call__(self, environ, start_response): |
| | | """ |
| | | Accept ``environ`` and ``start_response``; create a |
| | | :term:`request` and route the request to a :mod:`pyramid` |
| | | :term:`request` and route the request to a :app:`Pyramid` |
| | | view based on introspection of :term:`view configuration` |
| | | within the application registry; call ``start_response`` and |
| | | return an iterable. |
| | |
| | | is a callable (accepting no arguments) that should be called when |
| | | your scripting application is finished using the root. If |
| | | ``request`` is not None, it is used as the request passed to the |
| | | :mod:`pyramid` application root factory. A request is |
| | | :app:`Pyramid` application root factory. A request is |
| | | constructed and passed to the root factory if ``request`` is None.""" |
| | | registry = app.registry |
| | | if request is None: |
| | |
| | | |
| | | class Denied(PermitsResult): |
| | | """ An instance of ``Denied`` is returned when a security-related |
| | | API or other :mod:`pyramid` code denies an action unrelated to |
| | | API or other :app:`Pyramid` code denies an action unrelated to |
| | | an ACL check. It evaluates equal to all boolean false types. It |
| | | has an attribute named ``msg`` describing the circumstances for |
| | | the deny.""" |
| | |
| | | |
| | | class Allowed(PermitsResult): |
| | | """ An instance of ``Allowed`` is returned when a security-related |
| | | API or other :mod:`pyramid` code allows an action unrelated to |
| | | API or other :app:`Pyramid` code allows an action unrelated to |
| | | an ACL check. It evaluates equal to all boolean true types. It |
| | | has an attribute named ``msg`` describing the circumstances for |
| | | the allow.""" |
| | |
| | | |
| | | class static_view(object): |
| | | """ An instance of this class is a callable which can act as a |
| | | :mod:`pyramid` :term:`view callable`; this view will serve |
| | | :app:`Pyramid` :term:`view callable`; this view will serve |
| | | static files from a directory on disk based on the ``root_dir`` |
| | | you provide to its constructor. |
| | | |
| | |
| | | five minutes). |
| | | |
| | | .. note:: If the ``root_dir`` is relative to a :term:`package`, or |
| | | is a :term:`resource specification` the :mod:`pyramid` |
| | | is a :term:`resource specification` the :app:`Pyramid` |
| | | ``resource`` ZCML directive or |
| | | :class:`pyramid.configuration.Configurator` method can be |
| | | used to override resources within the named ``root_dir`` |
| | |
| | | _marker = object() |
| | | |
| | | def registerDummySecurityPolicy(userid=None, groupids=(), permissive=True): |
| | | """ Registers a pair of faux :mod:`pyramid` security policies: |
| | | """ Registers a pair of faux :app:`Pyramid` security policies: |
| | | a :term:`authentication policy` and a :term:`authorization |
| | | policy`. |
| | | |
| | |
| | | :func:`pyramid.security.effective_principals`, and |
| | | :func:`pyramid.security.principals_allowed_by_permission`. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.configuration.Configurator.testing_securitypolicy` |
| | | method in your unit and integration tests. |
| | |
| | | :func:`pyramid.traversal.find_model` is called with an |
| | | equivalent path string or tuple. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.configuration.Configurator.testing_models` |
| | | method in your unit and integration tests. |
| | |
| | | The default value of ``event_iface`` (``None``) implies a |
| | | subscriber registered for *any* kind of event. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.configuration.Configurator.testing_add_subscriber` |
| | | method in your unit and integration tests. |
| | |
| | | other ``render_*`` or ``get_*`` API of the |
| | | :mod:`pyramid.renderers` module. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.configuration.Configurator.testing_add_template`` |
| | | method in your unit and integration tests. |
| | |
| | | |
| | | def registerView(name, result='', view=None, for_=(Interface, Interface), |
| | | permission=None): |
| | | """ Registers a :mod:`pyramid` :term:`view callable` under the |
| | | """ Registers a :app:`Pyramid` :term:`view callable` under the |
| | | name implied by the ``name`` argument. The view will return a |
| | | :term:`WebOb` :term:`Response` object with the value implied by |
| | | the ``result`` argument as its ``body`` attribute. To gain more |
| | |
| | | This function is useful when testing code which calls |
| | | :func:`pyramid.view.render_view_to_response`. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.configuration.Configurator.add_view`` |
| | | method in your unit and integration tests. |
| | |
| | | See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for |
| | | more information about ZCA utilities. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the :meth:`pyramid.Registry.registerUtility` |
| | | method. The ``registry`` attribute of a :term:`Configurator` |
| | | in your unit and integration tests is an instance of the |
| | |
| | | See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for |
| | | more information about ZCA adapters. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the :meth:`pyramid.Registry.registerAdapter` |
| | | method. The ``registry`` attribute of a :term:`Configurator` |
| | | in your unit and integration tests is an instance of the |
| | |
| | | See `The ZCA book <http://www.muthukadan.net/docs/zca.html>`_ for |
| | | more information about ZCA subscribers. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.configuration.Configurator.add_subscriber` |
| | | method in your unit and integration tests. |
| | |
| | | This API is useful for testing code that calls |
| | | e.g. :func:`pyramid.url.route_url`. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.configuration.Configurator.add_route` |
| | | method in your unit and integration tests. |
| | |
| | | calls the :func:`pyramid.settings.get_settings` API and which |
| | | uses return values from that API. |
| | | |
| | | .. warning:: This API is deprecated as of :mod:`pyramid` 1.0. |
| | | .. warning:: This API is deprecated as of :app:`Pyramid` 1.0. |
| | | Instead use the |
| | | :meth:`pyramid.configuration.Configurator.add_settings` |
| | | method in your unit and integration tests. |
| | |
| | | return True |
| | | |
| | | class DummyModel: |
| | | """ A dummy :mod:`pyramid` :term:`model` object.""" |
| | | """ A dummy :app:`Pyramid` :term:`model` object.""" |
| | | def __init__(self, __name__=None, __parent__=None, __provides__=None, |
| | | **kw): |
| | | """ The model's ``__name__`` attribute will be set to the |
| | |
| | | |
| | | def setUp(registry=None, request=None, hook_zca=True): |
| | | """ |
| | | Set :mod:`pyramid` registry and request thread locals for the |
| | | Set :app:`Pyramid` registry and request thread locals for the |
| | | duration of a single unit test. |
| | | |
| | | Use this function in the ``setUp`` method of a unittest test case |
| | |
| | | :func:`pyramid.threadlocal.get_current_request` functions. |
| | | |
| | | If you use the ``testing.register*`` APIs, or the |
| | | ``get_current_*`` functions (or call :mod:`pyramid` code that |
| | | ``get_current_*`` functions (or call :app:`Pyramid` code that |
| | | uses these functions) without calling ``setUp``, |
| | | :func:`pyramid.threadlocal.get_current_registry` will return a |
| | | *global* :term:`application registry`, which may cause unit tests |
| | |
| | | execution of the test. |
| | | |
| | | .. warning:: Although this method of setting up a test registry |
| | | will never disappear, after :mod:`pyramid` 1.0, |
| | | will never disappear, after :app:`Pyramid` 1.0, |
| | | using the ``begin`` and ``end`` methods of a |
| | | ``Configurator`` are preferred to using |
| | | ``pyramid.testing.setUp`` and |
| | |
| | | imported, ignore the argument. |
| | | |
| | | .. warning:: Although this method of tearing a test setup down |
| | | will never disappear, after :mod:`pyramid` 1.0, |
| | | will never disappear, after :app:`Pyramid` 1.0, |
| | | using the ``begin`` and ``end`` methods of a |
| | | ``Configurator`` are preferred to using |
| | | ``pyramid.testing.setUp`` and |
| | |
| | | def cleanUp(*arg, **kw): |
| | | """ :func:`pyramid.testing.cleanUp` is an alias for |
| | | :func:`pyramid.testing.setUp`. Although this function is |
| | | effectively deprecated as of :mod:`pyramid` 1.0, due to its |
| | | effectively deprecated as of :app:`Pyramid` 1.0, due to its |
| | | extensive production usage, it will never be removed.""" |
| | | return setUp(*arg, **kw) |
| | | |
| | |
| | | Provided any :term:`model` and a :term:`request` object, return |
| | | the model object representing the :term:`virtual root` of the |
| | | current :term:`request`. Using a virtual root in a |
| | | :term:`traversal` -based :mod:`pyramid` application permits |
| | | :term:`traversal` -based :app:`Pyramid` application permits |
| | | rooting, for example, the object at the traversal path ``/cms`` at |
| | | ``http://example.com/`` instead of rooting it at |
| | | ``http://example.com/cms/``. |
| | |
| | | resolveable by the |
| | | :func:`pyramid.traversal.find_model` API. |
| | | ``traversal_path`` is a function mostly used by the |
| | | internals of :mod:`pyramid` and by people writing |
| | | internals of :app:`Pyramid` and by people writing |
| | | their own traversal machinery, as opposed to users |
| | | writing applications in :mod:`pyramid`. |
| | | writing applications in :app:`Pyramid`. |
| | | """ |
| | | if isinstance(path, unicode): |
| | | path = path.encode('ascii') |
| | |
| | | from pyramid.traversal import quote_path_segment |
| | | |
| | | def route_url(route_name, request, *elements, **kw): |
| | | """Generates a fully qualified URL for a named :mod:`pyramid` |
| | | """Generates a fully qualified URL for a named :app:`Pyramid` |
| | | :term:`route configuration`. |
| | | |
| | | Use the route's ``name`` as the first positional argument. Use a |
| | |
| | | |
| | | class AppendSlashNotFoundViewFactory(object): |
| | | """ There can only be one :term:`Not Found view` in any |
| | | :mod:`pyramid` application. Even if you use |
| | | :app:`Pyramid` application. Even if you use |
| | | :func:`pyramid.view.append_slash_notfound_view` as the Not |
| | | Found view, :mod:`pyramid` still must generate a ``404 Not |
| | | Found view, :app:`Pyramid` still must generate a ``404 Not |
| | | Found`` response when it cannot redirect to a slash-appended URL; |
| | | this not found response will be visible to site users. |
| | | |
| | |
| | | from pyramid.traversal import quote_path_segment |
| | | |
| | | def wsgiapp(wrapped): |
| | | """ Decorator to turn a WSGI application into a :mod:`pyramid` |
| | | """ Decorator to turn a WSGI application into a :app:`Pyramid` |
| | | :term:`view callable`. This decorator differs from the |
| | | :func:`pyramid.wsgi.wsgiapp2` decorator inasmuch as fixups of |
| | | ``PATH_INFO`` and ``SCRIPT_NAME`` within the WSGI environment *are |
| | |
| | | |
| | | The ``wsgiapp`` decorator will convert the result of the WSGI |
| | | application to a :term:`Response` and return it to |
| | | :mod:`pyramid` as if the WSGI app were a :mod:`pyramid` |
| | | :app:`Pyramid` as if the WSGI app were a :mod:`pyramid` |
| | | view. |
| | | |
| | | """ |
| | |
| | | return wraps(wrapped)(decorator) # grokkability |
| | | |
| | | def wsgiapp2(wrapped): |
| | | """ Decorator to turn a WSGI application into a :mod:`pyramid` |
| | | """ Decorator to turn a WSGI application into a :app:`Pyramid` |
| | | view callable. This decorator differs from the |
| | | :func:`pyramid.wsgi.wsgiapp` decorator inasmuch as fixups of |
| | | ``PATH_INFO`` and ``SCRIPT_NAME`` within the WSGI environment |
| | |
| | | config.add_view(hello_world, name='hello_world.txt') |
| | | |
| | | The ``wsgiapp2`` decorator will convert the result of the WSGI |
| | | application to a Response and return it to :mod:`pyramid` as if |
| | | the WSGI app were a :mod:`pyramid` view. The ``SCRIPT_NAME`` |
| | | application to a Response and return it to :app:`Pyramid` as if |
| | | the WSGI app were a :app:`Pyramid` view. The ``SCRIPT_NAME`` |
| | | and ``PATH_INFO`` values present in the WSGI environment are fixed |
| | | up before the application is invoked. """ |
| | | |