From 7a505dbfc9ae9a5c933072653ac44e4086d26e59 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 11 Jul 2011 23:36:36 -0400 Subject: simplify --- docs/narr/introduction.rst | 82 ++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 46 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a0b682e25..d26f1b8bf 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -10,11 +10,8 @@ ============================== :app:`Pyramid` is a general, open source, Python web application development -*framework*. Its primary goal is to make it easier for a developer to create -web applications. The type of application being created could be a -spreadsheet, a corporate intranet, or a social networking platform; Pyramid's -generality enables it to be used to build an unconstrained variety of web -applications. +*framework*. Its primary goal is to make it easier for a Python developer to +create web applications. .. sidebar:: Frameworks vs. Libraries @@ -33,34 +30,30 @@ applications. own via a set of libraries if the framework provides a set of facilities that fits your application requirements. -The first release of Pyramid's predecessor (named :mod:`repoze.bfg`) was made -in July of 2008. We have worked hard to ensure that Pyramid continues to -follow the design and engineering principles that we consider to be the core -characteristics of a successful framework: +Pyramid attempts to follow follow these design and engineering principles: Simplicity - :app:`Pyramid` takes a *"pay only for what you eat"* approach. This means - that you can get results even if you have only a partial understanding of - :app:`Pyramid`. It doesn’t force you to use any particular technology to - produce an application, and we try to keep the core set of concepts that - you need to understand to a minimum. + :app:`Pyramid` takes a *"pay only for what you eat"* approach. You can get + results even if you have only a partial understanding of :app:`Pyramid`. + It doesn’t force you to use any particular technology to produce an + application, and we try to keep the core set of concepts that you need to + understand to a minimum. Minimalism - :app:`Pyramid` concentrates on providing fast, high-quality solutions to - the fundamental problems of creating a web application: the mapping of URLs - to code, templating, security and serving static assets. We consider these - to be the core activities that are common to nearly all web applications. + :app:`Pyramid` tries to solve only the the fundamental problems of creating + a web application: the mapping of URLs to code, templating, security and + serving static assets. We consider these to be the core activities that are + common to nearly all web applications. Documentation - Pyramid's minimalism means that it is relatively easy for us to maintain - extensive and up-to-date documentation. It is our goal that no aspect of - Pyramid remains undocumented. + Pyramid's minimalism means that it is easier for us to maintain complete + and up-to-date documentation. It is our goal that no aspect of Pyramid + is undocumented. Speed :app:`Pyramid` is designed to provide noticeably fast execution for common - tasks such as templating and simple response generation. Although the - “hardware is cheap” mantra may appear to offer a ready solution to speed - problems, the limits of this approach become painfully evident when one + tasks such as templating and simple response generation. Although “hardware + is cheap", the limits of this approach become painfully evident when one finds him or herself responsible for managing a great many machines. Reliability @@ -75,7 +68,6 @@ Openness .. index:: single: Pylons - single: Agendaless Consulting single: repoze namespace package What Is The Pylons Project? @@ -83,7 +75,7 @@ What Is The Pylons Project? :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 `_ +contributors. The `Pylons Project website `_ includes details about how :app:`Pyramid` relates to the Pylons Project. .. index:: @@ -96,23 +88,22 @@ includes details about how :app:`Pyramid` relates to the Pylons Project. :app:`Pyramid` and Other Web Frameworks ------------------------------------------ -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. +The first release of Pyramid's predecessor (named :mod:`repoze.bfg`) was made +in July of 2008. At the end of 2010, we changed the name of +:mod:`repoze.bfg` to :app:`Pyramid`. It was merged into the Pylons project +as :app:`Pyramid` in November of that year. :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 :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, :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 :app:`Pyramid` were -pioneered first in Zope. +Many features of :app:`Pyramid` trace their origins back to :term:`Zope`. +Like 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 :app:`Pyramid` were pioneered first in Zope. The :app:`Pyramid` concept of :term:`URL dispatch` is inspired by the :term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons @@ -127,15 +118,14 @@ The concept of :term:`view` is used by :app:`Pyramid` mostly as it 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 -: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. :app:`Pyramid` supports :term:`ZCML` and -decorator-based configuration, but does not require either. See -:ref:`configuration_narr` for more information. +Like :term:`Pylons` version 1.0, but unlike :term:`Zope`, a :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. :app:`Pyramid` supports :term:`ZCML` +and decorator-based :term:`declarative 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`, :app:`Pyramid` makes no assumptions about which -- cgit v1.2.3 From 6ce1e0cf1a141767ee0aca70786c15dd993347c5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 20 Jul 2011 06:10:38 -0400 Subject: add more index markers --- docs/narr/introduction.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d26f1b8bf..6cc5a87e5 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -67,8 +67,7 @@ Openness open source license `_. .. index:: - single: Pylons - single: repoze namespace package + single: Pylons Project What Is The Pylons Project? --------------------------- -- cgit v1.2.3 From b202997e2e0b9eed860afc9baa9497ba5b986fb1 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sat, 23 Jul 2011 01:12:03 -0700 Subject: remove extra word --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 6cc5a87e5..63c31d340 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -30,7 +30,7 @@ create web applications. own via a set of libraries if the framework provides a set of facilities that fits your application requirements. -Pyramid attempts to follow follow these design and engineering principles: +Pyramid attempts to follow these design and engineering principles: Simplicity :app:`Pyramid` takes a *"pay only for what you eat"* approach. You can get -- cgit v1.2.3 From 55ce9d632f828d285360c1abee9f56042243cac9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 28 Aug 2011 22:15:48 -0400 Subject: clean up inappropriate discussions of ZCML --- docs/narr/introduction.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 63c31d340..97f63fcfe 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -122,9 +122,9 @@ 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. :app:`Pyramid` supports :term:`ZCML` -and decorator-based :term:`declarative configuration`, but does not require -either. See :ref:`configuration_narr` for more information. +declarations are used for this purpose. Out of the box, Pyramid supports +imperative and decorator-based configuration; :term:`ZCML` may be used via an +add-on package named ``pyramid_zcml``. Also unlike :term:`Zope` and unlike other "full-stack" frameworks such as :term:`Django`, :app:`Pyramid` makes no assumptions about which -- cgit v1.2.3 From bb93cbdf16ac03e354569959663d053a68685fc5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 05:56:14 -0400 Subject: add squishy whats-unique section to introduction --- docs/narr/introduction.rst | 467 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 464 insertions(+), 3 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 97f63fcfe..5524f698d 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -52,20 +52,481 @@ Documentation Speed :app:`Pyramid` is designed to provide noticeably fast execution for common - tasks such as templating and simple response generation. Although “hardware + tasks such as templating and simple response generation. Although "hardware is cheap", the limits of this approach become painfully evident when one finds him or herself responsible for managing a great many machines. Reliability :app:`Pyramid` is developed conservatively and tested exhaustively. Where Pyramid source code is concerned, our motto is: "If it ain’t tested, it’s - broke". Every release of Pyramid has 100% statement coverage via unit - tests. + broke". Openness As with Python, the Pyramid software is distributed under a `permissive open source license `_. +What Makes Pyramid Unique +------------------------- + +Understandably, people don't usually want to hear about squishy engineering +principles, they want to hear about concrete stuff that solves their +problems. With that in mind, what would make someone want to use Pyramid +instead of the dozens-of-odd other web frameworks available today? What +makes Pyramid unique? + +This is a hard question to answer, because there are lots of excellent +choices, and it's actually quite hard to make a wrong choice, particularly in +the Python web framework market. But one reasonable answer is this: you can +write very small applications in Pyramid without needing to know a lot. +"What?", you say, "that can't possibly be a unique feature, lots of other web +frameworks let you do that!" Well, you're right. But unlike many other +systems, you can also write very large applications in Pyramid if you learn a +little more about it. Pyramid will allow you to become productive quickly, +and will grow with you; it won't hold you back when your application is small +and it won't get in your way when your application becomes large. "Well +that's fine," you say, "lots of other frameworks let me write large apps +too." Absolutely. But other Python web frameworks don't seamlessly let you +do both. They seem to fall into two non-overlapping categories: frameworks +for "small apps" and frameworks for "big apps". The "small app" frameworks +typically sacrifice "big app" features, and vice versa. + +We don't think it's a universally reasonable suggestion to write "small apps" +in a "small framework" and "big apps" in a "big framework". You can't really +know what size every application will eventually grow to. We don't really +want to have to rewrite a previously small application in another framework +when it gets "too big". We believe the current binary distinction between +"small" and "large" frameworks is just false; one framework should be able to +be good at both if it's well-designed. Pyramid is such a framework. + +To this end, Pyramid provides a set of features, that, combined, are unique +amongst Python web frameworks. Lots of other frameworks contain some +combination of these features; Pyramid of course actually stole many of them +from those other frameworks. But Pyramid is the only one that has all of +them in one place, documented appropriately, and useful ala-carte without +necessarily paying for the entire banquet. These are detailed below. + +Single-File Applications +~~~~~~~~~~~~~~~~~~~~~~~~ + +You can write a Pyramid application that lives entirely in one Python file, +not unlike existing Python microframeworks. This is beneficial for "one off" +prototyping, bug reproduction, and very small applications. These +applications are easy to understand because all the information about the +application lives in a single place, and you can deploy them without needing +to understand much about Python distributions and packaging. Pyramid isn't +really marketed as a "microframework", but it allows you to do almost +everything that frameworks that are marketed as "micro" offer in very similar +ways. + +Example: :ref:`firstapp_chapter`. + +Decorator-Based Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you like the idea of framework configuration statements living next to the +code it configures, so you don't have to constantly switch between files to +refer to framework configuration when adding new code, you can use Pyramid +decorators to localize the configuration. For example:: + + @view_config(route_name='fred') + def fred_view(request): + return Response('fred') + +However, unlike other systems (various "microframeworks" come to mind), using +decorators for configuration does not make your application difficult, +extend, test or reuse. The ``view_config`` decorator, for example, does not +actually *change* the input or output of the function it decorates, so +testing it is a "WYSIWYG" operation; you don't need to understand the +framework to test your own code, you just behave as if the decorator is not +there. You can also instruct Pyramid to ignore some decorators, or use +completely imperative configuration instead of decorators to add views. +Pyramid decorators are inert instead of eager: you detect and activate them +with a ``scan``. They're basically just markers. + +Example: :ref:`mapping_views_using_a_decorator_section`. + +URL Generation +~~~~~~~~~~~~~~ + +Pyramid is capable of generating URLs for resources, routes, and static +assets. Its URL generation APIs are easy to use and flexible. If you use +Pyramid's various APIs for generating URLs, you can change your configuration +around arbitrarily without fear of breaking a link on one of your web pages. + +Example: :ref:`generating_route_urls`. + +Static file serving +~~~~~~~~~~~~~~~~~~~ + +Pyramid is perfectly willing to serve static files itself. It won't make you +use some external web server to do that. You can even serve more than one +set of static files in a single Pyramid web application (e.g. ``/static`` and +``/static2``). You can also, optionally, place your files on an external web +server and ask Pyramid to help you generate URLs to those files, so you can +use Pyramid's internal fileserving while doing development, and a faster +static file server in production without changing any code. + +Example: :ref:`static_assets_section`. + +Debug Toolbar +~~~~~~~~~~~~~ + +Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to +render a project. This toolbar overlays your application in the browser, and +allows you access to framework data such as the routes configured, the last +renderings performed, the current set of packages installed, SQLAlchemy +queries run, logging data, and various other facts. When an exception +occurs, you can use its interactive debugger to poke around right in your +browser to try to determine the cause of the exception. It's handy. + +Example: :ref:`debug_toolbar`. + +Debugging settings +~~~~~~~~~~~~~~~~~~ + +Pyramid has debugging settings that allow you to print Pyramid runtime +information to the console when things aren't behaving as you're expecting. +For example, you can turn on "debug_notfound", which prints an informative +message to the console every time a URL does not match any view. You can +turn on "debug_authorization", which lets you know why a view execution was +allowed or denied by printing a message to the console. These features are +useful for those WTF moments. + +There are also a number of ``paster`` commands that allow you to introspect +the configuration of your system: ``paster proutes`` shows all configured +routes for an application in the order they'll be evaluated for matching; +``paster pviews`` shows all configured views for any given URL. These are +also WTF-crushers in some circumstances. + +Example: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. + +Class-Based and Function-Based Views +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid has a structured, unified conception of views. Views can be +functions, methods of classes, or even instances. When you add a new view, +you can choose to make it a function or a method of a class; in either case, +Pyramid treats it largely the same way. You can change your mind later, and +move code between methods of classes and functions. A collection of similar +view callables can be attached to a single class as methods, if that floats +your boat, and they can share initialization code as necessary. All kinds of +views are easy to understand and use and operate similarly. There is no +phony distinction between them; they can be used for the same purposes. + +Example: :ref:`view_config_placement`. + +Event system +~~~~~~~~~~~~ + +Pyramid emits *events* during its request processing lifecycle. You can +subscribe any number of listeners to these events. For example, to be +notified of a new request, you can subscribe to the ``NewRequest`` event. To +be notified that a template is about to be rendered, you can subscribe to the +``BeforeRender`` event, and so forth. Using an event publishing system as a +framework notification feature instead of hardcoded hook points tends to make +systems based on that framework less brittle. You can also use Pyramid's +event system to send your *own* events. For example, if you'd like to create +a system that is itself a framework, and may want to notify subscribers that +a document has just been indexed, you can create your own event type +(``DocumentIndexed`` perhaps) and send the event via Pyramid. Users of this +framework can then subscribe to your event like they'd subscribe to the +events that are normally sent by Pyramid itself. + +Example: :ref:`events_chapter` and :ref:`event_types`. + +Extensible templating +~~~~~~~~~~~~~~~~~~~~~ + +Pyramid has a structured API that allows for pluggability of "renderers". +Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated +as renderers. Renderer bindings for all of these templating systems already +exist for use in Pyramid. But if you'd rather use another, it's not a big +deal. Just copy the code from an existing renderer package, and plug in your +own. You'll then be able to use your templating system from within Pyramid +just as you'd use one of the "built-in" templating systems. + +Example: :ref:`templates_used_directly`. + +Speed +~~~~~ + +The Pyramid core is, as far as we can tell, at least marginally faster than +any other existing Python web framework. It has been engineered from the +ground up for speed. It only does as much work as absolutely necessary when +you ask it to get a job done. Extraneous function calls and suboptimal +algorithms in its core codepaths are avoided religiously. It is feasible to +get, for example, between 3500 and 4000 requests per second from a simple +Pyramid view on commodity dual-core laptop hardware and an appropriate WSGI +server (mod_wsgi or gunicorn). In any case, performance statstics are +largely useless without requirements and goals, but if you need speed, +Pyramid will almost certainly never be your application's bottleneck; at +least no more than Python will be a bottleneck. + +Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ + +Sessions +~~~~~~~~ + +Pyramid has built-in HTTP sessioning. This allows you to associate data with +otherwise anonymous users between requests. Lots of systems do this. But +Pyramid also allows you to plug in your own sessioning system by creating +some code that adheres to a documented interface. Currently there is a +binding package for the Beaker sessioning system that does exactly this. But +if you have a specialized need (perhaps you want to store your session data +in MongoDB), you can. You can even switch between implementations without +changing your application code. + +Example: :ref:`sessions_chapter`. + +No singletons +~~~~~~~~~~~~~ + +Pyramid is written in such a way that it has exactly zero "singleton" data +structures. Or, put another way, Pyramid constructs no "mutable globals". +Or put even a different way, an import of a Pyramid application needn't have +any "import time side effects". This is esoteric-sounding, but if you've +ever tried to cope with parameterizing a Django "settings.py" file for +multiple installations of the same application, or if you've ever needed to +monkey-patch some framework fixture so that it behaves properly for your use +case, or if you've ever wanted to deploy your system using an asynchronous +server, you'll end up appreciating this feature. It just won't be a problem. +You can even run multiple copies of a similar but not identically configured +Pyramid application within the same Python process. This is good for shared +hosting environments, where RAM is at a premium. + +View Predicates and Many Views Per Route +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unlike many other systems, Pyramid allows you to associate more than one view +per route. For example, you can create a route with the pattern ``/items`` +and when the route is matched, you can shuffle off the request to one view if +the request method is GET, another view if the request method is POST, etc. +A system known as "view predicates" allows for this. Request method matching +is the very most basic thing you can do with a view predicate. You can also +associate views with other request parameters such as the elements in the +query string, the Accept header, whether the request is an XHR request or +not, and lots of other things. This feature allows you to keep your +individual views "clean"; they won't need much conditional logic, so they'll +be easier to test. + +Example: :ref:`view_configuration_parameters`. + +Exception views +~~~~~~~~~~~~~~~ + +Exceptions happen. Rather than deal with exceptions that might present +themselves to a user in production in an ad-hoc way, Pyramid allows you to +register *exception views*. Exception views are like regular Pyramid views, +but they're only invoked when an exception "bubbles up" to Pyramid itself. +For example, you might register an exception view for the ``Exception`` +exception, which will catch *all* exceptions, and present a pretty "whoops, +this is embarrassing" page. Or you might choose to register an exception +view for only specific kinds of application-specific exceptions, such as an +exception that happens when a file is not found, or an exception that happens +when action cannot be performed because the user doesn't have permission to +do something. In the former case, you can show a pretty "Not Found" page; in +the latter case you might show a login form. + +Example: :ref:`exception_views`. + +Asset specifications +~~~~~~~~~~~~~~~~~~~~ + +Asset specifications are strings that contain both a Python package name and +a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these +specifications is omnipresent in Pyramid. You can refer to a template using +an asset specification, a translation directory, and other package-bound +static resources using one. This makes a system built on Pyramid extensible, +because you don't have to rely on globals ("the static directory") or lookup +schemes ("the ordered set of template directories") to address your files. +You can move files around as necessary, and include other packages that may +not share your system's templates or static files without encountering +conflicts. + +Because asset specifications are used heavily in Pyramid, we've also provided +a way to allow users to override assets. Say you love a system that someone +else has created with Pyramid but you just need to change "that one template" +to make it all better. No need to fork the application. Just override the +asset specification for that template with your own inside a wrapper, and +you're good to go. + +Example: :ref:`asset_specifications`. + +Transaction management +~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid's :term:`scaffold` system renders projects that include a +*transaction management* system, also stolen from Zope. When you use this +transaction management system, you cease being responsible for committing +your data anymore. Instead, Pyramid takes care of committing: it commits at +the end of a request or aborts if there's an exception. Why is that a good +thing? Transaction boundaries are awfully hard to get right. If you add a +``session.commit`` call in your application logic, and your code goes on to +do other important things after that commit, and error happens in the later +code, sometimes, you're kind of screwed. Some data will have been written to +the database that probably should not have. Having a centralized commit +point saves you from needing to think about this. Also, Pyramid's +transaction management system allows you to synchronize commits between +multiple databases, and allows you to do things like conditionally send email +if a transaction commits, but otherwise keep quiet. + +Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements +anywhere in application code). + +Configuration conflict detection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When a system is small, it's reasonably easy to keep it in all in your head. +But when systems grow large, you may have hundreds or thousands of +configuration statements which add a view, add a route, and so forth. +Pyramid's configuration system keeps track of your configuration statements, +and if you accidentally add two that are identical, or Pyramid can't make +sense out of what it would mean to have both statements active at the same +time, it will complain loudly at startup time. It's not dumb though: it will +automatically resolve conflicting configuration statements on its own if you +use the configuration ``include`` system: "more local" statements are +preferred over "less local" ones. This allows you to intelligently factor +large systems into smaller ones. + +Example: :ref:`conflict_detection`. + +Configuration extensibility +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unlike other systems, Pyramid provides a structured ``include`` mechanism +that allows you compose applications from multiple Python packages. All the +configuration statements that can be performed in your "main" Pyramid +application can also be performed by included packages (including the +addition of views, routes, subscribers, and even authentication and +authorization policies). You can even extend or override an existing +application by including another application's configuration in your own, and +overriding or adding new views and routes to it. This has the potential to +allow you to compose a big application out of many other smaller ones. For +example, if you want to reuse an existing application that already has a +bunch of routes, you can just use the ``include`` statement with a +``route_prefix``; the new application will live within your application at a +URL prefix. It's not a big deal, and requires little up-front engineering +effort. + +Example: :ref:`building_an_extensible_app`. + +Flexible authentication and authorization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid includes a flexible, pluggable authentication and authorization +system. No matter where your user data is stored, or what scheme you'd like +to use to permit your users to access your data, you can use a predefined +Pyramid plugpoint to plug in your custom authentication and authorization +code. If you want to change these schemes later, you can just change it in +one place rather than everywhere in your code. It also ships with prebuilt +well-tested authentication and authorization schemes out of the box. But +what if you don't want to use Pyramid's built-in system? You don't have to. +You can just write your own bespoke security code as you would in any other +system. + +Example: :ref:`enabling_authorization_policy`. + +Built-in Internationalization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid ships with internalization-related features in its core: +localization, pluralization, and creating message catalogs from source files +and templates. Pyramid allows for a plurality of message catalog via the use +of translation domains: you can create a system that has its own translations +without conflict with other translations in other domains. + +Example: :ref:`i18n_chapter`. + +Traversal +~~~~~~~~~ + +:term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to +create a tree of resources, each of which can be addressed by one or more +URLs. Each of those resources can have one or more *views* associated with +it. Iif your data isn't naturally treelike (or you're unwilling to create a +treelike representation of your data), you aren't going to find traversal +very useful. However, traversal is absolutely fantastic for sites that need +to be arbitrarily extensible: it's a lot easier to add a node to a tree than +it is to shoehorn a route into an ordered list of other routes, or to create +another entire instance of an application to service a department and glue +code to allow disparate apps to share data. It's a great fit for sites that +naturally lend themselves to changing departmental hierarchies, such as CMS +systems and document management systems. Traversal also lends itself well to +systems that require very granular security ("Bob can edit *this* document" +as opposed to "Bob can edit documents"). + +Example: :ref:`much_ado_about_traversal_chapter`. + +HTTP Caching +~~~~~~~~~~~~ + +Pyramid provides an easy way to associate views with HTTP caching policies. +You can just tell Pyramid to configure your view with an ``http_cache`` +statement, and it will take care of the rest:: + + @view_config(http_cache=3600) # 60 minutes + def myview(request): .... + +Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to +responses generated when this view is invoked. + +See the :meth:`pyramid.config.Configurator.add_view` statement's +``http_cache`` documentation for more information. + +Tweens +~~~~~~ + +Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be +hooked by arbitrary add-ons named "tweens". The debug toolbar is a "tween", +and the ``pyramid_tm`` transaction manager is also. Tweens are more useful +than WSGI middleware in some circumstances because they run in the context of +Pyramid itself, meaning you have access to templates and other renderers, a +"real" request object, and other niceties. + +Example: :ref:`registering_tweens`. + +Testing +~~~~~~~ + +Every release of Pyramid has 100% statement coverage via unit and integration +tests, as measured by the ``coverage`` tool available on PyPI. It also has +greater than 95% decision/condition coverage as measured by the +``instrumental`` tool available on PyPI. It is automatically tested by the +Jenkins tool on Python 2.5, Python 2.6, Python 2.7, Jython and PyPy after +each commit to its GitHub repository. Official Pyramid add-ons are held to a +similar testing standard. We still find bugs in Pyramid and its official +add-ons, but we find a lot fewer of them than do the owners of comparable +projects that don't test so exhaustively. + +Example: http://jenkins.pylonsproject.org/ + +Support +~~~~~~~ + +It's our goal that no Pyramid question go unanswered. Whether you ask a +question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're +likely to get a reasonaly prompt response. We don't tolerate "tech trolls" +or other people who seem to get their rocks off by berating fellow users in +our various offical support channels. We try to keep it well-lit and +new-user-friendly. + +Example: Visit irc://freenode.net#pyramid (the ``#pyramid`` channel on +irc.freenode.net in an IRC client) or the pylons-discuss maillist at +http://groups.google.com/group/pylons-discuss/ . + +Documentation +~~~~~~~~~~~~~ + +It's a constant struggle, but we try to maintain a balance between +completeness and new-user-friendliness in the official narrative Pyramid +documentation (concrete suggestions for improvement are always appreciated, +by the way). We also maintain a "cookbook" of recipes, which are usually +demonstrations of common integration scenarios, too specific to add to the +official narrative docs. In any case, the Pyramid documentation is +comprehensive. + +Example: The rest of this documentation. + .. index:: single: Pylons Project -- cgit v1.2.3 From d8fc16f447c1a9ac91a24bb41f56a534706dfe41 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 06:26:28 -0400 Subject: garden --- docs/narr/introduction.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 5524f698d..9c6f85680 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -65,6 +65,8 @@ Openness As with Python, the Pyramid software is distributed under a `permissive open source license `_. +.. _what_makes_pyramid_unique: + What Makes Pyramid Unique ------------------------- -- cgit v1.2.3 From 2bf587e2975063ae402f3d543fbbbf9dfff86383 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 06:52:22 -0400 Subject: typo --- docs/narr/introduction.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 9c6f85680..5f4e3c13b 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -116,7 +116,7 @@ prototyping, bug reproduction, and very small applications. These applications are easy to understand because all the information about the application lives in a single place, and you can deploy them without needing to understand much about Python distributions and packaging. Pyramid isn't -really marketed as a "microframework", but it allows you to do almost +really marketed as a microframework, but it allows you to do almost everything that frameworks that are marketed as "micro" offer in very similar ways. @@ -134,16 +134,16 @@ decorators to localize the configuration. For example:: def fred_view(request): return Response('fred') -However, unlike other systems (various "microframeworks" come to mind), using -decorators for configuration does not make your application difficult, -extend, test or reuse. The ``view_config`` decorator, for example, does not -actually *change* the input or output of the function it decorates, so -testing it is a "WYSIWYG" operation; you don't need to understand the -framework to test your own code, you just behave as if the decorator is not -there. You can also instruct Pyramid to ignore some decorators, or use -completely imperative configuration instead of decorators to add views. -Pyramid decorators are inert instead of eager: you detect and activate them -with a ``scan``. They're basically just markers. +However, unlike some other systems, using decorators for Pyramid +configuration does not make your application difficult to extend, test or +reuse. The ``view_config`` decorator, for example, does not actually +*change* the input or output of the function it decorates, so testing it is a +"WYSIWYG" operation; you don't need to understand the framework to test your +own code, you just behave as if the decorator is not there. You can also +instruct Pyramid to ignore some decorators, or use completely imperative +configuration instead of decorators to add views. Pyramid decorators are +inert instead of eager: you detect and activate them with a ``scan``. +They're basically just markers. Example: :ref:`mapping_views_using_a_decorator_section`. -- cgit v1.2.3 From e088447d0fb4a908d1da07742301a3d01b48ade5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 12:24:29 -0400 Subject: add renderer section; fix wording (thanks jpenny) --- docs/narr/introduction.rst | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 5f4e3c13b..c39b7f440 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -73,8 +73,8 @@ What Makes Pyramid Unique Understandably, people don't usually want to hear about squishy engineering principles, they want to hear about concrete stuff that solves their problems. With that in mind, what would make someone want to use Pyramid -instead of the dozens-of-odd other web frameworks available today? What -makes Pyramid unique? +instead of one of the many other web frameworks available today? What makes +Pyramid unique? This is a hard question to answer, because there are lots of excellent choices, and it's actually quite hard to make a wrong choice, particularly in @@ -97,8 +97,9 @@ in a "small framework" and "big apps" in a "big framework". You can't really know what size every application will eventually grow to. We don't really want to have to rewrite a previously small application in another framework when it gets "too big". We believe the current binary distinction between -"small" and "large" frameworks is just false; one framework should be able to -be good at both if it's well-designed. Pyramid is such a framework. +"small" and "large" frameworks is just false; a well-designed framework +should be able to be good at both. Pyramid strives to be that kind of +framework. To this end, Pyramid provides a set of features, that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some @@ -217,6 +218,19 @@ phony distinction between them; they can be used for the same purposes. Example: :ref:`view_config_placement`. +Views can return dictionaries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you use a :term:`renderer`, you don't have to return a special kind of +"webby" ``Response`` object from a view. Instead, you can return a +dictionary instead, and Pyramid will take care of converting that dictionary +to a Response using a template of your behalf. This makes the view easier +to test, because you don't have to parse HTML in your tests; just make an +assertion instead that the view returns "the right stuff" in the dictionary +it returns. + +Example: :ref:`renderers_chapter`. + Event system ~~~~~~~~~~~~ -- cgit v1.2.3 From 31dc8d526dc58bf56179d6a7417a83fefdc7f475 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 12:43:17 -0400 Subject: misspelling --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index c39b7f440..eefac9812 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -105,7 +105,7 @@ To this end, Pyramid provides a set of features, that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some combination of these features; Pyramid of course actually stole many of them from those other frameworks. But Pyramid is the only one that has all of -them in one place, documented appropriately, and useful ala-carte without +them in one place, documented appropriately, and useful a la carte without necessarily paying for the entire banquet. These are detailed below. Single-File Applications -- cgit v1.2.3 From 1bca77cc705622da6aa1b163917a22f35e8c01d3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 12:45:28 -0400 Subject: chronology --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index eefac9812..a672c82ad 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -372,7 +372,7 @@ Transaction management ~~~~~~~~~~~~~~~~~~~~~~ Pyramid's :term:`scaffold` system renders projects that include a -*transaction management* system, also stolen from Zope. When you use this +*transaction management* system, stolen from Zope. When you use this transaction management system, you cease being responsible for committing your data anymore. Instead, Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good -- cgit v1.2.3 From 397f25da241db06d8cbe4fbcfc5e65d5e7dc00ff Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 13:57:17 -0400 Subject: de-theify --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a672c82ad..d93a9c54d 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -270,7 +270,7 @@ The Pyramid core is, as far as we can tell, at least marginally faster than any other existing Python web framework. It has been engineered from the ground up for speed. It only does as much work as absolutely necessary when you ask it to get a job done. Extraneous function calls and suboptimal -algorithms in its core codepaths are avoided religiously. It is feasible to +algorithms in its core codepaths are studiously avoided. It is feasible to get, for example, between 3500 and 4000 requests per second from a simple Pyramid view on commodity dual-core laptop hardware and an appropriate WSGI server (mod_wsgi or gunicorn). In any case, performance statstics are -- cgit v1.2.3 From b1d3065aad02204b2d2fe38976018bdc4ddd0c9d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 14:24:59 -0400 Subject: avoid needless generic comparison --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d93a9c54d..6e28500d1 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -511,8 +511,8 @@ greater than 95% decision/condition coverage as measured by the Jenkins tool on Python 2.5, Python 2.6, Python 2.7, Jython and PyPy after each commit to its GitHub repository. Official Pyramid add-ons are held to a similar testing standard. We still find bugs in Pyramid and its official -add-ons, but we find a lot fewer of them than do the owners of comparable -projects that don't test so exhaustively. +add-ons, but we find a lot fewer of them than if we didn't have a strict +testing regime. Example: http://jenkins.pylonsproject.org/ -- cgit v1.2.3 From 5962195498f53a349b101c9c8ca19daa9c1c9972 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 14:41:10 -0400 Subject: wording --- docs/narr/introduction.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 6e28500d1..b7721f186 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -94,12 +94,12 @@ typically sacrifice "big app" features, and vice versa. We don't think it's a universally reasonable suggestion to write "small apps" in a "small framework" and "big apps" in a "big framework". You can't really -know what size every application will eventually grow to. We don't really +know to what size every application will eventually grow. We don't really want to have to rewrite a previously small application in another framework when it gets "too big". We believe the current binary distinction between -"small" and "large" frameworks is just false; a well-designed framework -should be able to be good at both. Pyramid strives to be that kind of -framework. +frameworks for small and large applications is just false; a well-designed +framework should be able to be good at both. Pyramid strives to be that kind +of framework. To this end, Pyramid provides a set of features, that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some -- cgit v1.2.3 From bdebfb826ebee25f7f8358b89761429ca89ec249 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 15:03:25 -0400 Subject: wording --- docs/narr/introduction.rst | 103 ++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 47 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b7721f186..87617989a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -129,7 +129,12 @@ Decorator-Based Configuration If you like the idea of framework configuration statements living next to the code it configures, so you don't have to constantly switch between files to refer to framework configuration when adding new code, you can use Pyramid -decorators to localize the configuration. For example:: +decorators to localize the configuration. For example: + +.. code-block:: python + + from pyramid.view import view_config + from pyramid.response import Response @view_config(route_name='fred') def fred_view(request): @@ -137,14 +142,14 @@ decorators to localize the configuration. For example:: However, unlike some other systems, using decorators for Pyramid configuration does not make your application difficult to extend, test or -reuse. The ``view_config`` decorator, for example, does not actually -*change* the input or output of the function it decorates, so testing it is a -"WYSIWYG" operation; you don't need to understand the framework to test your -own code, you just behave as if the decorator is not there. You can also -instruct Pyramid to ignore some decorators, or use completely imperative -configuration instead of decorators to add views. Pyramid decorators are -inert instead of eager: you detect and activate them with a ``scan``. -They're basically just markers. +reuse. The :class:`~pyramid.view.view_config` decorator, for example, does +not actually *change* the input or output of the function it decorates, so +testing it is a "WYSIWYG" operation; you don't need to understand the +framework to test your own code, you just behave as if the decorator is not +there. You can also instruct Pyramid to ignore some decorators, or use +completely imperative configuration instead of decorators to add views. +Pyramid decorators are inert instead of eager: you detect and activate them +with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. @@ -206,15 +211,16 @@ Example: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. Class-Based and Function-Based Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid has a structured, unified conception of views. Views can be -functions, methods of classes, or even instances. When you add a new view, -you can choose to make it a function or a method of a class; in either case, -Pyramid treats it largely the same way. You can change your mind later, and -move code between methods of classes and functions. A collection of similar -view callables can be attached to a single class as methods, if that floats -your boat, and they can share initialization code as necessary. All kinds of -views are easy to understand and use and operate similarly. There is no -phony distinction between them; they can be used for the same purposes. +Pyramid has a structured, unified conception of a :term:`view callable`. +View callables can be functions, methods of classes, or even instances. When +you add a new view callable, you can choose to make it a function or a method +of a class; in either case, Pyramid treats it largely the same way. You can +change your mind later, and move code between methods of classes and +functions. A collection of similar view callables can be attached to a +single class as methods, if that floats your boat, and they can share +initialization code as necessary. All kinds of views are easy to understand +and use and operate similarly. There is no phony distinction between them; +they can be used for the same purposes. Example: :ref:`view_config_placement`. @@ -224,10 +230,11 @@ Views can return dictionaries If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a dictionary instead, and Pyramid will take care of converting that dictionary -to a Response using a template of your behalf. This makes the view easier -to test, because you don't have to parse HTML in your tests; just make an +to a Response using a template on your behalf. This makes the view easier to +test, because you don't have to parse HTML in your tests; just make an assertion instead that the view returns "the right stuff" in the dictionary -it returns. +it returns. You can write "real" unit tests instead of functionally testing +all of your views. Example: :ref:`renderers_chapter`. @@ -240,13 +247,14 @@ notified of a new request, you can subscribe to the ``NewRequest`` event. To be notified that a template is about to be rendered, you can subscribe to the ``BeforeRender`` event, and so forth. Using an event publishing system as a framework notification feature instead of hardcoded hook points tends to make -systems based on that framework less brittle. You can also use Pyramid's -event system to send your *own* events. For example, if you'd like to create -a system that is itself a framework, and may want to notify subscribers that -a document has just been indexed, you can create your own event type -(``DocumentIndexed`` perhaps) and send the event via Pyramid. Users of this -framework can then subscribe to your event like they'd subscribe to the -events that are normally sent by Pyramid itself. +systems based on that framework less brittle. + +You can also use Pyramid's event system to send your *own* events. For +example, if you'd like to create a system that is itself a framework, and may +want to notify subscribers that a document has just been indexed, you can +create your own event type (``DocumentIndexed`` perhaps) and send the event +via Pyramid. Users of this framework can then subscribe to your event like +they'd subscribe to the events that are normally sent by Pyramid itself. Example: :ref:`events_chapter` and :ref:`event_types`. @@ -258,8 +266,9 @@ Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated as renderers. Renderer bindings for all of these templating systems already exist for use in Pyramid. But if you'd rather use another, it's not a big deal. Just copy the code from an existing renderer package, and plug in your -own. You'll then be able to use your templating system from within Pyramid -just as you'd use one of the "built-in" templating systems. +favorite templating system. You'll then be able to use that templating +system from within Pyramid just as you'd use one of the "built-in" templating +systems. Example: :ref:`templates_used_directly`. @@ -270,13 +279,13 @@ The Pyramid core is, as far as we can tell, at least marginally faster than any other existing Python web framework. It has been engineered from the ground up for speed. It only does as much work as absolutely necessary when you ask it to get a job done. Extraneous function calls and suboptimal -algorithms in its core codepaths are studiously avoided. It is feasible to -get, for example, between 3500 and 4000 requests per second from a simple -Pyramid view on commodity dual-core laptop hardware and an appropriate WSGI -server (mod_wsgi or gunicorn). In any case, performance statstics are -largely useless without requirements and goals, but if you need speed, -Pyramid will almost certainly never be your application's bottleneck; at -least no more than Python will be a bottleneck. +algorithms in its core codepaths are avoided. It is feasible to get, for +example, between 3500 and 4000 requests per second from a simple Pyramid view +on commodity dual-core laptop hardware and an appropriate WSGI server +(mod_wsgi or gunicorn). In any case, performance statstics are largely +useless without requirements and goals, but if you need speed, Pyramid will +almost certainly never be your application's bottleneck; at least no more +than Python will be a bottleneck. Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ @@ -287,10 +296,10 @@ Pyramid has built-in HTTP sessioning. This allows you to associate data with otherwise anonymous users between requests. Lots of systems do this. But Pyramid also allows you to plug in your own sessioning system by creating some code that adheres to a documented interface. Currently there is a -binding package for the Beaker sessioning system that does exactly this. But -if you have a specialized need (perhaps you want to store your session data -in MongoDB), you can. You can even switch between implementations without -changing your application code. +binding package for the third-part Beaker sessioning system that does exactly +this. But if you have a specialized need (perhaps you want to store your +session data in MongoDB), you can. You can even switch between +implementations without changing your application code. Example: :ref:`sessions_chapter`. @@ -511,8 +520,8 @@ greater than 95% decision/condition coverage as measured by the Jenkins tool on Python 2.5, Python 2.6, Python 2.7, Jython and PyPy after each commit to its GitHub repository. Official Pyramid add-ons are held to a similar testing standard. We still find bugs in Pyramid and its official -add-ons, but we find a lot fewer of them than if we didn't have a strict -testing regime. +add-ons, but we've noticed we find a lot fewer of them than while working on +other projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ @@ -521,10 +530,10 @@ Support It's our goal that no Pyramid question go unanswered. Whether you ask a question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're -likely to get a reasonaly prompt response. We don't tolerate "tech trolls" -or other people who seem to get their rocks off by berating fellow users in -our various offical support channels. We try to keep it well-lit and -new-user-friendly. +likely to get a reasonably prompt response. We don't tolerate "support +trolls" or other people who seem to get their rocks off by berating fellow +users in our various offical support channels. We try to keep it well-lit +and new-user-friendly. Example: Visit irc://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at -- cgit v1.2.3 From 77ef3b0d26357ba36f5577924b0bef0b3365d1a6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 15:24:22 -0400 Subject: wording --- docs/narr/introduction.rst | 80 ++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 39 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 87617989a..d23a1f22f 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -341,16 +341,16 @@ Exception views Exceptions happen. Rather than deal with exceptions that might present themselves to a user in production in an ad-hoc way, Pyramid allows you to -register *exception views*. Exception views are like regular Pyramid views, -but they're only invoked when an exception "bubbles up" to Pyramid itself. -For example, you might register an exception view for the ``Exception`` -exception, which will catch *all* exceptions, and present a pretty "whoops, -this is embarrassing" page. Or you might choose to register an exception -view for only specific kinds of application-specific exceptions, such as an -exception that happens when a file is not found, or an exception that happens -when action cannot be performed because the user doesn't have permission to -do something. In the former case, you can show a pretty "Not Found" page; in -the latter case you might show a login form. +register an :term:`exception view`. Exception views are like regular Pyramid +views, but they're only invoked when an exception "bubbles up" to Pyramid +itself. For example, you might register an exception view for the +:exc:`Exception` exception, which will catch *all* exceptions, and present a +pretty "well, this is embarrassing" page. Or you might choose to register an +exception view for only specific kinds of application-specific exceptions, +such as an exception that happens when a file is not found, or an exception +that happens when action cannot be performed because the user doesn't have +permission to do something. In the former case, you can show a pretty "Not +Found" page; in the latter case you might show a login form. Example: :ref:`exception_views`. @@ -385,15 +385,16 @@ Pyramid's :term:`scaffold` system renders projects that include a transaction management system, you cease being responsible for committing your data anymore. Instead, Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good -thing? Transaction boundaries are awfully hard to get right. If you add a -``session.commit`` call in your application logic, and your code goes on to -do other important things after that commit, and error happens in the later -code, sometimes, you're kind of screwed. Some data will have been written to -the database that probably should not have. Having a centralized commit -point saves you from needing to think about this. Also, Pyramid's -transaction management system allows you to synchronize commits between -multiple databases, and allows you to do things like conditionally send email -if a transaction commits, but otherwise keep quiet. +thing? Having a centralized place for transaction management is a great +thing. If you instead add a ``session.commit`` call in your application +logic itself, and your code goes on to do other important things after that +commit, and error happens in the later code, you can easily wind up in a bad +place. Some data will have been written to the database that probably should +not have. Having a centralized commit point saves you from needing to think +about this. Also, Pyramid's transaction management system allows you to +synchronize commits between multiple databases, and allows you to do things +like conditionally send email if a transaction commits, but otherwise keep +quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements anywhere in application code). @@ -409,29 +410,29 @@ and if you accidentally add two that are identical, or Pyramid can't make sense out of what it would mean to have both statements active at the same time, it will complain loudly at startup time. It's not dumb though: it will automatically resolve conflicting configuration statements on its own if you -use the configuration ``include`` system: "more local" statements are -preferred over "less local" ones. This allows you to intelligently factor -large systems into smaller ones. +use the configuration :meth:`~pyramid.config.Configurator.include` system: +"more local" statements are preferred over "less local" ones. This allows +you to intelligently factor large systems into smaller ones. Example: :ref:`conflict_detection`. Configuration extensibility ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Unlike other systems, Pyramid provides a structured ``include`` mechanism -that allows you compose applications from multiple Python packages. All the -configuration statements that can be performed in your "main" Pyramid -application can also be performed by included packages (including the -addition of views, routes, subscribers, and even authentication and -authorization policies). You can even extend or override an existing -application by including another application's configuration in your own, and -overriding or adding new views and routes to it. This has the potential to -allow you to compose a big application out of many other smaller ones. For -example, if you want to reuse an existing application that already has a -bunch of routes, you can just use the ``include`` statement with a -``route_prefix``; the new application will live within your application at a -URL prefix. It's not a big deal, and requires little up-front engineering -effort. +Unlike other systems, Pyramid provides a structured "include" mechanism (see +:meth:`~pyramid.config.Configurator.include`) that allows you compose +applications from multiple Python packages. All the configuration statements +that can be performed in your "main" Pyramid application can also be +performed by included packages (including the addition of views, routes, +subscribers, and even authentication and authorization policies). You can +even extend or override an existing application by including another +application's configuration in your own, and overriding or adding new views +and routes to it. This has the potential to allow you to compose a big +application out of many other smaller ones. For example, if you want to +reuse an existing application that already has a bunch of routes, you can +just use the ``include`` statement with a ``route_prefix``; the new +application will live within your application at a URL prefix. It's not a +big deal, and requires little up-front engineering effort. Example: :ref:`building_an_extensible_app`. @@ -468,7 +469,7 @@ Traversal :term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to create a tree of resources, each of which can be addressed by one or more URLs. Each of those resources can have one or more *views* associated with -it. Iif your data isn't naturally treelike (or you're unwilling to create a +it. If your data isn't naturally treelike (or you're unwilling to create a treelike representation of your data), you aren't going to find traversal very useful. However, traversal is absolutely fantastic for sites that need to be arbitrarily extensible: it's a lot easier to add a node to a tree than @@ -495,7 +496,7 @@ statement, and it will take care of the rest:: Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to responses generated when this view is invoked. -See the :meth:`pyramid.config.Configurator.add_view` statement's +See the :meth:`~pyramid.config.Configurator.add_view` method's ``http_cache`` documentation for more information. Tweens @@ -550,7 +551,8 @@ demonstrations of common integration scenarios, too specific to add to the official narrative docs. In any case, the Pyramid documentation is comprehensive. -Example: The rest of this documentation. +Example: The rest of this documentation and the cookbook at +https://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . .. index:: single: Pylons Project -- cgit v1.2.3 From 368667432ded483434cabdf6bb46809bee73f05f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 18:31:42 -0400 Subject: add add_directive example --- docs/narr/introduction.rst | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d23a1f22f..ab76408af 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -434,6 +434,59 @@ just use the ``include`` statement with a ``route_prefix``; the new application will live within your application at a URL prefix. It's not a big deal, and requires little up-front engineering effort. +Does Pyramid's configurator allow you to do something, but you just want it a +little less verbose? Or you'd like to offer up some handy configuration +feature to other Pyramid users without requiring that we change Pyramid? You +can extend Pyramid's :term:`Configurator` with your own directives. For +example, let's say you find yourself doing this a lot: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + config = Configurator() + config.add_route('xhr_route', '/xhr/{id}') + config.add_view('my.package.GET_view', route_name='xhr_route', + xhr=True, permission='view', request_method='GET') + config.add_view('my.package.POST_view', route_name='xhr_route', + xhr=True, permission='view', request_method='POST') + config.add_view('my.package.HEAD_view', route_name='xhr_route', + xhr=True, permission='view', request_method='HEAD') + +Pretty tedious right? You can add a directive to the Pyramid configurator to +automate some of the tedium away: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def add_protected_xhr_views(config, module): + module = config.maybe_dotted(module) + for method in ('GET', 'POST', 'HEAD'): + view = getattr(module, 'xhr_%s_view' % method, None) + if view is not None: + config.add_view(view, route_name='xhr_route', xhr=True, + permission='view', request_method=method) + + config = Configurator() + config.add_directive('add_protected_xhr_views', add_protected_xhr_views) + +Once that's done, you can call the directive you've just added as a method of +the Configurator object: + +.. code-block:: python + :linenos: + + config.add_route('xhr_route', '/xhr/{id}') + config.add_protected_xhr_views('my.package') + +You can share your configuration code with others this way too by packaging +it up and calling :meth:`~pyramid.config.Configurator.add_directive` from +within a function called when another user uses the +:meth:`~pyramid.config.Configurator.include` method against your code. + Example: :ref:`building_an_extensible_app`. Flexible authentication and authorization -- cgit v1.2.3 From 6e5ab83429c3a4be37d71fe527b247f1270251a2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 18:34:28 -0400 Subject: add references --- docs/narr/introduction.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index ab76408af..1d5cc3711 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -487,7 +487,8 @@ it up and calling :meth:`~pyramid.config.Configurator.add_directive` from within a function called when another user uses the :meth:`~pyramid.config.Configurator.include` method against your code. -Example: :ref:`building_an_extensible_app`. +Examples: :ref:`building_an_extensible_app`, :ref:`including_configuration` +and :ref:`add_directive`. Flexible authentication and authorization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 85ac6b046b89a292e6bd383500fcb04ce6184058 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 19:18:51 -0400 Subject: add code examples --- docs/narr/introduction.rst | 132 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 1d5cc3711..a620e9505 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -224,8 +224,8 @@ they can be used for the same purposes. Example: :ref:`view_config_placement`. -Views can return dictionaries -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Rendered views can return dictionaries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a @@ -236,6 +236,28 @@ assertion instead that the view returns "the right stuff" in the dictionary it returns. You can write "real" unit tests instead of functionally testing all of your views. +For example, instead of: + +.. code-block:: python + :linenos: + + from pyramid.renderers import render_to_response + + def myview(request): + return render_to_response('myapp:templates/mytemplate.pt', {'a':1}, + request=request) + +You can do this: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + + @view_config(renderer='myapp:templates/mytemplate.pt') + def myview(request): + return {'a':1} + Example: :ref:`renderers_chapter`. Event system @@ -354,6 +376,112 @@ Found" page; in the latter case you might show a login form. Example: :ref:`exception_views`. +View Response Adapters +---------------------- + +A lot is made of the aesthetics of what *kind* of objects you're allowed to +return from view callables in various frameworks. Some frameworks allow +you return strings or tuples from view callables, and they make much of it. +When frameworks allow for this, code looks slightly prettier, because fewer +imports need to be done, and there is less code. For example, compare this: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + +To this: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + def aview(request): + return Response("Hello world!") + +The former is "prettier", right? + +Out of the box, if you define the former view callable (the one that simply +returns a string) in Pyramid, when it is executed, Pyramid will raise an +exception. This is because "explicit is better than implicit", in most +cases, and by default, Pyramid wants you to return a :term:`Response` object +from a view callable. This is because there's usually a heck of a lot more +to a response object than just its body. But if you're the kind of person +who values such aesthetics, we have an easy way to allow for this sort of +thing: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + from pyramid.response import Response + + def string_response_adapter(s): + response = Response(s) + response.content_type = 'text/html' + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + +Do that once in your Pyramid application at startup. Now you can return +strings from any of your view callables, e.g.: + +.. code-block:: python + :linenos: + + def helloview(request): + return "Hello world!" + + def goodbyeview(request): + return "Goodbye world!" + +Oh noes! What if you want to indicate a custom content type? And a custom +status code? No fear: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def tuple_response_adapter(val): + status_int, content_type, body = val + response = Response(body) + response.content_type = content_type + response.status_int = status_int + return response + + def string_response_adapter(body): + response = Response(body) + response.content_type = 'text/html' + response.status_int = 200 + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + config.add_response_adapter(tuple_response_adapter, tuple) + +Once this is done, both of these view callables will work: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + + def anotherview(request): + return (403, 'text/plain', "Forbidden") + +Pyramid defaults to explicit behavior, because it's the most generally +useful, but provide hooks that allow you to adapt the framework to localized +aesthetic desires. + +See also :ref:`using_iresponse`. + Asset specifications ~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 970b888021e81228f38cc2d4099dfe4ca350eba9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 7 Sep 2011 19:30:35 -0400 Subject: add global response section --- docs/narr/introduction.rst | 240 +++++++++++++++++++++++++-------------------- 1 file changed, 132 insertions(+), 108 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a620e9505..df1f3f954 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -260,26 +260,6 @@ You can do this: Example: :ref:`renderers_chapter`. -Event system -~~~~~~~~~~~~ - -Pyramid emits *events* during its request processing lifecycle. You can -subscribe any number of listeners to these events. For example, to be -notified of a new request, you can subscribe to the ``NewRequest`` event. To -be notified that a template is about to be rendered, you can subscribe to the -``BeforeRender`` event, and so forth. Using an event publishing system as a -framework notification feature instead of hardcoded hook points tends to make -systems based on that framework less brittle. - -You can also use Pyramid's event system to send your *own* events. For -example, if you'd like to create a system that is itself a framework, and may -want to notify subscribers that a document has just been indexed, you can -create your own event type (``DocumentIndexed`` perhaps) and send the event -via Pyramid. Users of this framework can then subscribe to your event like -they'd subscribe to the events that are normally sent by Pyramid itself. - -Example: :ref:`events_chapter` and :ref:`event_types`. - Extensible templating ~~~~~~~~~~~~~~~~~~~~~ @@ -292,98 +272,22 @@ favorite templating system. You'll then be able to use that templating system from within Pyramid just as you'd use one of the "built-in" templating systems. -Example: :ref:`templates_used_directly`. - -Speed -~~~~~ - -The Pyramid core is, as far as we can tell, at least marginally faster than -any other existing Python web framework. It has been engineered from the -ground up for speed. It only does as much work as absolutely necessary when -you ask it to get a job done. Extraneous function calls and suboptimal -algorithms in its core codepaths are avoided. It is feasible to get, for -example, between 3500 and 4000 requests per second from a simple Pyramid view -on commodity dual-core laptop hardware and an appropriate WSGI server -(mod_wsgi or gunicorn). In any case, performance statstics are largely -useless without requirements and goals, but if you need speed, Pyramid will -almost certainly never be your application's bottleneck; at least no more -than Python will be a bottleneck. - -Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ - -Sessions -~~~~~~~~ - -Pyramid has built-in HTTP sessioning. This allows you to associate data with -otherwise anonymous users between requests. Lots of systems do this. But -Pyramid also allows you to plug in your own sessioning system by creating -some code that adheres to a documented interface. Currently there is a -binding package for the third-part Beaker sessioning system that does exactly -this. But if you have a specialized need (perhaps you want to store your -session data in MongoDB), you can. You can even switch between -implementations without changing your application code. - -Example: :ref:`sessions_chapter`. - -No singletons -~~~~~~~~~~~~~ - -Pyramid is written in such a way that it has exactly zero "singleton" data -structures. Or, put another way, Pyramid constructs no "mutable globals". -Or put even a different way, an import of a Pyramid application needn't have -any "import time side effects". This is esoteric-sounding, but if you've -ever tried to cope with parameterizing a Django "settings.py" file for -multiple installations of the same application, or if you've ever needed to -monkey-patch some framework fixture so that it behaves properly for your use -case, or if you've ever wanted to deploy your system using an asynchronous -server, you'll end up appreciating this feature. It just won't be a problem. -You can even run multiple copies of a similar but not identically configured -Pyramid application within the same Python process. This is good for shared -hosting environments, where RAM is at a premium. - -View Predicates and Many Views Per Route -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Unlike many other systems, Pyramid allows you to associate more than one view -per route. For example, you can create a route with the pattern ``/items`` -and when the route is matched, you can shuffle off the request to one view if -the request method is GET, another view if the request method is POST, etc. -A system known as "view predicates" allows for this. Request method matching -is the very most basic thing you can do with a view predicate. You can also -associate views with other request parameters such as the elements in the -query string, the Accept header, whether the request is an XHR request or -not, and lots of other things. This feature allows you to keep your -individual views "clean"; they won't need much conditional logic, so they'll -be easier to test. - -Example: :ref:`view_configuration_parameters`. - -Exception views -~~~~~~~~~~~~~~~ +Pyramid does not make you use a single templating system exclusively. You +can use multiple templating systems, even in the same project. -Exceptions happen. Rather than deal with exceptions that might present -themselves to a user in production in an ad-hoc way, Pyramid allows you to -register an :term:`exception view`. Exception views are like regular Pyramid -views, but they're only invoked when an exception "bubbles up" to Pyramid -itself. For example, you might register an exception view for the -:exc:`Exception` exception, which will catch *all* exceptions, and present a -pretty "well, this is embarrassing" page. Or you might choose to register an -exception view for only specific kinds of application-specific exceptions, -such as an exception that happens when a file is not found, or an exception -that happens when action cannot be performed because the user doesn't have -permission to do something. In the former case, you can show a pretty "Not -Found" page; in the latter case you might show a login form. - -Example: :ref:`exception_views`. +Example: :ref:`templates_used_directly`. View Response Adapters ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ -A lot is made of the aesthetics of what *kind* of objects you're allowed to -return from view callables in various frameworks. Some frameworks allow -you return strings or tuples from view callables, and they make much of it. -When frameworks allow for this, code looks slightly prettier, because fewer -imports need to be done, and there is less code. For example, compare this: +A lot is made of the aesthetics of what *kinds* of objects you're allowed to +return from view callables in various frameworks. In a previous section in +this document we showed you that, if you use a :term:`renderer`, you can +usually return a dictionary from a view callable instead of a full-on +:term:`Response` object. But some frameworks allow you return strings or +tuples from view callables, and they make much of it. When frameworks allow +for this, code looks slightly prettier, because fewer imports need to be +done, and there is less code. For example, compare this: .. code-block:: python :linenos: @@ -482,6 +386,126 @@ aesthetic desires. See also :ref:`using_iresponse`. +"Global" Response Object +~~~~~~~~~~~~~~~~~~~~~~~~ + +"Constructing these response objects in my view callables is such a chore! +And I'm way too lazy to register a response adapter, as per the prior +section," you say. Fine. Be that way: + +.. code-block:: python + :linenos: + + def aview(request): + response = request.response + response.body = 'Hello world!' + response.content_type = 'text/plain' + return response + +See also :ref:`request_response_attr`. + +Event system +~~~~~~~~~~~~ + +Pyramid emits *events* during its request processing lifecycle. You can +subscribe any number of listeners to these events. For example, to be +notified of a new request, you can subscribe to the ``NewRequest`` event. To +be notified that a template is about to be rendered, you can subscribe to the +``BeforeRender`` event, and so forth. Using an event publishing system as a +framework notification feature instead of hardcoded hook points tends to make +systems based on that framework less brittle. + +You can also use Pyramid's event system to send your *own* events. For +example, if you'd like to create a system that is itself a framework, and may +want to notify subscribers that a document has just been indexed, you can +create your own event type (``DocumentIndexed`` perhaps) and send the event +via Pyramid. Users of this framework can then subscribe to your event like +they'd subscribe to the events that are normally sent by Pyramid itself. + +Example: :ref:`events_chapter` and :ref:`event_types`. + +Speed +~~~~~ + +The Pyramid core is, as far as we can tell, at least marginally faster than +any other existing Python web framework. It has been engineered from the +ground up for speed. It only does as much work as absolutely necessary when +you ask it to get a job done. Extraneous function calls and suboptimal +algorithms in its core codepaths are avoided. It is feasible to get, for +example, between 3500 and 4000 requests per second from a simple Pyramid view +on commodity dual-core laptop hardware and an appropriate WSGI server +(mod_wsgi or gunicorn). In any case, performance statstics are largely +useless without requirements and goals, but if you need speed, Pyramid will +almost certainly never be your application's bottleneck; at least no more +than Python will be a bottleneck. + +Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ + +Sessions +~~~~~~~~ + +Pyramid has built-in HTTP sessioning. This allows you to associate data with +otherwise anonymous users between requests. Lots of systems do this. But +Pyramid also allows you to plug in your own sessioning system by creating +some code that adheres to a documented interface. Currently there is a +binding package for the third-part Beaker sessioning system that does exactly +this. But if you have a specialized need (perhaps you want to store your +session data in MongoDB), you can. You can even switch between +implementations without changing your application code. + +Example: :ref:`sessions_chapter`. + +No singletons +~~~~~~~~~~~~~ + +Pyramid is written in such a way that it has exactly zero "singleton" data +structures. Or, put another way, Pyramid constructs no "mutable globals". +Or put even a different way, an import of a Pyramid application needn't have +any "import time side effects". This is esoteric-sounding, but if you've +ever tried to cope with parameterizing a Django "settings.py" file for +multiple installations of the same application, or if you've ever needed to +monkey-patch some framework fixture so that it behaves properly for your use +case, or if you've ever wanted to deploy your system using an asynchronous +server, you'll end up appreciating this feature. It just won't be a problem. +You can even run multiple copies of a similar but not identically configured +Pyramid application within the same Python process. This is good for shared +hosting environments, where RAM is at a premium. + +View Predicates and Many Views Per Route +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unlike many other systems, Pyramid allows you to associate more than one view +per route. For example, you can create a route with the pattern ``/items`` +and when the route is matched, you can shuffle off the request to one view if +the request method is GET, another view if the request method is POST, etc. +A system known as "view predicates" allows for this. Request method matching +is the very most basic thing you can do with a view predicate. You can also +associate views with other request parameters such as the elements in the +query string, the Accept header, whether the request is an XHR request or +not, and lots of other things. This feature allows you to keep your +individual views "clean"; they won't need much conditional logic, so they'll +be easier to test. + +Example: :ref:`view_configuration_parameters`. + +Exception views +~~~~~~~~~~~~~~~ + +Exceptions happen. Rather than deal with exceptions that might present +themselves to a user in production in an ad-hoc way, Pyramid allows you to +register an :term:`exception view`. Exception views are like regular Pyramid +views, but they're only invoked when an exception "bubbles up" to Pyramid +itself. For example, you might register an exception view for the +:exc:`Exception` exception, which will catch *all* exceptions, and present a +pretty "well, this is embarrassing" page. Or you might choose to register an +exception view for only specific kinds of application-specific exceptions, +such as an exception that happens when a file is not found, or an exception +that happens when action cannot be performed because the user doesn't have +permission to do something. In the former case, you can show a pretty "Not +Found" page; in the latter case you might show a login form. + +Example: :ref:`exception_views`. + Asset specifications ~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 2386bb2b774ee745f7923a3edec734332b38658a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 03:48:26 -0400 Subject: require, not construct --- docs/narr/introduction.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index df1f3f954..3c3c88591 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -458,12 +458,13 @@ Example: :ref:`sessions_chapter`. No singletons ~~~~~~~~~~~~~ -Pyramid is written in such a way that it has exactly zero "singleton" data -structures. Or, put another way, Pyramid constructs no "mutable globals". -Or put even a different way, an import of a Pyramid application needn't have -any "import time side effects". This is esoteric-sounding, but if you've -ever tried to cope with parameterizing a Django "settings.py" file for -multiple installations of the same application, or if you've ever needed to +Pyramid is written in such a way that it requires your application to have +exactly zero "singleton" data structures. Or, put another way, Pyramid +doesn't requires you to construct any "mutable globals". Or put even a +different way, an import of a Pyramid application needn't have any "import +time side effects". This is esoteric-sounding, but if you've ever tried to +cope with parameterizing a Django "settings.py" file for multiple +installations of the same application, or if you've ever needed to monkey-patch some framework fixture so that it behaves properly for your use case, or if you've ever wanted to deploy your system using an asynchronous server, you'll end up appreciating this feature. It just won't be a problem. -- cgit v1.2.3 From 00128a1bc824c7d79ce5595bf233669a00b57f36 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 03:56:50 -0400 Subject: wording --- docs/narr/introduction.rst | 58 +++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 24 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 3c3c88591..498514987 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -515,11 +515,11 @@ a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these specifications is omnipresent in Pyramid. You can refer to a template using an asset specification, a translation directory, and other package-bound static resources using one. This makes a system built on Pyramid extensible, -because you don't have to rely on globals ("the static directory") or lookup -schemes ("the ordered set of template directories") to address your files. -You can move files around as necessary, and include other packages that may -not share your system's templates or static files without encountering -conflicts. +because you don't have to rely on globals ("*the* static directory") or +lookup schemes ("*the* ordered set of template directories") to address your +files. You can move files around as necessary, and include other packages +that may not share your system's templates or static files without +encountering conflicts. Because asset specifications are used heavily in Pyramid, we've also provided a way to allow users to override assets. Say you love a system that someone @@ -539,15 +539,22 @@ transaction management system, you cease being responsible for committing your data anymore. Instead, Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good thing? Having a centralized place for transaction management is a great -thing. If you instead add a ``session.commit`` call in your application -logic itself, and your code goes on to do other important things after that -commit, and error happens in the later code, you can easily wind up in a bad -place. Some data will have been written to the database that probably should -not have. Having a centralized commit point saves you from needing to think -about this. Also, Pyramid's transaction management system allows you to -synchronize commits between multiple databases, and allows you to do things -like conditionally send email if a transaction commits, but otherwise keep -quiet. +thing. If, instead of managing your transactions in a centralized place, you +sprikle ``session.commit`` calls in your application logic itself, you can +wind up in a bad place. Wherever you manually commit data to your database, +it's likely that some of your other code is going to run *after* your commit. +If that code goes on to do other important things after that commit, and +error happens in the later code, you can easily wind up with inconsistent +data if you're not extremely careful. Some data will have been written to +the database that probably should not have. Having a centralized commit +point saves you from needing to think about this; it's great for lazy people +who also care about data integrity. Either the request completes +successfully, and all chages are committed, or it does not, and all changes +are aborted. + +Also, Pyramid's transaction management system allows you to synchronize +commits between multiple databases, and allows you to do things like +conditionally send email if a transaction commits, but otherwise keep quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements anywhere in application code). @@ -576,16 +583,16 @@ Unlike other systems, Pyramid provides a structured "include" mechanism (see :meth:`~pyramid.config.Configurator.include`) that allows you compose applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be -performed by included packages (including the addition of views, routes, -subscribers, and even authentication and authorization policies). You can -even extend or override an existing application by including another -application's configuration in your own, and overriding or adding new views -and routes to it. This has the potential to allow you to compose a big -application out of many other smaller ones. For example, if you want to -reuse an existing application that already has a bunch of routes, you can -just use the ``include`` statement with a ``route_prefix``; the new -application will live within your application at a URL prefix. It's not a -big deal, and requires little up-front engineering effort. +performed by included packages including the addition of views, routes, +subscribers, and even authentication and authorization policies. You can even +extend or override an existing application by including another application's +configuration in your own, and overriding or adding new views and routes to +it. This has the potential to allow you to compose a big application out of +many other smaller ones. For example, if you want to reuse an existing +application that already has a bunch of routes, you can just use the +``include`` statement with a ``route_prefix``; the new application will live +within your application at a URL prefix. It's not a big deal, and requires +little up-front engineering effort. Does Pyramid's configurator allow you to do something, but you just want it a little less verbose? Or you'd like to offer up some handy configuration @@ -635,6 +642,9 @@ the Configurator object: config.add_route('xhr_route', '/xhr/{id}') config.add_protected_xhr_views('my.package') +Your previously multiple repetitive configuration lines have now morphed into +one line. + You can share your configuration code with others this way too by packaging it up and calling :meth:`~pyramid.config.Configurator.add_directive` from within a function called when another user uses the -- cgit v1.2.3 From ab7b2447c2733e9a5ec049bb567235bae0e631f6 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 05:01:43 -0400 Subject: wording/typo fixes --- docs/narr/introduction.rst | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 498514987..029aa1e07 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -206,7 +206,7 @@ routes for an application in the order they'll be evaluated for matching; ``paster pviews`` shows all configured views for any given URL. These are also WTF-crushers in some circumstances. -Example: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. +Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. Class-Based and Function-Based Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -512,14 +512,13 @@ Asset specifications Asset specifications are strings that contain both a Python package name and a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these -specifications is omnipresent in Pyramid. You can refer to a template using -an asset specification, a translation directory, and other package-bound -static resources using one. This makes a system built on Pyramid extensible, -because you don't have to rely on globals ("*the* static directory") or -lookup schemes ("*the* ordered set of template directories") to address your -files. You can move files around as necessary, and include other packages -that may not share your system's templates or static files without -encountering conflicts. +specifications is omnipresent in Pyramid. An asset specification can refer +to a template, a translation directory, or any other package-bound static +resource. This makes a system built on Pyramid extensible, because you don't +have to rely on globals ("*the* static directory") or lookup schemes ("*the* +ordered set of template directories") to address your files. You can move +files around as necessary, and include other packages that may not share your +system's templates or static files without encountering conflicts. Because asset specifications are used heavily in Pyramid, we've also provided a way to allow users to override assets. Say you love a system that someone @@ -528,7 +527,7 @@ to make it all better. No need to fork the application. Just override the asset specification for that template with your own inside a wrapper, and you're good to go. -Example: :ref:`asset_specifications`. +Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. Transaction management ~~~~~~~~~~~~~~~~~~~~~~ @@ -586,7 +585,7 @@ that can be performed in your "main" Pyramid application can also be performed by included packages including the addition of views, routes, subscribers, and even authentication and authorization policies. You can even extend or override an existing application by including another application's -configuration in your own, and overriding or adding new views and routes to +configuration in your own, overriding or adding new views and routes to it. This has the potential to allow you to compose a big application out of many other smaller ones. For example, if you want to reuse an existing application that already has a bunch of routes, you can just use the -- cgit v1.2.3 From fdae55901a72a0894274847da8811779cdfdd1cd Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 05:02:25 -0400 Subject: wording/typo fixes --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 029aa1e07..267234b6a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -737,8 +737,8 @@ greater than 95% decision/condition coverage as measured by the Jenkins tool on Python 2.5, Python 2.6, Python 2.7, Jython and PyPy after each commit to its GitHub repository. Official Pyramid add-ons are held to a similar testing standard. We still find bugs in Pyramid and its official -add-ons, but we've noticed we find a lot fewer of them than while working on -other projects that don't have a good testing regime. +add-ons, but we've noticed we find a lot more of them while working on other +projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ -- cgit v1.2.3 From e7085bb4fcbd1bec75dc13724b8e399879c69290 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 05:03:08 -0400 Subject: wording/typo fixes --- docs/narr/introduction.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 267234b6a..d404ef08c 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -285,9 +285,9 @@ return from view callables in various frameworks. In a previous section in this document we showed you that, if you use a :term:`renderer`, you can usually return a dictionary from a view callable instead of a full-on :term:`Response` object. But some frameworks allow you return strings or -tuples from view callables, and they make much of it. When frameworks allow -for this, code looks slightly prettier, because fewer imports need to be -done, and there is less code. For example, compare this: +tuples from view callables. When frameworks allow for this, code looks +slightly prettier, because fewer imports need to be done, and there is less +code. For example, compare this: .. code-block:: python :linenos: -- cgit v1.2.3 From 5b0496ee16cc1c43344870eda41f48e3851667f4 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 8 Sep 2011 10:56:24 -0500 Subject: garden --- docs/narr/introduction.rst | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d404ef08c..49c6ce521 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -211,7 +211,7 @@ Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. Class-Based and Function-Based Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid has a structured, unified conception of a :term:`view callable`. +Pyramid has a structured, unified concept of a :term:`view callable`. View callables can be functions, methods of classes, or even instances. When you add a new view callable, you can choose to make it a function or a method of a class; in either case, Pyramid treats it largely the same way. You can @@ -448,7 +448,7 @@ Pyramid has built-in HTTP sessioning. This allows you to associate data with otherwise anonymous users between requests. Lots of systems do this. But Pyramid also allows you to plug in your own sessioning system by creating some code that adheres to a documented interface. Currently there is a -binding package for the third-part Beaker sessioning system that does exactly +binding package for the third-party Beaker sessioning system that does exactly this. But if you have a specialized need (perhaps you want to store your session data in MongoDB), you can. You can even switch between implementations without changing your application code. @@ -460,8 +460,8 @@ No singletons Pyramid is written in such a way that it requires your application to have exactly zero "singleton" data structures. Or, put another way, Pyramid -doesn't requires you to construct any "mutable globals". Or put even a -different way, an import of a Pyramid application needn't have any "import +doesn't require you to construct any "mutable globals". Or put even a +different way, an import of a Pyramid application needn't have any "import- time side effects". This is esoteric-sounding, but if you've ever tried to cope with parameterizing a Django "settings.py" file for multiple installations of the same application, or if you've ever needed to @@ -501,7 +501,7 @@ itself. For example, you might register an exception view for the pretty "well, this is embarrassing" page. Or you might choose to register an exception view for only specific kinds of application-specific exceptions, such as an exception that happens when a file is not found, or an exception -that happens when action cannot be performed because the user doesn't have +that happens when an action cannot be performed because the user doesn't have permission to do something. In the former case, you can show a pretty "Not Found" page; in the latter case you might show a login form. @@ -539,10 +539,10 @@ your data anymore. Instead, Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good thing? Having a centralized place for transaction management is a great thing. If, instead of managing your transactions in a centralized place, you -sprikle ``session.commit`` calls in your application logic itself, you can +sprinkle ``session.commit`` calls in your application logic itself, you can wind up in a bad place. Wherever you manually commit data to your database, it's likely that some of your other code is going to run *after* your commit. -If that code goes on to do other important things after that commit, and +If that code goes on to do other important things after that commit, and an error happens in the later code, you can easily wind up with inconsistent data if you're not extremely careful. Some data will have been written to the database that probably should not have. Having a centralized commit @@ -561,7 +561,7 @@ anywhere in application code). Configuration conflict detection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a system is small, it's reasonably easy to keep it in all in your head. +When a system is small, it's reasonably easy to keep it all in your head. But when systems grow large, you may have hundreds or thousands of configuration statements which add a view, add a route, and so forth. Pyramid's configuration system keeps track of your configuration statements, @@ -641,8 +641,7 @@ the Configurator object: config.add_route('xhr_route', '/xhr/{id}') config.add_protected_xhr_views('my.package') -Your previously multiple repetitive configuration lines have now morphed into -one line. +Your previously repetitive configuration lines have now morphed into one line. You can share your configuration code with others this way too by packaging it up and calling :meth:`~pyramid.config.Configurator.add_directive` from -- cgit v1.2.3 From fed66efe5347858eaf78e0fcb75c77eabf01efab Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Sep 2011 12:38:52 -0700 Subject: Replaced "the the" with "the" under Minimalism --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 49c6ce521..bba3594fe 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -40,7 +40,7 @@ Simplicity understand to a minimum. Minimalism - :app:`Pyramid` tries to solve only the the fundamental problems of creating + :app:`Pyramid` tries to solve only the fundamental problems of creating a web application: the mapping of URLs to code, templating, security and serving static assets. We consider these to be the core activities that are common to nearly all web applications. -- cgit v1.2.3 From 41cb3afe29320abb4e20a951863c0ae4a64eba67 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 8 Sep 2011 17:59:53 -0400 Subject: typo --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index bba3594fe..25511d12a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -434,7 +434,7 @@ you ask it to get a job done. Extraneous function calls and suboptimal algorithms in its core codepaths are avoided. It is feasible to get, for example, between 3500 and 4000 requests per second from a simple Pyramid view on commodity dual-core laptop hardware and an appropriate WSGI server -(mod_wsgi or gunicorn). In any case, performance statstics are largely +(mod_wsgi or gunicorn). In any case, performance statistics are largely useless without requirements and goals, but if you need speed, Pyramid will almost certainly never be your application's bottleneck; at least no more than Python will be a bottleneck. -- cgit v1.2.3 From d10aeb228f58be6beff35266fea0bc7be006aab9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Sep 2011 03:37:11 -0400 Subject: feedback from david cramer --- docs/narr/introduction.rst | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 25511d12a..b691d5a7c 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -258,6 +258,14 @@ You can do this: def myview(request): return {'a':1} +When this view callable is called by Pyramid, the ``{'a':1}`` dictionary will +be rendered to a response on your behalf. The string passed as ``renderer=`` +above is an :term:`asset specification`. It is in the form +``packagename:directoryname/filename.ext``. In this case, it names the +``mytemplate.pt`` file in the ``templates`` directory within the ``myapp`` +Python package. Asset specifications are omnipresent in Pyramid: see +:ref:`intro_asset_specs` for more information. + Example: :ref:`renderers_chapter`. Extensible templating @@ -507,6 +515,8 @@ Found" page; in the latter case you might show a login form. Example: :ref:`exception_views`. +.. _intro_asset_specs: + Asset specifications ~~~~~~~~~~~~~~~~~~~~ @@ -597,7 +607,10 @@ Does Pyramid's configurator allow you to do something, but you just want it a little less verbose? Or you'd like to offer up some handy configuration feature to other Pyramid users without requiring that we change Pyramid? You can extend Pyramid's :term:`Configurator` with your own directives. For -example, let's say you find yourself doing this a lot: +example, let's say you find yourself calling +:meth:`pyramid.config.Configurator.add_view` repetitvely. Usually you can +take the boring away by using existing shortcuts, but let's say that this is +a case such a way that no existing shortcut works to take the boring away: .. code-block:: python :linenos: -- cgit v1.2.3 From a7238e374de68557aeed47c416cb94538615dcf8 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 9 Sep 2011 02:42:16 -0500 Subject: garden --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b691d5a7c..b24c95c67 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -608,7 +608,7 @@ little less verbose? Or you'd like to offer up some handy configuration feature to other Pyramid users without requiring that we change Pyramid? You can extend Pyramid's :term:`Configurator` with your own directives. For example, let's say you find yourself calling -:meth:`pyramid.config.Configurator.add_view` repetitvely. Usually you can +:meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can take the boring away by using existing shortcuts, but let's say that this is a case such a way that no existing shortcut works to take the boring away: -- cgit v1.2.3 From 214125fa966026f979981312356832cd0a52983a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Sep 2011 04:04:27 -0400 Subject: garden --- docs/narr/introduction.rst | 168 ++++++++++++++++++++++++++++++--------------- 1 file changed, 114 insertions(+), 54 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b24c95c67..62374ff54 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -208,6 +208,17 @@ also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. +Add-ons +~~~~~~~~ + +Pyramid has an extensive set of add-ons held to the same quality standards as +the Pyramid core itself. Add-ons are packages which provide functionality +that the Pyramid core doesn't. Add-on packages already exist which let you +easily send email, let you use the Jinja2 templating system, let you use +XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. + +Examples: https://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation + Class-Based and Function-Based Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -222,7 +233,39 @@ initialization code as necessary. All kinds of views are easy to understand and use and operate similarly. There is no phony distinction between them; they can be used for the same purposes. -Example: :ref:`view_config_placement`. +Here's a view callable defined as a function: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + @view_config(route_name='aview') + def aview(request): + return Response('one') + +Here's a few views defined as methods of a class instead: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + from pyramid.view import view_config + + class AView(object): + def __init__(self, request): + self.request = request + + @view_config(route_name='view_one') + def view_one(request): + return Response('one') + + @view_config(route_name='view_two') + def view_two(request): + return Response('two') + +See also :ref:`view_config_placement`. Rendered views can return dictionaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -603,66 +646,20 @@ application that already has a bunch of routes, you can just use the within your application at a URL prefix. It's not a big deal, and requires little up-front engineering effort. -Does Pyramid's configurator allow you to do something, but you just want it a -little less verbose? Or you'd like to offer up some handy configuration -feature to other Pyramid users without requiring that we change Pyramid? You -can extend Pyramid's :term:`Configurator` with your own directives. For -example, let's say you find yourself calling -:meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can -take the boring away by using existing shortcuts, but let's say that this is -a case such a way that no existing shortcut works to take the boring away: +For example: .. code-block:: python :linenos: from pyramid.config import Configurator - config = Configurator() - config.add_route('xhr_route', '/xhr/{id}') - config.add_view('my.package.GET_view', route_name='xhr_route', - xhr=True, permission='view', request_method='GET') - config.add_view('my.package.POST_view', route_name='xhr_route', - xhr=True, permission='view', request_method='POST') - config.add_view('my.package.HEAD_view', route_name='xhr_route', - xhr=True, permission='view', request_method='HEAD') - -Pretty tedious right? You can add a directive to the Pyramid configurator to -automate some of the tedium away: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - - def add_protected_xhr_views(config, module): - module = config.maybe_dotted(module) - for method in ('GET', 'POST', 'HEAD'): - view = getattr(module, 'xhr_%s_view' % method, None) - if view is not None: - config.add_view(view, route_name='xhr_route', xhr=True, - permission='view', request_method=method) - - config = Configurator() - config.add_directive('add_protected_xhr_views', add_protected_xhr_views) - -Once that's done, you can call the directive you've just added as a method of -the Configurator object: - -.. code-block:: python - :linenos: - - config.add_route('xhr_route', '/xhr/{id}') - config.add_protected_xhr_views('my.package') - -Your previously repetitive configuration lines have now morphed into one line. - -You can share your configuration code with others this way too by packaging -it up and calling :meth:`~pyramid.config.Configurator.add_directive` from -within a function called when another user uses the -:meth:`~pyramid.config.Configurator.include` method against your code. + if __name__ == '__main__': + config = Configurator() + config.include('pyramid_jinja2') + config.include('pyramid_exclog') + config.include('some.other.guys.package', route_prefix='/someotherguy') -Examples: :ref:`building_an_extensible_app`, :ref:`including_configuration` -and :ref:`add_directive`. +See also :ref:`including_configuration` and :ref:`building_an_extensible_app` Flexible authentication and authorization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -739,6 +736,69 @@ Pyramid itself, meaning you have access to templates and other renderers, a Example: :ref:`registering_tweens`. +Automating repetitive configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Does Pyramid's configurator allow you to do something, but you're a little +adventurous and just want it a little less verbose? Or you'd like to offer +up some handy configuration feature to other Pyramid users without requiring +that we change Pyramid? You can extend Pyramid's :term:`Configurator` with +your own directives. For example, let's say you find yourself calling +:meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can +take the boring away by using existing shortcuts, but let's say that this is +a case such a way that no existing shortcut works to take the boring away: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + config = Configurator() + config.add_route('xhr_route', '/xhr/{id}') + config.add_view('my.package.GET_view', route_name='xhr_route', + xhr=True, permission='view', request_method='GET') + config.add_view('my.package.POST_view', route_name='xhr_route', + xhr=True, permission='view', request_method='POST') + config.add_view('my.package.HEAD_view', route_name='xhr_route', + xhr=True, permission='view', request_method='HEAD') + +Pretty tedious right? You can add a directive to the Pyramid configurator to +automate some of the tedium away: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def add_protected_xhr_views(config, module): + module = config.maybe_dotted(module) + for method in ('GET', 'POST', 'HEAD'): + view = getattr(module, 'xhr_%s_view' % method, None) + if view is not None: + config.add_view(view, route_name='xhr_route', xhr=True, + permission='view', request_method=method) + + config = Configurator() + config.add_directive('add_protected_xhr_views', add_protected_xhr_views) + +Once that's done, you can call the directive you've just added as a method of +the Configurator object: + +.. code-block:: python + :linenos: + + config.add_route('xhr_route', '/xhr/{id}') + config.add_protected_xhr_views('my.package') + +Your previously repetitive configuration lines have now morphed into one line. + +You can share your configuration code with others this way too by packaging +it up and calling :meth:`~pyramid.config.Configurator.add_directive` from +within a function called when another user uses the +:meth:`~pyramid.config.Configurator.include` method against your code. + +See also :ref:`add_directive`. + Testing ~~~~~~~ -- cgit v1.2.3 From d3aae87e4e167ab8ff7a0c54fee4197d9a8b8763 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Sep 2011 04:13:31 -0400 Subject: garden --- docs/narr/introduction.rst | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 62374ff54..8a7c724a1 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -108,22 +108,24 @@ from those other frameworks. But Pyramid is the only one that has all of them in one place, documented appropriately, and useful a la carte without necessarily paying for the entire banquet. These are detailed below. -Single-File Applications +Single-file applications ~~~~~~~~~~~~~~~~~~~~~~~~ You can write a Pyramid application that lives entirely in one Python file, -not unlike existing Python microframeworks. This is beneficial for "one off" +not unlike existing Python microframeworks. This is beneficial for one-off prototyping, bug reproduction, and very small applications. These applications are easy to understand because all the information about the application lives in a single place, and you can deploy them without needing to understand much about Python distributions and packaging. Pyramid isn't really marketed as a microframework, but it allows you to do almost -everything that frameworks that are marketed as "micro" offer in very similar +everything that frameworks that are marketed as micro offer in very similar ways. -Example: :ref:`firstapp_chapter`. +.. literalinclude:: helloworld.py -Decorator-Based Configuration +See also :ref:`firstapp_chapter`. + +Decorator-based configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you like the idea of framework configuration statements living next to the @@ -153,7 +155,7 @@ with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. -URL Generation +URL generation ~~~~~~~~~~~~~~ Pyramid is capable of generating URLs for resources, routes, and static @@ -219,7 +221,7 @@ XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. Examples: https://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation -Class-Based and Function-Based Views +Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pyramid has a structured, unified concept of a :term:`view callable`. @@ -328,7 +330,7 @@ can use multiple templating systems, even in the same project. Example: :ref:`templates_used_directly`. -View Response Adapters +View response adapters ~~~~~~~~~~~~~~~~~~~~~~ A lot is made of the aesthetics of what *kinds* of objects you're allowed to @@ -437,7 +439,7 @@ aesthetic desires. See also :ref:`using_iresponse`. -"Global" Response Object +"Global" response object ~~~~~~~~~~~~~~~~~~~~~~~~ "Constructing these response objects in my view callables is such a chore! @@ -523,7 +525,7 @@ You can even run multiple copies of a similar but not identically configured Pyramid application within the same Python process. This is good for shared hosting environments, where RAM is at a premium. -View Predicates and Many Views Per Route +View predicates and many views per route ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike many other systems, Pyramid allows you to associate more than one view @@ -677,7 +679,7 @@ system. Example: :ref:`enabling_authorization_policy`. -Built-in Internationalization +Built-in internationalization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pyramid ships with internalization-related features in its core: @@ -708,7 +710,7 @@ as opposed to "Bob can edit documents"). Example: :ref:`much_ado_about_traversal_chapter`. -HTTP Caching +HTTP caching ~~~~~~~~~~~~ Pyramid provides an easy way to associate views with HTTP caching policies. -- cgit v1.2.3 From 82dcba5bf8d6d024f42ded1565d30c314b8e8b4b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 9 Sep 2011 04:20:46 -0400 Subject: reorder --- docs/narr/introduction.rst | 448 ++++++++++++++++++++++----------------------- 1 file changed, 224 insertions(+), 224 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8a7c724a1..8694556b2 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -269,6 +269,47 @@ Here's a few views defined as methods of a class instead: See also :ref:`view_config_placement`. +.. _intro_asset_specs: + +Asset specifications +~~~~~~~~~~~~~~~~~~~~ + +Asset specifications are strings that contain both a Python package name and +a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these +specifications is omnipresent in Pyramid. An asset specification can refer +to a template, a translation directory, or any other package-bound static +resource. This makes a system built on Pyramid extensible, because you don't +have to rely on globals ("*the* static directory") or lookup schemes ("*the* +ordered set of template directories") to address your files. You can move +files around as necessary, and include other packages that may not share your +system's templates or static files without encountering conflicts. + +Because asset specifications are used heavily in Pyramid, we've also provided +a way to allow users to override assets. Say you love a system that someone +else has created with Pyramid but you just need to change "that one template" +to make it all better. No need to fork the application. Just override the +asset specification for that template with your own inside a wrapper, and +you're good to go. + +Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. + +Extensible templating +~~~~~~~~~~~~~~~~~~~~~ + +Pyramid has a structured API that allows for pluggability of "renderers". +Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated +as renderers. Renderer bindings for all of these templating systems already +exist for use in Pyramid. But if you'd rather use another, it's not a big +deal. Just copy the code from an existing renderer package, and plug in your +favorite templating system. You'll then be able to use that templating +system from within Pyramid just as you'd use one of the "built-in" templating +systems. + +Pyramid does not make you use a single templating system exclusively. You +can use multiple templating systems, even in the same project. + +Example: :ref:`templates_used_directly`. + Rendered views can return dictionaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -313,150 +354,6 @@ Python package. Asset specifications are omnipresent in Pyramid: see Example: :ref:`renderers_chapter`. -Extensible templating -~~~~~~~~~~~~~~~~~~~~~ - -Pyramid has a structured API that allows for pluggability of "renderers". -Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated -as renderers. Renderer bindings for all of these templating systems already -exist for use in Pyramid. But if you'd rather use another, it's not a big -deal. Just copy the code from an existing renderer package, and plug in your -favorite templating system. You'll then be able to use that templating -system from within Pyramid just as you'd use one of the "built-in" templating -systems. - -Pyramid does not make you use a single templating system exclusively. You -can use multiple templating systems, even in the same project. - -Example: :ref:`templates_used_directly`. - -View response adapters -~~~~~~~~~~~~~~~~~~~~~~ - -A lot is made of the aesthetics of what *kinds* of objects you're allowed to -return from view callables in various frameworks. In a previous section in -this document we showed you that, if you use a :term:`renderer`, you can -usually return a dictionary from a view callable instead of a full-on -:term:`Response` object. But some frameworks allow you return strings or -tuples from view callables. When frameworks allow for this, code looks -slightly prettier, because fewer imports need to be done, and there is less -code. For example, compare this: - -.. code-block:: python - :linenos: - - def aview(request): - return "Hello world!" - -To this: - -.. code-block:: python - :linenos: - - from pyramid.response import Response - - def aview(request): - return Response("Hello world!") - -The former is "prettier", right? - -Out of the box, if you define the former view callable (the one that simply -returns a string) in Pyramid, when it is executed, Pyramid will raise an -exception. This is because "explicit is better than implicit", in most -cases, and by default, Pyramid wants you to return a :term:`Response` object -from a view callable. This is because there's usually a heck of a lot more -to a response object than just its body. But if you're the kind of person -who values such aesthetics, we have an easy way to allow for this sort of -thing: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - from pyramid.response import Response - - def string_response_adapter(s): - response = Response(s) - response.content_type = 'text/html' - return response - - if __name__ == '__main__': - config = Configurator() - config.add_response_adapter(string_response_adapter, basestring) - -Do that once in your Pyramid application at startup. Now you can return -strings from any of your view callables, e.g.: - -.. code-block:: python - :linenos: - - def helloview(request): - return "Hello world!" - - def goodbyeview(request): - return "Goodbye world!" - -Oh noes! What if you want to indicate a custom content type? And a custom -status code? No fear: - -.. code-block:: python - :linenos: - - from pyramid.config import Configurator - - def tuple_response_adapter(val): - status_int, content_type, body = val - response = Response(body) - response.content_type = content_type - response.status_int = status_int - return response - - def string_response_adapter(body): - response = Response(body) - response.content_type = 'text/html' - response.status_int = 200 - return response - - if __name__ == '__main__': - config = Configurator() - config.add_response_adapter(string_response_adapter, basestring) - config.add_response_adapter(tuple_response_adapter, tuple) - -Once this is done, both of these view callables will work: - -.. code-block:: python - :linenos: - - def aview(request): - return "Hello world!" - - def anotherview(request): - return (403, 'text/plain', "Forbidden") - -Pyramid defaults to explicit behavior, because it's the most generally -useful, but provide hooks that allow you to adapt the framework to localized -aesthetic desires. - -See also :ref:`using_iresponse`. - -"Global" response object -~~~~~~~~~~~~~~~~~~~~~~~~ - -"Constructing these response objects in my view callables is such a chore! -And I'm way too lazy to register a response adapter, as per the prior -section," you say. Fine. Be that way: - -.. code-block:: python - :linenos: - - def aview(request): - response = request.response - response.body = 'Hello world!' - response.content_type = 'text/plain' - return response - -See also :ref:`request_response_attr`. - Event system ~~~~~~~~~~~~ @@ -477,6 +374,47 @@ they'd subscribe to the events that are normally sent by Pyramid itself. Example: :ref:`events_chapter` and :ref:`event_types`. +Built-in internationalization +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pyramid ships with internalization-related features in its core: +localization, pluralization, and creating message catalogs from source files +and templates. Pyramid allows for a plurality of message catalog via the use +of translation domains: you can create a system that has its own translations +without conflict with other translations in other domains. + +Example: :ref:`i18n_chapter`. + +HTTP caching +~~~~~~~~~~~~ + +Pyramid provides an easy way to associate views with HTTP caching policies. +You can just tell Pyramid to configure your view with an ``http_cache`` +statement, and it will take care of the rest:: + + @view_config(http_cache=3600) # 60 minutes + def myview(request): .... + +Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to +responses generated when this view is invoked. + +See the :meth:`~pyramid.config.Configurator.add_view` method's +``http_cache`` documentation for more information. + +Sessions +~~~~~~~~ + +Pyramid has built-in HTTP sessioning. This allows you to associate data with +otherwise anonymous users between requests. Lots of systems do this. But +Pyramid also allows you to plug in your own sessioning system by creating +some code that adheres to a documented interface. Currently there is a +binding package for the third-party Beaker sessioning system that does exactly +this. But if you have a specialized need (perhaps you want to store your +session data in MongoDB), you can. You can even switch between +implementations without changing your application code. + +Example: :ref:`sessions_chapter`. + Speed ~~~~~ @@ -494,19 +432,23 @@ than Python will be a bottleneck. Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ -Sessions -~~~~~~~~ +Exception views +~~~~~~~~~~~~~~~ -Pyramid has built-in HTTP sessioning. This allows you to associate data with -otherwise anonymous users between requests. Lots of systems do this. But -Pyramid also allows you to plug in your own sessioning system by creating -some code that adheres to a documented interface. Currently there is a -binding package for the third-party Beaker sessioning system that does exactly -this. But if you have a specialized need (perhaps you want to store your -session data in MongoDB), you can. You can even switch between -implementations without changing your application code. +Exceptions happen. Rather than deal with exceptions that might present +themselves to a user in production in an ad-hoc way, Pyramid allows you to +register an :term:`exception view`. Exception views are like regular Pyramid +views, but they're only invoked when an exception "bubbles up" to Pyramid +itself. For example, you might register an exception view for the +:exc:`Exception` exception, which will catch *all* exceptions, and present a +pretty "well, this is embarrassing" page. Or you might choose to register an +exception view for only specific kinds of application-specific exceptions, +such as an exception that happens when a file is not found, or an exception +that happens when an action cannot be performed because the user doesn't have +permission to do something. In the former case, you can show a pretty "Not +Found" page; in the latter case you might show a login form. -Example: :ref:`sessions_chapter`. +Example: :ref:`exception_views`. No singletons ~~~~~~~~~~~~~ @@ -542,48 +484,6 @@ be easier to test. Example: :ref:`view_configuration_parameters`. -Exception views -~~~~~~~~~~~~~~~ - -Exceptions happen. Rather than deal with exceptions that might present -themselves to a user in production in an ad-hoc way, Pyramid allows you to -register an :term:`exception view`. Exception views are like regular Pyramid -views, but they're only invoked when an exception "bubbles up" to Pyramid -itself. For example, you might register an exception view for the -:exc:`Exception` exception, which will catch *all* exceptions, and present a -pretty "well, this is embarrassing" page. Or you might choose to register an -exception view for only specific kinds of application-specific exceptions, -such as an exception that happens when a file is not found, or an exception -that happens when an action cannot be performed because the user doesn't have -permission to do something. In the former case, you can show a pretty "Not -Found" page; in the latter case you might show a login form. - -Example: :ref:`exception_views`. - -.. _intro_asset_specs: - -Asset specifications -~~~~~~~~~~~~~~~~~~~~ - -Asset specifications are strings that contain both a Python package name and -a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these -specifications is omnipresent in Pyramid. An asset specification can refer -to a template, a translation directory, or any other package-bound static -resource. This makes a system built on Pyramid extensible, because you don't -have to rely on globals ("*the* static directory") or lookup schemes ("*the* -ordered set of template directories") to address your files. You can move -files around as necessary, and include other packages that may not share your -system's templates or static files without encountering conflicts. - -Because asset specifications are used heavily in Pyramid, we've also provided -a way to allow users to override assets. Say you love a system that someone -else has created with Pyramid but you just need to change "that one template" -to make it all better. No need to fork the application. Just override the -asset specification for that template with your own inside a wrapper, and -you're good to go. - -Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. - Transaction management ~~~~~~~~~~~~~~~~~~~~~~ @@ -679,17 +579,6 @@ system. Example: :ref:`enabling_authorization_policy`. -Built-in internationalization -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pyramid ships with internalization-related features in its core: -localization, pluralization, and creating message catalogs from source files -and templates. Pyramid allows for a plurality of message catalog via the use -of translation domains: you can create a system that has its own translations -without conflict with other translations in other domains. - -Example: :ref:`i18n_chapter`. - Traversal ~~~~~~~~~ @@ -710,22 +599,6 @@ as opposed to "Bob can edit documents"). Example: :ref:`much_ado_about_traversal_chapter`. -HTTP caching -~~~~~~~~~~~~ - -Pyramid provides an easy way to associate views with HTTP caching policies. -You can just tell Pyramid to configure your view with an ``http_cache`` -statement, and it will take care of the rest:: - - @view_config(http_cache=3600) # 60 minutes - def myview(request): .... - -Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to -responses generated when this view is invoked. - -See the :meth:`~pyramid.config.Configurator.add_view` method's -``http_cache`` documentation for more information. - Tweens ~~~~~~ @@ -738,6 +611,133 @@ Pyramid itself, meaning you have access to templates and other renderers, a Example: :ref:`registering_tweens`. +View response adapters +~~~~~~~~~~~~~~~~~~~~~~ + +A lot is made of the aesthetics of what *kinds* of objects you're allowed to +return from view callables in various frameworks. In a previous section in +this document we showed you that, if you use a :term:`renderer`, you can +usually return a dictionary from a view callable instead of a full-on +:term:`Response` object. But some frameworks allow you return strings or +tuples from view callables. When frameworks allow for this, code looks +slightly prettier, because fewer imports need to be done, and there is less +code. For example, compare this: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + +To this: + +.. code-block:: python + :linenos: + + from pyramid.response import Response + + def aview(request): + return Response("Hello world!") + +The former is "prettier", right? + +Out of the box, if you define the former view callable (the one that simply +returns a string) in Pyramid, when it is executed, Pyramid will raise an +exception. This is because "explicit is better than implicit", in most +cases, and by default, Pyramid wants you to return a :term:`Response` object +from a view callable. This is because there's usually a heck of a lot more +to a response object than just its body. But if you're the kind of person +who values such aesthetics, we have an easy way to allow for this sort of +thing: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + from pyramid.response import Response + + def string_response_adapter(s): + response = Response(s) + response.content_type = 'text/html' + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + +Do that once in your Pyramid application at startup. Now you can return +strings from any of your view callables, e.g.: + +.. code-block:: python + :linenos: + + def helloview(request): + return "Hello world!" + + def goodbyeview(request): + return "Goodbye world!" + +Oh noes! What if you want to indicate a custom content type? And a custom +status code? No fear: + +.. code-block:: python + :linenos: + + from pyramid.config import Configurator + + def tuple_response_adapter(val): + status_int, content_type, body = val + response = Response(body) + response.content_type = content_type + response.status_int = status_int + return response + + def string_response_adapter(body): + response = Response(body) + response.content_type = 'text/html' + response.status_int = 200 + return response + + if __name__ == '__main__': + config = Configurator() + config.add_response_adapter(string_response_adapter, basestring) + config.add_response_adapter(tuple_response_adapter, tuple) + +Once this is done, both of these view callables will work: + +.. code-block:: python + :linenos: + + def aview(request): + return "Hello world!" + + def anotherview(request): + return (403, 'text/plain', "Forbidden") + +Pyramid defaults to explicit behavior, because it's the most generally +useful, but provide hooks that allow you to adapt the framework to localized +aesthetic desires. + +See also :ref:`using_iresponse`. + +"Global" response object +~~~~~~~~~~~~~~~~~~~~~~~~ + +"Constructing these response objects in my view callables is such a chore! +And I'm way too lazy to register a response adapter, as per the prior +section," you say. Fine. Be that way: + +.. code-block:: python + :linenos: + + def aview(request): + response = request.response + response.body = 'Hello world!' + response.content_type = 'text/plain' + return response + +See also :ref:`request_response_attr`. + Automating repetitive configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 814455d4475046a24cd11a30805a5db8d4e4ed13 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:09:23 -0700 Subject: Insert missing "to". --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..63f142124 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -618,7 +618,7 @@ A lot is made of the aesthetics of what *kinds* of objects you're allowed to return from view callables in various frameworks. In a previous section in this document we showed you that, if you use a :term:`renderer`, you can usually return a dictionary from a view callable instead of a full-on -:term:`Response` object. But some frameworks allow you return strings or +:term:`Response` object. But some frameworks allow you to return strings or tuples from view callables. When frameworks allow for this, code looks slightly prettier, because fewer imports need to be done, and there is less code. For example, compare this: -- cgit v1.2.3 From 7047d24edf7ade4e442d1e79dea33492f2a4ba45 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:16:04 -0700 Subject: Corrected verb to agree with singular subject "Pyramid". --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..ed0f322b6 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -715,7 +715,7 @@ Once this is done, both of these view callables will work: return (403, 'text/plain', "Forbidden") Pyramid defaults to explicit behavior, because it's the most generally -useful, but provide hooks that allow you to adapt the framework to localized +useful, but provides hooks that allow you to adapt the framework to localized aesthetic desires. See also :ref:`using_iresponse`. -- cgit v1.2.3 From 3970b06caa0e51fadc9525c7f4ac83b733fd19be Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:23:49 -0700 Subject: Removed line break in hyphenation of "import-time" which rendered as "import- time". --- docs/narr/introduction.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..b2fb95c42 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -456,9 +456,9 @@ No singletons Pyramid is written in such a way that it requires your application to have exactly zero "singleton" data structures. Or, put another way, Pyramid doesn't require you to construct any "mutable globals". Or put even a -different way, an import of a Pyramid application needn't have any "import- -time side effects". This is esoteric-sounding, but if you've ever tried to -cope with parameterizing a Django "settings.py" file for multiple +different way, an import of a Pyramid application needn't have any +"import-time side effects". This is esoteric-sounding, but if you've ever +tried to cope with parameterizing a Django "settings.py" file for multiple installations of the same application, or if you've ever needed to monkey-patch some framework fixture so that it behaves properly for your use case, or if you've ever wanted to deploy your system using an asynchronous -- cgit v1.2.3 From 157d3256acf633bb21cfd09e542c639672c2c579 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:30:48 -0700 Subject: Correct spelling of "chages" to "changes". --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..6bf2665ee 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -503,7 +503,7 @@ data if you're not extremely careful. Some data will have been written to the database that probably should not have. Having a centralized commit point saves you from needing to think about this; it's great for lazy people who also care about data integrity. Either the request completes -successfully, and all chages are committed, or it does not, and all changes +successfully, and all changes are committed, or it does not, and all changes are aborted. Also, Pyramid's transaction management system allows you to synchronize -- cgit v1.2.3 From efc17af3c788809db4fc50cd7c585f6545534933 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:32:52 -0700 Subject: Insert missing "to". --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..ef7615079 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -534,7 +534,7 @@ Configuration extensibility ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike other systems, Pyramid provides a structured "include" mechanism (see -:meth:`~pyramid.config.Configurator.include`) that allows you compose +:meth:`~pyramid.config.Configurator.include`) that allows you to compose applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be performed by included packages including the addition of views, routes, -- cgit v1.2.3 From 0e5e1bc169b137c03f9112925a10c2185c414292 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:39:23 -0700 Subject: "internalization-related" s/b "internationalization-related" --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..633b48d36 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -377,7 +377,7 @@ Example: :ref:`events_chapter` and :ref:`event_types`. Built-in internationalization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid ships with internalization-related features in its core: +Pyramid ships with internationalization-related features in its core: localization, pluralization, and creating message catalogs from source files and templates. Pyramid allows for a plurality of message catalog via the use of translation domains: you can create a system that has its own translations -- cgit v1.2.3 From acf9ff6b8816afa4e0ce57b6301911fe343d4fb4 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 9 Sep 2011 03:42:38 -0700 Subject: "CMS systems" is redundant, so spelled out acronym. --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8694556b2..8cd6daba8 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -592,8 +592,8 @@ to be arbitrarily extensible: it's a lot easier to add a node to a tree than it is to shoehorn a route into an ordered list of other routes, or to create another entire instance of an application to service a department and glue code to allow disparate apps to share data. It's a great fit for sites that -naturally lend themselves to changing departmental hierarchies, such as CMS -systems and document management systems. Traversal also lends itself well to +naturally lend themselves to changing departmental hierarchies, such as +content management systems and document management systems. Traversal also lends itself well to systems that require very granular security ("Bob can edit *this* document" as opposed to "Bob can edit documents"). -- cgit v1.2.3 From c8b363e547635e92a78c5718e9f17a5e8f55dc7f Mon Sep 17 00:00:00 2001 From: michr Date: Thu, 29 Sep 2011 02:03:33 -0700 Subject: avoid warning for latexindex, foreword by putting them in a hidden toc from now on complie docs strictly, turning warnings to errors exclude unnecssary static js files when compiling ePub --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 823c1ea13..8f0533997 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -826,7 +826,7 @@ trolls" or other people who seem to get their rocks off by berating fellow users in our various offical support channels. We try to keep it well-lit and new-user-friendly. -Example: Visit irc://freenode.net#pyramid (the ``#pyramid`` channel on +Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at http://groups.google.com/group/pylons-discuss/ . -- cgit v1.2.3 From cfb2b5596b8ef366aeef3bce5b61eafc7a2f175d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 6 Oct 2011 03:05:29 -0400 Subject: remove all reference to the paster command-line utility --- docs/narr/introduction.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 823c1ea13..e30a23a9a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -202,11 +202,11 @@ turn on "debug_authorization", which lets you know why a view execution was allowed or denied by printing a message to the console. These features are useful for those WTF moments. -There are also a number of ``paster`` commands that allow you to introspect -the configuration of your system: ``paster proutes`` shows all configured -routes for an application in the order they'll be evaluated for matching; -``paster pviews`` shows all configured views for any given URL. These are -also WTF-crushers in some circumstances. +There are also a number of commands that you can invoke within a Pyramid +environment that allow you to introspect the configuration of your system: +``proutes`` shows all configured routes for an application in the order +they'll be evaluated for matching; ``pviews`` shows all configured views for +any given URL. These are also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. -- cgit v1.2.3 From 56f1d2ea13f93b46161d12112e75125efee2120b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 21 Nov 2011 12:03:47 -0500 Subject: de-jythonify --- docs/narr/introduction.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 547f88ef3..2387db6a7 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -808,11 +808,11 @@ Every release of Pyramid has 100% statement coverage via unit and integration tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the ``instrumental`` tool available on PyPI. It is automatically tested by the -Jenkins tool on Python 2.5, Python 2.6, Python 2.7, Jython and PyPy after -each commit to its GitHub repository. Official Pyramid add-ons are held to a -similar testing standard. We still find bugs in Pyramid and its official -add-ons, but we've noticed we find a lot more of them while working on other -projects that don't have a good testing regime. +Jenkins tool on Python 2.6, Python 2.7, Python 3.2 and PyPy after each commit +to its GitHub repository. Official Pyramid add-ons are held to a similar +testing standard. We still find bugs in Pyramid and its official add-ons, +but we've noticed we find a lot more of them while working on other projects +that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ -- cgit v1.2.3 From f75a3f07b0a5699f99b89d93b4e3a66beea21ac1 Mon Sep 17 00:00:00 2001 From: Chris Davies Date: Thu, 1 Dec 2011 01:57:41 -0500 Subject: https://docs.pylonsproject.org to http://docs.pylonsproject.org as readthedocs.org doesn't support https --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 2387db6a7..7c6ad00f3 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -219,7 +219,7 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. -Examples: https://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation +Examples: http://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -842,7 +842,7 @@ official narrative docs. In any case, the Pyramid documentation is comprehensive. Example: The rest of this documentation and the cookbook at -https://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . +http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . .. index:: single: Pylons Project -- cgit v1.2.3 From 97b64d3b736f6abf0d78126c75d5e56e774bd234 Mon Sep 17 00:00:00 2001 From: Paul Winkler Date: Mon, 30 Jan 2012 17:34:51 -0500 Subject: Hello world with traversal, linked from various places; plus some 'what this chapter is for' notes on the other traversal chapters. Hope this helps. --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 7c6ad00f3..92955aafd 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -597,7 +597,7 @@ content management systems and document management systems. Traversal also lend systems that require very granular security ("Bob can edit *this* document" as opposed to "Bob can edit documents"). -Example: :ref:`much_ado_about_traversal_chapter`. +Example: :ref:`hello_traversal_chapter` and :ref:`much_ado_about_traversal_chapter`. Tweens ~~~~~~ -- cgit v1.2.3 From d66d9a6507a983f4a6510ba19a0d4f3e87e39c4b Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Sun, 11 Mar 2012 17:13:35 -0600 Subject: view class methods were missing self parameter. --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 92955aafd..507201439 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -260,11 +260,11 @@ Here's a few views defined as methods of a class instead: self.request = request @view_config(route_name='view_one') - def view_one(request): + def view_one(self, request): return Response('one') @view_config(route_name='view_two') - def view_two(request): + def view_two(self, request): return Response('two') See also :ref:`view_config_placement`. -- cgit v1.2.3 From e73a5496b04952c45201449a5ce75d89c6678b7e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 11 Mar 2012 19:16:53 -0700 Subject: only self --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 507201439..d7e719bb1 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -260,11 +260,11 @@ Here's a few views defined as methods of a class instead: self.request = request @view_config(route_name='view_one') - def view_one(self, request): + def view_one(self): return Response('one') @view_config(route_name='view_two') - def view_two(self, request): + def view_two(self): return Response('two') See also :ref:`view_config_placement`. -- cgit v1.2.3 From c946fc7b717359cf26dab45a9b84f06f6c1bc466 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Tue, 13 Mar 2012 17:19:18 -0700 Subject: Typos --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index d7e719bb1..8f7b17dc3 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -347,7 +347,7 @@ You can do this: When this view callable is called by Pyramid, the ``{'a':1}`` dictionary will be rendered to a response on your behalf. The string passed as ``renderer=`` above is an :term:`asset specification`. It is in the form -``packagename:directoryname/filename.ext``. In this case, it names the +``packagename:directoryname/filename.ext``. In this case, it refers to the ``mytemplate.pt`` file in the ``templates`` directory within the ``myapp`` Python package. Asset specifications are omnipresent in Pyramid: see :ref:`intro_asset_specs` for more information. -- cgit v1.2.3 From 5d0989efeb3eecd4cc55fd9c1dcaf1134ced56b2 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 4 May 2012 19:56:00 -0400 Subject: add introspection to whats unique --- docs/narr/introduction.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8f7b17dc3..2d04a4f5a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -801,6 +801,34 @@ within a function called when another user uses the See also :ref:`add_directive`. +Programmatic Introspection +-------------------------- + +If you're building a large system that other users may plug code into, it's +useful to be able to get an enumeration of what code they plugged in *at +application runtime*. For example, you might want to show them a set of tabs +at the top of the screen based on an enumeration of views they registered. + +This is possible using Pyramid's :term:`introspector`. + +Here's an example of using Pyramid's introspector from within a view +callable: + +.. code-block:: python + :linenos: + + from pyramid.view import view_config + from pyramid.response import Response + + @view_config(route_name='bar') + def show_current_route_pattern(request): + introspector = request.registry.introspector + route_name = request.matched_route.name + route_intr = introspector.get('routes', route_name) + return Response(str(route_intr['pattern'])) + +See also :ref:`using_introspection`. + Testing ~~~~~~~ -- cgit v1.2.3 From d6a9543c1149c02c19aca3d053a5afd9ca0f1dbf Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 4 May 2012 19:59:50 -0400 Subject: garden --- docs/narr/introduction.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 2d04a4f5a..a1f1c7d5e 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -593,11 +593,12 @@ it is to shoehorn a route into an ordered list of other routes, or to create another entire instance of an application to service a department and glue code to allow disparate apps to share data. It's a great fit for sites that naturally lend themselves to changing departmental hierarchies, such as -content management systems and document management systems. Traversal also lends itself well to -systems that require very granular security ("Bob can edit *this* document" -as opposed to "Bob can edit documents"). +content management systems and document management systems. Traversal also +lends itself well to systems that require very granular security ("Bob can +edit *this* document" as opposed to "Bob can edit documents"). -Example: :ref:`hello_traversal_chapter` and :ref:`much_ado_about_traversal_chapter`. +Examples: :ref:`hello_traversal_chapter` and +:ref:`much_ado_about_traversal_chapter`. Tweens ~~~~~~ -- cgit v1.2.3 From 1252ab764fda606003aa23a0e3bfa89ba948e3f1 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 4 May 2012 20:07:10 -0400 Subject: add python 3 as a uniqueness --- docs/narr/introduction.rst | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a1f1c7d5e..9b3a63089 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -830,6 +830,14 @@ callable: See also :ref:`using_introspection`. +Python 3 Compatibility +---------------------- + +Pyramid and most of its add-ons are Python 3 compatible. If you develop a +Pyramid application today, you won't need to worry that five years from now +you'll be backwatered because there are language features you'd like to use +but your framework doesn't support newer Python versions. + Testing ~~~~~~~ -- cgit v1.2.3 From 1d03bbca7fe9f005d4a08c7dfe7eb139ab4b0df1 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Mon, 7 May 2012 21:45:40 -0500 Subject: Two grammatical fixes --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 9b3a63089..b5fa6a9f7 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -534,14 +534,14 @@ Configuration extensibility ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike other systems, Pyramid provides a structured "include" mechanism (see -:meth:`~pyramid.config.Configurator.include`) that allows you to compose +:meth:`~pyramid.config.Configurator.include`) that allows you to combine applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be performed by included packages including the addition of views, routes, subscribers, and even authentication and authorization policies. You can even extend or override an existing application by including another application's configuration in your own, overriding or adding new views and routes to -it. This has the potential to allow you to compose a big application out of +it. This has the potential to allow you to create a big application out of many other smaller ones. For example, if you want to reuse an existing application that already has a bunch of routes, you can just use the ``include`` statement with a ``route_prefix``; the new application will live -- cgit v1.2.3 From 32178572428cafec64f73dc06cad5c02feaceba8 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 11 Aug 2012 02:18:21 -0600 Subject: get heading levels right --- docs/narr/introduction.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b5fa6a9f7..7c0f9223f 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -803,7 +803,7 @@ within a function called when another user uses the See also :ref:`add_directive`. Programmatic Introspection --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ If you're building a large system that other users may plug code into, it's useful to be able to get an enumeration of what code they plugged in *at @@ -831,7 +831,7 @@ callable: See also :ref:`using_introspection`. Python 3 Compatibility ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ Pyramid and most of its add-ons are Python 3 compatible. If you develop a Pyramid application today, you won't need to worry that five years from now -- cgit v1.2.3 From 5f0e510c7de2735f8cb84479be07a94a9617b8b8 Mon Sep 17 00:00:00 2001 From: Carlos de la Guardia Date: Fri, 28 Sep 2012 01:14:27 -0500 Subject: Remove duplicate word --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 7c0f9223f..b35c61720 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -315,7 +315,7 @@ Rendered views can return dictionaries If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a -dictionary instead, and Pyramid will take care of converting that dictionary +dictionary, and Pyramid will take care of converting that dictionary to a Response using a template on your behalf. This makes the view easier to test, because you don't have to parse HTML in your tests; just make an assertion instead that the view returns "the right stuff" in the dictionary -- cgit v1.2.3 From f65e191ed7da0ff97638879cf854c0b1cb505aaa Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 2 Jan 2013 23:09:40 +0200 Subject: typos --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b35c61720..956d7a177 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -101,7 +101,7 @@ frameworks for small and large applications is just false; a well-designed framework should be able to be good at both. Pyramid strives to be that kind of framework. -To this end, Pyramid provides a set of features, that, combined, are unique +To this end, Pyramid provides a set of features that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some combination of these features; Pyramid of course actually stole many of them from those other frameworks. But Pyramid is the only one that has all of -- cgit v1.2.3 From a03b29ccc094537fa0d80b2545a9d16fc94566cb Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 8 Jan 2013 00:50:24 +0200 Subject: typos --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b35c61720..187b81702 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -475,7 +475,7 @@ per route. For example, you can create a route with the pattern ``/items`` and when the route is matched, you can shuffle off the request to one view if the request method is GET, another view if the request method is POST, etc. A system known as "view predicates" allows for this. Request method matching -is the very most basic thing you can do with a view predicate. You can also +is the most basic thing you can do with a view predicate. You can also associate views with other request parameters such as the elements in the query string, the Accept header, whether the request is an XHR request or not, and lots of other things. This feature allows you to keep your -- cgit v1.2.3 From 01c184719d026b8c61267e55b0646da9b86bd6a0 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sun, 3 Feb 2013 23:44:51 +0200 Subject: remove questionable sentence I could not tell whether it was meant to be humorous, or if it simply was a mistake. Regardless, I think it does not add much. If Speed needs to be defended, perhaps something better would do. For now, I remove. --- docs/narr/introduction.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index c4f2ea512..809732220 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -52,9 +52,7 @@ Documentation Speed :app:`Pyramid` is designed to provide noticeably fast execution for common - tasks such as templating and simple response generation. Although "hardware - is cheap", the limits of this approach become painfully evident when one - finds him or herself responsible for managing a great many machines. + tasks such as templating and simple response generation. Reliability :app:`Pyramid` is developed conservatively and tested exhaustively. Where -- cgit v1.2.3 From 1d3b11ea4c7ce0e05ca80063f997596791f75fda Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 4 Feb 2013 20:53:03 +0200 Subject: fix and shorten broken sentence --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index c4f2ea512..3540ee5c4 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -749,7 +749,7 @@ that we change Pyramid? You can extend Pyramid's :term:`Configurator` with your own directives. For example, let's say you find yourself calling :meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can take the boring away by using existing shortcuts, but let's say that this is -a case such a way that no existing shortcut works to take the boring away: +a case where there is no such shortcut: .. code-block:: python :linenos: -- cgit v1.2.3 From 9547903b00196b7311b6f0c26f42fed78a91e933 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Tue, 19 Feb 2013 23:34:56 +0200 Subject: rm broken link; could not find existing equivalent --- docs/narr/introduction.rst | 1 - 1 file changed, 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 3540ee5c4..47c32b0ba 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -219,7 +219,6 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. -Examples: http://docs.pylonsproject.org/docs/pyramid.html#pyramid-add-on-documentation Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 37607c3a9382de7c3757799791a91b80e2d9888d Mon Sep 17 00:00:00 2001 From: Catalin Iacob Date: Sun, 31 Mar 2013 14:33:24 +0200 Subject: Consistently link middleware term to the glossary --- docs/narr/introduction.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index f9c25c69c..48164d323 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -600,10 +600,10 @@ Examples: :ref:`hello_traversal_chapter` and Tweens ~~~~~~ -Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be -hooked by arbitrary add-ons named "tweens". The debug toolbar is a "tween", -and the ``pyramid_tm`` transaction manager is also. Tweens are more useful -than WSGI middleware in some circumstances because they run in the context of +Pyramid has a sort of internal WSGI-middleware-ish pipeline that can be hooked +by arbitrary add-ons named "tweens". The debug toolbar is a "tween", and the +``pyramid_tm`` transaction manager is also. Tweens are more useful than WSGI +:term:`middleware` in some circumstances because they run in the context of Pyramid itself, meaning you have access to templates and other renderers, a "real" request object, and other niceties. -- cgit v1.2.3 From ff00405c65a901d5a952e27ec96ff4239c58b012 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 2 Aug 2013 13:00:52 -0400 Subject: point at add-on documentation --- docs/narr/introduction.rst | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 48164d323..fa2646134 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -217,6 +217,8 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. +Examples: http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation + Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 4a7ab035275b20b9a2926d65a3936b6fc8c35c3a Mon Sep 17 00:00:00 2001 From: tisdall Date: Fri, 9 Aug 2013 14:51:35 -0400 Subject: "offical" to "official" --- docs/narr/introduction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index fa2646134..032f4be6b 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -859,7 +859,7 @@ It's our goal that no Pyramid question go unanswered. Whether you ask a question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're likely to get a reasonably prompt response. We don't tolerate "support trolls" or other people who seem to get their rocks off by berating fellow -users in our various offical support channels. We try to keep it well-lit +users in our various official support channels. We try to keep it well-lit and new-user-friendly. Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on -- cgit v1.2.3 From 1f7a00346411033d935bf931c206b585353f8be4 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Sat, 5 Oct 2013 00:37:09 -0500 Subject: Docs: Link from renderer narrative docs to example render_to_response call, and index the example. More fully explain the 2 examples, one with render_to_response call and one without. --- docs/narr/introduction.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 032f4be6b..8c2acf95c 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -321,7 +321,14 @@ assertion instead that the view returns "the right stuff" in the dictionary it returns. You can write "real" unit tests instead of functionally testing all of your views. -For example, instead of: +.. index:: + pair: renderer; explicitly calling + pair: view renderer; explictly calling + +.. _example_render_to_response_call: + +For example, instead of returning a ``Response`` object from a +``render_to_response`` call: .. code-block:: python :linenos: @@ -332,7 +339,7 @@ For example, instead of: return render_to_response('myapp:templates/mytemplate.pt', {'a':1}, request=request) -You can do this: +You can return a Python dictionary: .. code-block:: python :linenos: -- cgit v1.2.3 From daefb5f5009166ac9fbc3ba7fb6498d093620eec Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 10:12:14 -0500 Subject: Doc: introduction.rst: Broaden debug toolbar feature description to include other interactive development features. --- docs/narr/introduction.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 032f4be6b..64cce407a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -176,8 +176,13 @@ static file server in production without changing any code. Example: :ref:`static_assets_section`. -Debug Toolbar -~~~~~~~~~~~~~ +Fully Interactive Development +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When developing a Pyramid application a variety of interactive features are +available. Pyramid will automatically utilize changed templates when +rendering pages and automatically restart the application to incorporate +changed python code. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -- cgit v1.2.3 From 6461f60320106b5114bb7f226959c7d7f2995ec2 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 11:26:22 -0500 Subject: Docs: introduction.rst: Improve wording. --- docs/narr/introduction.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 64cce407a..816199038 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -179,10 +179,10 @@ Example: :ref:`static_assets_section`. Fully Interactive Development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When developing a Pyramid application a variety of interactive features are -available. Pyramid will automatically utilize changed templates when -rendering pages and automatically restart the application to incorporate -changed python code. +When developing a Pyramid application a variety of interactive +features are available. Pyramid can automatically utilize changed +templates when rendering pages and automatically restart the +application to incorporate changed python code. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -- cgit v1.2.3 From 8e1e6914945a5a3d05f49f0e32b7152182b23767 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Mon, 7 Oct 2013 22:20:26 -0500 Subject: Docs: introduction.rst: Note that printf() works. --- docs/narr/introduction.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 9ec26f276..b60934ebb 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -182,7 +182,8 @@ Fully Interactive Development When developing a Pyramid application a variety of interactive features are available. Pyramid can automatically utilize changed templates when rendering pages and automatically restart the -application to incorporate changed python code. +application to incorporate changed python code. Plain old ``printf()`` +calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -- cgit v1.2.3 From d84407421d1830ed726bcc280b3de112aca701e7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 7 Oct 2013 21:40:10 -0700 Subject: wrap to 79 --- docs/narr/introduction.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index b60934ebb..ece720a97 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -179,11 +179,11 @@ Example: :ref:`static_assets_section`. Fully Interactive Development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When developing a Pyramid application a variety of interactive -features are available. Pyramid can automatically utilize changed -templates when rendering pages and automatically restart the -application to incorporate changed python code. Plain old ``printf()`` -calls used for debugging can display to a console. +When developing a Pyramid application, several interactive features are +available. Pyramid can automatically utilize changed templates when rendering +pages and automatically restart the application to incorporate changed python +code. Plain old ``printf()`` calls used for debugging can display to a +console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and @@ -790,7 +790,7 @@ automate some of the tedium away: for method in ('GET', 'POST', 'HEAD'): view = getattr(module, 'xhr_%s_view' % method, None) if view is not None: - config.add_view(view, route_name='xhr_route', xhr=True, + config.add_view(view, route_name='xhr_route', xhr=True, permission='view', request_method=method) config = Configurator() -- cgit v1.2.3 From 2004173e4f1614b8eb9cc3534ec3117c736ff009 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 8 Oct 2013 09:37:39 -0500 Subject: Docs: introduction.rst: Beaker -> Redis. --- docs/narr/introduction.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index ece720a97..4e705b8b1 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -418,12 +418,12 @@ Sessions Pyramid has built-in HTTP sessioning. This allows you to associate data with otherwise anonymous users between requests. Lots of systems do this. But -Pyramid also allows you to plug in your own sessioning system by creating -some code that adheres to a documented interface. Currently there is a -binding package for the third-party Beaker sessioning system that does exactly -this. But if you have a specialized need (perhaps you want to store your -session data in MongoDB), you can. You can even switch between -implementations without changing your application code. +Pyramid also allows you to plug in your own sessioning system by creating some +code that adheres to a documented interface. Currently there is a binding +package for the third-party Redis sessioning system that does exactly this. +But if you have a specialized need (perhaps you want to store your session data +in MongoDB), you can. You can even switch between implementations without +changing your application code. Example: :ref:`sessions_chapter`. -- cgit v1.2.3 From 4bc489d00bcb6013db1e9da00c3c16809eeb90fc Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 8 Oct 2013 11:17:18 -0700 Subject: print() not printf() --- docs/narr/introduction.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index ece720a97..bb2d85e94 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -180,10 +180,9 @@ Fully Interactive Development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When developing a Pyramid application, several interactive features are -available. Pyramid can automatically utilize changed templates when rendering +available. Pyramid can automatically utilize changed templates when rendering pages and automatically restart the application to incorporate changed python -code. Plain old ``printf()`` calls used for debugging can display to a -console. +code. Plain old ``print()`` calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -- cgit v1.2.3 From 392a6c7df93b67d6889680133fda0f744970d61f Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sun, 17 Nov 2013 00:11:37 +0200 Subject: Removed extra indentation from some examples (:linenos: should be indented with the same indentation as the rest of the code block) --- docs/narr/introduction.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a9c5fdfbd..8acbab3a0 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -336,7 +336,7 @@ For example, instead of returning a ``Response`` object from a ``render_to_response`` call: .. code-block:: python - :linenos: + :linenos: from pyramid.renderers import render_to_response @@ -347,7 +347,7 @@ For example, instead of returning a ``Response`` object from a You can return a Python dictionary: .. code-block:: python - :linenos: + :linenos: from pyramid.view import view_config @@ -827,7 +827,7 @@ Here's an example of using Pyramid's introspector from within a view callable: .. code-block:: python - :linenos: + :linenos: from pyramid.view import view_config from pyramid.response import Response -- cgit v1.2.3 From 2033eeb3602f330930585678aac926749b9c22f7 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 10 Feb 2014 03:22:33 -0600 Subject: - Garden PR #1121 --- docs/narr/introduction.rst | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8acbab3a0..a37d74c9b 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -121,7 +121,9 @@ ways. .. literalinclude:: helloworld.py -See also :ref:`firstapp_chapter`. +.. seealso:: + + See also :ref:`firstapp_chapter`. Decorator-based configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -271,7 +273,9 @@ Here's a few views defined as methods of a class instead: def view_two(self): return Response('two') -See also :ref:`view_config_placement`. +.. seealso:: + + See also :ref:`view_config_placement`. .. _intro_asset_specs: @@ -572,7 +576,10 @@ For example: config.include('pyramid_exclog') config.include('some.other.guys.package', route_prefix='/someotherguy') -See also :ref:`including_configuration` and :ref:`building_an_extensible_app` +.. seealso:: + + See also :ref:`including_configuration` and + :ref:`building_an_extensible_app`. Flexible authentication and authorization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -730,7 +737,9 @@ Pyramid defaults to explicit behavior, because it's the most generally useful, but provides hooks that allow you to adapt the framework to localized aesthetic desires. -See also :ref:`using_iresponse`. +.. seealso:: + + See also :ref:`using_iresponse`. "Global" response object ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -748,7 +757,9 @@ section," you say. Fine. Be that way: response.content_type = 'text/plain' return response -See also :ref:`request_response_attr`. +.. seealso:: + + See also :ref:`request_response_attr`. Automating repetitive configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -811,7 +822,9 @@ it up and calling :meth:`~pyramid.config.Configurator.add_directive` from within a function called when another user uses the :meth:`~pyramid.config.Configurator.include` method against your code. -See also :ref:`add_directive`. +.. seealso:: + + See also :ref:`add_directive`. Programmatic Introspection ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -839,7 +852,9 @@ callable: route_intr = introspector.get('routes', route_name) return Response(str(route_intr['pattern'])) -See also :ref:`using_introspection`. +.. seealso:: + + See also :ref:`using_introspection`. Python 3 Compatibility ~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From d5923976b090e3538d9e655d72361cbfab6a250a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 31 May 2015 11:48:55 -0700 Subject: - update testing and templating remarks - grammar, punctuation, 79-column rewrapping, case corrections --- docs/narr/introduction.rst | 165 +++++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 82 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index a37d74c9b..2d3cd23e9 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -65,11 +65,11 @@ Openness .. _what_makes_pyramid_unique: -What Makes Pyramid Unique +What makes Pyramid unique ------------------------- Understandably, people don't usually want to hear about squishy engineering -principles, they want to hear about concrete stuff that solves their +principles; they want to hear about concrete stuff that solves their problems. With that in mind, what would make someone want to use Pyramid instead of one of the many other web frameworks available today? What makes Pyramid unique? @@ -78,13 +78,13 @@ This is a hard question to answer, because there are lots of excellent choices, and it's actually quite hard to make a wrong choice, particularly in the Python web framework market. But one reasonable answer is this: you can write very small applications in Pyramid without needing to know a lot. -"What?", you say, "that can't possibly be a unique feature, lots of other web +"What?", you say. "That can't possibly be a unique feature. Lots of other web frameworks let you do that!" Well, you're right. But unlike many other systems, you can also write very large applications in Pyramid if you learn a little more about it. Pyramid will allow you to become productive quickly, -and will grow with you; it won't hold you back when your application is small +and will grow with you. It won't hold you back when your application is small, and it won't get in your way when your application becomes large. "Well -that's fine," you say, "lots of other frameworks let me write large apps +that's fine," you say. "Lots of other frameworks let me write large apps, too." Absolutely. But other Python web frameworks don't seamlessly let you do both. They seem to fall into two non-overlapping categories: frameworks for "small apps" and frameworks for "big apps". The "small app" frameworks @@ -95,15 +95,15 @@ in a "small framework" and "big apps" in a "big framework". You can't really know to what size every application will eventually grow. We don't really want to have to rewrite a previously small application in another framework when it gets "too big". We believe the current binary distinction between -frameworks for small and large applications is just false; a well-designed +frameworks for small and large applications is just false. A well-designed framework should be able to be good at both. Pyramid strives to be that kind of framework. To this end, Pyramid provides a set of features that, combined, are unique amongst Python web frameworks. Lots of other frameworks contain some -combination of these features; Pyramid of course actually stole many of them +combination of these features. Pyramid of course actually stole many of them from those other frameworks. But Pyramid is the only one that has all of -them in one place, documented appropriately, and useful a la carte without +them in one place, documented appropriately, and useful *à la carte* without necessarily paying for the entire banquet. These are detailed below. Single-file applications @@ -143,14 +143,14 @@ decorators to localize the configuration. For example: return Response('fred') However, unlike some other systems, using decorators for Pyramid -configuration does not make your application difficult to extend, test or +configuration does not make your application difficult to extend, test, or reuse. The :class:`~pyramid.view.view_config` decorator, for example, does not actually *change* the input or output of the function it decorates, so -testing it is a "WYSIWYG" operation; you don't need to understand the -framework to test your own code, you just behave as if the decorator is not +testing it is a "WYSIWYG" operation. You don't need to understand the +framework to test your own code. You just behave as if the decorator is not there. You can also instruct Pyramid to ignore some decorators, or use completely imperative configuration instead of decorators to add views. -Pyramid decorators are inert instead of eager: you detect and activate them +Pyramid decorators are inert instead of eager. You detect and activate them with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. @@ -171,24 +171,24 @@ Static file serving Pyramid is perfectly willing to serve static files itself. It won't make you use some external web server to do that. You can even serve more than one set of static files in a single Pyramid web application (e.g. ``/static`` and -``/static2``). You can also, optionally, place your files on an external web -server and ask Pyramid to help you generate URLs to those files, so you can -use Pyramid's internal fileserving while doing development, and a faster -static file server in production without changing any code. +``/static2``). You can optionally place your files on an external web +server and ask Pyramid to help you generate URLs to those files. This let's +you use Pyramid's internal file serving while doing development, and a faster +static file server in production, without changing any code. Example: :ref:`static_assets_section`. -Fully Interactive Development +Fully interactive development ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When developing a Pyramid application, several interactive features are available. Pyramid can automatically utilize changed templates when rendering -pages and automatically restart the application to incorporate changed python +pages and automatically restart the application to incorporate changed Python code. Plain old ``print()`` calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and -allows you access to framework data such as the routes configured, the last +allows you access to framework data, such as the routes configured, the last renderings performed, the current set of packages installed, SQLAlchemy queries run, logging data, and various other facts. When an exception occurs, you can use its interactive debugger to poke around right in your @@ -201,16 +201,16 @@ Debugging settings Pyramid has debugging settings that allow you to print Pyramid runtime information to the console when things aren't behaving as you're expecting. -For example, you can turn on "debug_notfound", which prints an informative +For example, you can turn on ``debug_notfound``, which prints an informative message to the console every time a URL does not match any view. You can -turn on "debug_authorization", which lets you know why a view execution was +turn on ``debug_authorization``, which lets you know why a view execution was allowed or denied by printing a message to the console. These features are useful for those WTF moments. There are also a number of commands that you can invoke within a Pyramid -environment that allow you to introspect the configuration of your system: +environment that allow you to introspect the configuration of your system. ``proutes`` shows all configured routes for an application in the order -they'll be evaluated for matching; ``pviews`` shows all configured views for +they'll be evaluated for matching. ``pviews`` shows all configured views for any given URL. These are also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. @@ -224,8 +224,8 @@ that the Pyramid core doesn't. Add-on packages already exist which let you easily send email, let you use the Jinja2 templating system, let you use XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. -Examples: http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation - +Examples: +http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -233,13 +233,13 @@ Class-based and function-based views Pyramid has a structured, unified concept of a :term:`view callable`. View callables can be functions, methods of classes, or even instances. When you add a new view callable, you can choose to make it a function or a method -of a class; in either case, Pyramid treats it largely the same way. You can -change your mind later, and move code between methods of classes and +of a class. In either case Pyramid treats it largely the same way. You can +change your mind later and move code between methods of classes and functions. A collection of similar view callables can be attached to a single class as methods, if that floats your boat, and they can share initialization code as necessary. All kinds of views are easy to understand -and use and operate similarly. There is no phony distinction between them; -they can be used for the same purposes. +and use, and operate similarly. There is no phony distinction between them. +They can be used for the same purposes. Here's a view callable defined as a function: @@ -283,10 +283,10 @@ Asset specifications ~~~~~~~~~~~~~~~~~~~~ Asset specifications are strings that contain both a Python package name and -a file or directory name, e.g. ``MyPackage:static/index.html``. Use of these +a file or directory name, e.g., ``MyPackage:static/index.html``. Use of these specifications is omnipresent in Pyramid. An asset specification can refer to a template, a translation directory, or any other package-bound static -resource. This makes a system built on Pyramid extensible, because you don't +resource. This makes a system built on Pyramid extensible because you don't have to rely on globals ("*the* static directory") or lookup schemes ("*the* ordered set of template directories") to address your files. You can move files around as necessary, and include other packages that may not share your @@ -325,10 +325,9 @@ If you use a :term:`renderer`, you don't have to return a special kind of "webby" ``Response`` object from a view. Instead, you can return a dictionary, and Pyramid will take care of converting that dictionary to a Response using a template on your behalf. This makes the view easier to -test, because you don't have to parse HTML in your tests; just make an -assertion instead that the view returns "the right stuff" in the dictionary -it returns. You can write "real" unit tests instead of functionally testing -all of your views. +test, because you don't have to parse HTML in your tests; instead just make an +assertion that the view returns "the right stuff" in the dictionary. You can +write "real" unit tests instead of functionally testing all of your views. .. index:: pair: renderer; explicitly calling @@ -394,7 +393,7 @@ Built-in internationalization Pyramid ships with internationalization-related features in its core: localization, pluralization, and creating message catalogs from source files -and templates. Pyramid allows for a plurality of message catalog via the use +and templates. Pyramid allows for a plurality of message catalogs via the use of translation domains: you can create a system that has its own translations without conflict with other translations in other domains. @@ -445,7 +444,7 @@ useless without requirements and goals, but if you need speed, Pyramid will almost certainly never be your application's bottleneck; at least no more than Python will be a bottleneck. -Example: http://blog.curiasolutions.com/the-great-web-framework-shootout/ +Example: http://blog.curiasolutions.com/pages/the-great-web-framework-shootout.html Exception views ~~~~~~~~~~~~~~~ @@ -469,11 +468,11 @@ No singletons ~~~~~~~~~~~~~ Pyramid is written in such a way that it requires your application to have -exactly zero "singleton" data structures. Or, put another way, Pyramid +exactly zero "singleton" data structures. Or put another way, Pyramid doesn't require you to construct any "mutable globals". Or put even a different way, an import of a Pyramid application needn't have any "import-time side effects". This is esoteric-sounding, but if you've ever -tried to cope with parameterizing a Django "settings.py" file for multiple +tried to cope with parameterizing a Django ``settings.py`` file for multiple installations of the same application, or if you've ever needed to monkey-patch some framework fixture so that it behaves properly for your use case, or if you've ever wanted to deploy your system using an asynchronous @@ -494,7 +493,7 @@ is the most basic thing you can do with a view predicate. You can also associate views with other request parameters such as the elements in the query string, the Accept header, whether the request is an XHR request or not, and lots of other things. This feature allows you to keep your -individual views "clean"; they won't need much conditional logic, so they'll +individual views clean. They won't need much conditional logic, so they'll be easier to test. Example: :ref:`view_configuration_parameters`. @@ -505,10 +504,10 @@ Transaction management Pyramid's :term:`scaffold` system renders projects that include a *transaction management* system, stolen from Zope. When you use this transaction management system, you cease being responsible for committing -your data anymore. Instead, Pyramid takes care of committing: it commits at +your data anymore. Instead Pyramid takes care of committing: it commits at the end of a request or aborts if there's an exception. Why is that a good thing? Having a centralized place for transaction management is a great -thing. If, instead of managing your transactions in a centralized place, you +thing. If instead of managing your transactions in a centralized place you sprinkle ``session.commit`` calls in your application logic itself, you can wind up in a bad place. Wherever you manually commit data to your database, it's likely that some of your other code is going to run *after* your commit. @@ -521,8 +520,8 @@ who also care about data integrity. Either the request completes successfully, and all changes are committed, or it does not, and all changes are aborted. -Also, Pyramid's transaction management system allows you to synchronize -commits between multiple databases, and allows you to do things like +Pyramid's transaction management system allows you to synchronize +commits between multiple databases. It also allows you to do things like conditionally send email if a transaction commits, but otherwise keep quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements @@ -534,13 +533,14 @@ Configuration conflict detection When a system is small, it's reasonably easy to keep it all in your head. But when systems grow large, you may have hundreds or thousands of configuration statements which add a view, add a route, and so forth. -Pyramid's configuration system keeps track of your configuration statements, -and if you accidentally add two that are identical, or Pyramid can't make + +Pyramid's configuration system keeps track of your configuration statements. +If you accidentally add two that are identical, or Pyramid can't make sense out of what it would mean to have both statements active at the same -time, it will complain loudly at startup time. It's not dumb though: it will +time, it will complain loudly at startup time. It's not dumb though. It will automatically resolve conflicting configuration statements on its own if you -use the configuration :meth:`~pyramid.config.Configurator.include` system: -"more local" statements are preferred over "less local" ones. This allows +use the configuration :meth:`~pyramid.config.Configurator.include` system. +"More local" statements are preferred over "less local" ones. This allows you to intelligently factor large systems into smaller ones. Example: :ref:`conflict_detection`. @@ -552,15 +552,15 @@ Unlike other systems, Pyramid provides a structured "include" mechanism (see :meth:`~pyramid.config.Configurator.include`) that allows you to combine applications from multiple Python packages. All the configuration statements that can be performed in your "main" Pyramid application can also be -performed by included packages including the addition of views, routes, +performed by included packages, including the addition of views, routes, subscribers, and even authentication and authorization policies. You can even extend or override an existing application by including another application's configuration in your own, overriding or adding new views and routes to it. This has the potential to allow you to create a big application out of many other smaller ones. For example, if you want to reuse an existing application that already has a bunch of routes, you can just use the -``include`` statement with a ``route_prefix``; the new application will live -within your application at a URL prefix. It's not a big deal, and requires +``include`` statement with a ``route_prefix``. The new application will live +within your application at an URL prefix. It's not a big deal, and requires little up-front engineering effort. For example: @@ -603,8 +603,8 @@ Traversal :term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to create a tree of resources, each of which can be addressed by one or more URLs. Each of those resources can have one or more *views* associated with -it. If your data isn't naturally treelike (or you're unwilling to create a -treelike representation of your data), you aren't going to find traversal +it. If your data isn't naturally treelike, or you're unwilling to create a +treelike representation of your data, you aren't going to find traversal very useful. However, traversal is absolutely fantastic for sites that need to be arbitrarily extensible: it's a lot easier to add a node to a tree than it is to shoehorn a route into an ordered list of other routes, or to create @@ -635,7 +635,7 @@ View response adapters A lot is made of the aesthetics of what *kinds* of objects you're allowed to return from view callables in various frameworks. In a previous section in -this document we showed you that, if you use a :term:`renderer`, you can +this document, we showed you that, if you use a :term:`renderer`, you can usually return a dictionary from a view callable instead of a full-on :term:`Response` object. But some frameworks allow you to return strings or tuples from view callables. When frameworks allow for this, code looks @@ -826,7 +826,7 @@ within a function called when another user uses the See also :ref:`add_directive`. -Programmatic Introspection +Programmatic introspection ~~~~~~~~~~~~~~~~~~~~~~~~~~ If you're building a large system that other users may plug code into, it's @@ -856,7 +856,7 @@ callable: See also :ref:`using_introspection`. -Python 3 Compatibility +Python 3 compatibility ~~~~~~~~~~~~~~~~~~~~~~ Pyramid and most of its add-ons are Python 3 compatible. If you develop a @@ -871,11 +871,11 @@ Every release of Pyramid has 100% statement coverage via unit and integration tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the ``instrumental`` tool available on PyPI. It is automatically tested by the -Jenkins tool on Python 2.6, Python 2.7, Python 3.2 and PyPy after each commit -to its GitHub repository. Official Pyramid add-ons are held to a similar -testing standard. We still find bugs in Pyramid and its official add-ons, -but we've noticed we find a lot more of them while working on other projects -that don't have a good testing regime. +Jenkins tool on Python 2.6, Python 2.7, Python 3.2, Python 3.3, Python 3.4, +PyPy, and PyPy3 after each commit to its GitHub repository. Official Pyramid +add-ons are held to a similar testing standard. We still find bugs in Pyramid +and its official add-ons, but we've noticed we find a lot more of them while +working on other projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ @@ -883,15 +883,15 @@ Support ~~~~~~~ It's our goal that no Pyramid question go unanswered. Whether you ask a -question on IRC, on the Pylons-discuss maillist, or on StackOverflow, you're -likely to get a reasonably prompt response. We don't tolerate "support +question on IRC, on the Pylons-discuss mailing list, or on StackOverflow, +you're likely to get a reasonably prompt response. We don't tolerate "support trolls" or other people who seem to get their rocks off by berating fellow users in our various official support channels. We try to keep it well-lit and new-user-friendly. Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at -http://groups.google.com/group/pylons-discuss/ . +http://groups.google.com/group/pylons-discuss/. Documentation ~~~~~~~~~~~~~ @@ -900,12 +900,12 @@ It's a constant struggle, but we try to maintain a balance between completeness and new-user-friendliness in the official narrative Pyramid documentation (concrete suggestions for improvement are always appreciated, by the way). We also maintain a "cookbook" of recipes, which are usually -demonstrations of common integration scenarios, too specific to add to the +demonstrations of common integration scenarios too specific to add to the official narrative docs. In any case, the Pyramid documentation is comprehensive. -Example: The rest of this documentation and the cookbook at -http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/ . +Example: The Pyramid Cookbook at +http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/. .. index:: single: Pylons Project @@ -934,25 +934,26 @@ in July of 2008. At the end of 2010, we changed the name of as :app:`Pyramid` in November of that year. :app:`Pyramid` was inspired by :term:`Zope`, :term:`Pylons` (version -1.0) and :term:`Django`. As a result, :app:`Pyramid` borrows several +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 :app:`Pyramid` trace their origins back to :term:`Zope`. -Like Zope applications, :app:`Pyramid` applications can be easily extended: -if you obey certain constraints, the application you produce can be reused, +Like 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 :app:`Pyramid` were pioneered first in Zope. 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, :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 -with a set of conventions for calling those views. You are free to -use third-party components that fit your needs in your applications. +:term:`Routes` system used by :term:`Pylons` version 1.0. Like Pylons version +1.0, :app:`Pyramid` is mostly policy-free. It makes no assertions about which +database you should use. Pyramid no longer has built-in templating facilities +as of version 1.5a2, but instead officially supports bindings for templating +languages, including Chameleon, Jinja2, and Mako. In essence, it only +supplies a mechanism to map URLs to :term:`view` code, along with a set of +conventions for calling those views. You are free to use third-party +components that fit your needs in your applications. The concept of :term:`view` is used by :app:`Pyramid` mostly as it would be by Django. :app:`Pyramid` has a documentation culture more like Django's @@ -967,15 +968,15 @@ declarations are used for this purpose. Out of the box, Pyramid supports imperative and decorator-based configuration; :term:`ZCML` may be used via an add-on package named ``pyramid_zcml``. -Also unlike :term:`Zope` and unlike other "full-stack" frameworks such +Also unlike :term:`Zope` and other "full-stack" frameworks such 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`; :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. -:app:`Pyramid` makes no such assumption; it allows you to use a -relational database but doesn't encourage or discourage the decision. +:app:`Pyramid` makes no such assumption, allowing you to use a +relational database, and neither encouraging nor discouraging the decision. Other Python web frameworks advertise themselves as members of a class of web frameworks named `model-view-controller @@ -987,7 +988,7 @@ frameworks, :app:`Pyramid` also generally fits into this class. The :app:`Pyramid` authors believe that the MVC pattern just doesn't really fit the web very well. In a :app:`Pyramid` application, there is a - resource tree, which represents the site structure, and views, which tend + resource tree which represents the site structure, and views which tend to present the data stored in the resource tree and a user-defined "domain model". However, no facility provided *by the framework* actually necessarily maps to the concept of a "controller" or "model". So if you -- cgit v1.2.3 From ca00fbd88aaa42af89d9243c4475ff1ccd08b187 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 8 Oct 2015 01:03:31 -0700 Subject: rewrapping, rst heading underlines, minor grammar --- docs/narr/introduction.rst | 657 ++++++++++++++++++++++----------------------- 1 file changed, 322 insertions(+), 335 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 2d3cd23e9..7906dd85d 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -7,7 +7,7 @@ single: framework :app:`Pyramid` Introduction -============================== +=========================== :app:`Pyramid` is a general, open source, Python web application development *framework*. Its primary goal is to make it easier for a Python developer to @@ -15,40 +15,39 @@ create web applications. .. sidebar:: Frameworks vs. Libraries - A *framework* differs from a *library* in one very important way: - library code is always *called* by code that you write, while a - framework always *calls* code that you write. Using a set of - libraries to create an application is usually easier than using a - framework initially, because you can choose to cede control to - library code you have not authored very selectively. But when you - use a framework, you are required to cede a greater portion of - control to code you have not authored: code that resides in the - framework itself. You needn't use a framework at all to create a - web application using Python. A rich set of libraries already - exists for the platform. In practice, however, using a framework - to create an application is often more practical than rolling your - own via a set of libraries if the framework provides a set of - facilities that fits your application requirements. + A *framework* differs from a *library* in one very important way: library + code is always *called* by code that you write, while a framework always + *calls* code that you write. Using a set of libraries to create an + application is usually easier than using a framework initially, because you + can choose to cede control to library code you have not authored very + selectively. But when you use a framework, you are required to cede a + greater portion of control to code you have not authored: code that resides + in the framework itself. You needn't use a framework at all to create a web + application using Python. A rich set of libraries already exists for the + platform. In practice, however, using a framework to create an application + is often more practical than rolling your own via a set of libraries if the + framework provides a set of facilities that fits your application + requirements. Pyramid attempts to follow these design and engineering principles: Simplicity :app:`Pyramid` takes a *"pay only for what you eat"* approach. You can get - results even if you have only a partial understanding of :app:`Pyramid`. - It doesn’t force you to use any particular technology to produce an - application, and we try to keep the core set of concepts that you need to - understand to a minimum. + results even if you have only a partial understanding of :app:`Pyramid`. It + doesn't force you to use any particular technology to produce an application, + and we try to keep the core set of concepts that you need to understand to a + minimum. Minimalism - :app:`Pyramid` tries to solve only the fundamental problems of creating - a web application: the mapping of URLs to code, templating, security and - serving static assets. We consider these to be the core activities that are - common to nearly all web applications. + :app:`Pyramid` tries to solve only the fundamental problems of creating a web + application: the mapping of URLs to code, templating, security, and serving + static assets. We consider these to be the core activities that are common to + nearly all web applications. Documentation - Pyramid's minimalism means that it is easier for us to maintain complete - and up-to-date documentation. It is our goal that no aspect of Pyramid - is undocumented. + Pyramid's minimalism means that it is easier for us to maintain complete and + up-to-date documentation. It is our goal that no aspect of Pyramid is + undocumented. Speed :app:`Pyramid` is designed to provide noticeably fast execution for common @@ -56,12 +55,12 @@ Speed Reliability :app:`Pyramid` is developed conservatively and tested exhaustively. Where - Pyramid source code is concerned, our motto is: "If it ain’t tested, it’s + Pyramid source code is concerned, our motto is: "If it ain't tested, it's broke". Openness - As with Python, the Pyramid software is distributed under a `permissive - open source license `_. + As with Python, the Pyramid software is distributed under a `permissive open + source license `_. .. _what_makes_pyramid_unique: @@ -69,55 +68,53 @@ What makes Pyramid unique ------------------------- Understandably, people don't usually want to hear about squishy engineering -principles; they want to hear about concrete stuff that solves their -problems. With that in mind, what would make someone want to use Pyramid -instead of one of the many other web frameworks available today? What makes -Pyramid unique? - -This is a hard question to answer, because there are lots of excellent -choices, and it's actually quite hard to make a wrong choice, particularly in -the Python web framework market. But one reasonable answer is this: you can -write very small applications in Pyramid without needing to know a lot. -"What?", you say. "That can't possibly be a unique feature. Lots of other web -frameworks let you do that!" Well, you're right. But unlike many other -systems, you can also write very large applications in Pyramid if you learn a -little more about it. Pyramid will allow you to become productive quickly, -and will grow with you. It won't hold you back when your application is small, -and it won't get in your way when your application becomes large. "Well -that's fine," you say. "Lots of other frameworks let me write large apps, -too." Absolutely. But other Python web frameworks don't seamlessly let you -do both. They seem to fall into two non-overlapping categories: frameworks -for "small apps" and frameworks for "big apps". The "small app" frameworks -typically sacrifice "big app" features, and vice versa. +principles; they want to hear about concrete stuff that solves their problems. +With that in mind, what would make someone want to use Pyramid instead of one +of the many other web frameworks available today? What makes Pyramid unique? + +This is a hard question to answer because there are lots of excellent choices, +and it's actually quite hard to make a wrong choice, particularly in the Python +web framework market. But one reasonable answer is this: you can write very +small applications in Pyramid without needing to know a lot. "What?" you say. +"That can't possibly be a unique feature. Lots of other web frameworks let you +do that!" Well, you're right. But unlike many other systems, you can also +write very large applications in Pyramid if you learn a little more about it. +Pyramid will allow you to become productive quickly, and will grow with you. It +won't hold you back when your application is small, and it won't get in your +way when your application becomes large. "Well that's fine," you say. "Lots of +other frameworks let me write large apps, too." Absolutely. But other Python +web frameworks don't seamlessly let you do both. They seem to fall into two +non-overlapping categories: frameworks for "small apps" and frameworks for "big +apps". The "small app" frameworks typically sacrifice "big app" features, and +vice versa. We don't think it's a universally reasonable suggestion to write "small apps" in a "small framework" and "big apps" in a "big framework". You can't really -know to what size every application will eventually grow. We don't really -want to have to rewrite a previously small application in another framework -when it gets "too big". We believe the current binary distinction between -frameworks for small and large applications is just false. A well-designed -framework should be able to be good at both. Pyramid strives to be that kind -of framework. - -To this end, Pyramid provides a set of features that, combined, are unique +know to what size every application will eventually grow. We don't really want +to have to rewrite a previously small application in another framework when it +gets "too big". We believe the current binary distinction between frameworks +for small and large applications is just false. A well-designed framework +should be able to be good at both. Pyramid strives to be that kind of +framework. + +To this end, Pyramid provides a set of features that combined are unique amongst Python web frameworks. Lots of other frameworks contain some combination of these features. Pyramid of course actually stole many of them -from those other frameworks. But Pyramid is the only one that has all of -them in one place, documented appropriately, and useful *à la carte* without +from those other frameworks. But Pyramid is the only one that has all of them +in one place, documented appropriately, and useful *à la carte* without necessarily paying for the entire banquet. These are detailed below. Single-file applications ~~~~~~~~~~~~~~~~~~~~~~~~ -You can write a Pyramid application that lives entirely in one Python file, -not unlike existing Python microframeworks. This is beneficial for one-off -prototyping, bug reproduction, and very small applications. These -applications are easy to understand because all the information about the -application lives in a single place, and you can deploy them without needing -to understand much about Python distributions and packaging. Pyramid isn't -really marketed as a microframework, but it allows you to do almost -everything that frameworks that are marketed as micro offer in very similar -ways. +You can write a Pyramid application that lives entirely in one Python file, not +unlike existing Python microframeworks. This is beneficial for one-off +prototyping, bug reproduction, and very small applications. These applications +are easy to understand because all the information about the application lives +in a single place, and you can deploy them without needing to understand much +about Python distributions and packaging. Pyramid isn't really marketed as a +microframework, but it allows you to do almost everything that frameworks that +are marketed as "micro" offer in very similar ways. .. literalinclude:: helloworld.py @@ -142,26 +139,25 @@ decorators to localize the configuration. For example: def fred_view(request): return Response('fred') -However, unlike some other systems, using decorators for Pyramid -configuration does not make your application difficult to extend, test, or -reuse. The :class:`~pyramid.view.view_config` decorator, for example, does -not actually *change* the input or output of the function it decorates, so -testing it is a "WYSIWYG" operation. You don't need to understand the -framework to test your own code. You just behave as if the decorator is not -there. You can also instruct Pyramid to ignore some decorators, or use -completely imperative configuration instead of decorators to add views. -Pyramid decorators are inert instead of eager. You detect and activate them -with a :term:`scan`. +However, unlike some other systems, using decorators for Pyramid configuration +does not make your application difficult to extend, test, or reuse. The +:class:`~pyramid.view.view_config` decorator, for example, does not actually +*change* the input or output of the function it decorates, so testing it is a +"WYSIWYG" operation. You don't need to understand the framework to test your +own code. You just behave as if the decorator is not there. You can also +instruct Pyramid to ignore some decorators, or use completely imperative +configuration instead of decorators to add views. Pyramid decorators are inert +instead of eager. You detect and activate them with a :term:`scan`. Example: :ref:`mapping_views_using_a_decorator_section`. URL generation ~~~~~~~~~~~~~~ -Pyramid is capable of generating URLs for resources, routes, and static -assets. Its URL generation APIs are easy to use and flexible. If you use -Pyramid's various APIs for generating URLs, you can change your configuration -around arbitrarily without fear of breaking a link on one of your web pages. +Pyramid is capable of generating URLs for resources, routes, and static assets. +Its URL generation APIs are easy to use and flexible. If you use Pyramid's +various APIs for generating URLs, you can change your configuration around +arbitrarily without fear of breaking a link on one of your web pages. Example: :ref:`generating_route_urls`. @@ -169,12 +165,12 @@ Static file serving ~~~~~~~~~~~~~~~~~~~ Pyramid is perfectly willing to serve static files itself. It won't make you -use some external web server to do that. You can even serve more than one -set of static files in a single Pyramid web application (e.g. ``/static`` and -``/static2``). You can optionally place your files on an external web -server and ask Pyramid to help you generate URLs to those files. This let's -you use Pyramid's internal file serving while doing development, and a faster -static file server in production, without changing any code. +use some external web server to do that. You can even serve more than one set +of static files in a single Pyramid web application (e.g., ``/static`` and +``/static2``). You can optionally place your files on an external web server +and ask Pyramid to help you generate URLs to those files. This let's you use +Pyramid's internal file serving while doing development, and a faster static +file server in production, without changing any code. Example: :ref:`static_assets_section`. @@ -189,10 +185,10 @@ code. Plain old ``print()`` calls used for debugging can display to a console. Pyramid's debug toolbar comes activated when you use a Pyramid scaffold to render a project. This toolbar overlays your application in the browser, and allows you access to framework data, such as the routes configured, the last -renderings performed, the current set of packages installed, SQLAlchemy -queries run, logging data, and various other facts. When an exception -occurs, you can use its interactive debugger to poke around right in your -browser to try to determine the cause of the exception. It's handy. +renderings performed, the current set of packages installed, SQLAlchemy queries +run, logging data, and various other facts. When an exception occurs, you can +use its interactive debugger to poke around right in your browser to try to +determine the cause of the exception. It's handy. Example: :ref:`debug_toolbar`. @@ -200,29 +196,29 @@ Debugging settings ~~~~~~~~~~~~~~~~~~ Pyramid has debugging settings that allow you to print Pyramid runtime -information to the console when things aren't behaving as you're expecting. -For example, you can turn on ``debug_notfound``, which prints an informative -message to the console every time a URL does not match any view. You can -turn on ``debug_authorization``, which lets you know why a view execution was +information to the console when things aren't behaving as you're expecting. For +example, you can turn on ``debug_notfound``, which prints an informative +message to the console every time a URL does not match any view. You can turn +on ``debug_authorization``, which lets you know why a view execution was allowed or denied by printing a message to the console. These features are useful for those WTF moments. There are also a number of commands that you can invoke within a Pyramid environment that allow you to introspect the configuration of your system. -``proutes`` shows all configured routes for an application in the order -they'll be evaluated for matching. ``pviews`` shows all configured views for -any given URL. These are also WTF-crushers in some circumstances. +``proutes`` shows all configured routes for an application in the order they'll +be evaluated for matching. ``pviews`` shows all configured views for any given +URL. These are also WTF-crushers in some circumstances. Examples: :ref:`debug_authorization_section` and :ref:`command_line_chapter`. Add-ons -~~~~~~~~ +~~~~~~~ Pyramid has an extensive set of add-ons held to the same quality standards as -the Pyramid core itself. Add-ons are packages which provide functionality -that the Pyramid core doesn't. Add-on packages already exist which let you -easily send email, let you use the Jinja2 templating system, let you use -XML-RPC or JSON-RPC, let you integrate with jQuery Mobile, etc. +the Pyramid core itself. Add-ons are packages which provide functionality that +the Pyramid core doesn't. Add-on packages already exist which let you easily +send email, let you use the Jinja2 templating system, let you use XML-RPC or +JSON-RPC, let you integrate with jQuery Mobile, etc. Examples: http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation @@ -230,16 +226,16 @@ http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documen Class-based and function-based views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid has a structured, unified concept of a :term:`view callable`. -View callables can be functions, methods of classes, or even instances. When -you add a new view callable, you can choose to make it a function or a method -of a class. In either case Pyramid treats it largely the same way. You can -change your mind later and move code between methods of classes and -functions. A collection of similar view callables can be attached to a -single class as methods, if that floats your boat, and they can share -initialization code as necessary. All kinds of views are easy to understand -and use, and operate similarly. There is no phony distinction between them. -They can be used for the same purposes. +Pyramid has a structured, unified concept of a :term:`view callable`. View +callables can be functions, methods of classes, or even instances. When you +add a new view callable, you can choose to make it a function or a method of a +class. In either case Pyramid treats it largely the same way. You can change +your mind later and move code between methods of classes and functions. A +collection of similar view callables can be attached to a single class as +methods, if that floats your boat, and they can share initialization code as +necessary. All kinds of views are easy to understand and use, and operate +similarly. There is no phony distinction between them. They can be used for +the same purposes. Here's a view callable defined as a function: @@ -282,22 +278,22 @@ Here's a few views defined as methods of a class instead: Asset specifications ~~~~~~~~~~~~~~~~~~~~ -Asset specifications are strings that contain both a Python package name and -a file or directory name, e.g., ``MyPackage:static/index.html``. Use of these -specifications is omnipresent in Pyramid. An asset specification can refer -to a template, a translation directory, or any other package-bound static +Asset specifications are strings that contain both a Python package name and a +file or directory name, e.g., ``MyPackage:static/index.html``. Use of these +specifications is omnipresent in Pyramid. An asset specification can refer to +a template, a translation directory, or any other package-bound static resource. This makes a system built on Pyramid extensible because you don't have to rely on globals ("*the* static directory") or lookup schemes ("*the* ordered set of template directories") to address your files. You can move files around as necessary, and include other packages that may not share your system's templates or static files without encountering conflicts. -Because asset specifications are used heavily in Pyramid, we've also provided -a way to allow users to override assets. Say you love a system that someone -else has created with Pyramid but you just need to change "that one template" -to make it all better. No need to fork the application. Just override the -asset specification for that template with your own inside a wrapper, and -you're good to go. +Because asset specifications are used heavily in Pyramid, we've also provided a +way to allow users to override assets. Say you love a system that someone else +has created with Pyramid but you just need to change "that one template" to +make it all better. No need to fork the application. Just override the asset +specification for that template with your own inside a wrapper, and you're good +to go. Examples: :ref:`asset_specifications` and :ref:`overriding_assets_section`. @@ -309,12 +305,11 @@ Templating systems such as Mako, Genshi, Chameleon, and Jinja2 can be treated as renderers. Renderer bindings for all of these templating systems already exist for use in Pyramid. But if you'd rather use another, it's not a big deal. Just copy the code from an existing renderer package, and plug in your -favorite templating system. You'll then be able to use that templating -system from within Pyramid just as you'd use one of the "built-in" templating -systems. +favorite templating system. You'll then be able to use that templating system +from within Pyramid just as you'd use one of the "built-in" templating systems. -Pyramid does not make you use a single templating system exclusively. You -can use multiple templating systems, even in the same project. +Pyramid does not make you use a single templating system exclusively. You can +use multiple templating systems, even in the same project. Example: :ref:`templates_used_directly`. @@ -322,12 +317,12 @@ Rendered views can return dictionaries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you use a :term:`renderer`, you don't have to return a special kind of -"webby" ``Response`` object from a view. Instead, you can return a -dictionary, and Pyramid will take care of converting that dictionary -to a Response using a template on your behalf. This makes the view easier to -test, because you don't have to parse HTML in your tests; instead just make an -assertion that the view returns "the right stuff" in the dictionary. You can -write "real" unit tests instead of functionally testing all of your views. +"webby" ``Response`` object from a view. Instead you can return a dictionary, +and Pyramid will take care of converting that dictionary to a Response using a +template on your behalf. This makes the view easier to test, because you don't +have to parse HTML in your tests. Instead just make an assertion that the view +returns "the right stuff" in the dictionary. You can write "real" unit tests +instead of functionally testing all of your views. .. index:: pair: renderer; explicitly calling @@ -363,7 +358,7 @@ be rendered to a response on your behalf. The string passed as ``renderer=`` above is an :term:`asset specification`. It is in the form ``packagename:directoryname/filename.ext``. In this case, it refers to the ``mytemplate.pt`` file in the ``templates`` directory within the ``myapp`` -Python package. Asset specifications are omnipresent in Pyramid: see +Python package. Asset specifications are omnipresent in Pyramid. See :ref:`intro_asset_specs` for more information. Example: :ref:`renderers_chapter`. @@ -372,9 +367,9 @@ Event system ~~~~~~~~~~~~ Pyramid emits *events* during its request processing lifecycle. You can -subscribe any number of listeners to these events. For example, to be -notified of a new request, you can subscribe to the ``NewRequest`` event. To -be notified that a template is about to be rendered, you can subscribe to the +subscribe any number of listeners to these events. For example, to be notified +of a new request, you can subscribe to the ``NewRequest`` event. To be +notified that a template is about to be rendered, you can subscribe to the ``BeforeRender`` event, and so forth. Using an event publishing system as a framework notification feature instead of hardcoded hook points tends to make systems based on that framework less brittle. @@ -382,9 +377,9 @@ systems based on that framework less brittle. You can also use Pyramid's event system to send your *own* events. For example, if you'd like to create a system that is itself a framework, and may want to notify subscribers that a document has just been indexed, you can -create your own event type (``DocumentIndexed`` perhaps) and send the event -via Pyramid. Users of this framework can then subscribe to your event like -they'd subscribe to the events that are normally sent by Pyramid itself. +create your own event type (``DocumentIndexed`` perhaps) and send the event via +Pyramid. Users of this framework can then subscribe to your event like they'd +subscribe to the events that are normally sent by Pyramid itself. Example: :ref:`events_chapter` and :ref:`event_types`. @@ -394,7 +389,7 @@ Built-in internationalization Pyramid ships with internationalization-related features in its core: localization, pluralization, and creating message catalogs from source files and templates. Pyramid allows for a plurality of message catalogs via the use -of translation domains: you can create a system that has its own translations +of translation domains. You can create a system that has its own translations without conflict with other translations in other domains. Example: :ref:`i18n_chapter`. @@ -402,9 +397,9 @@ Example: :ref:`i18n_chapter`. HTTP caching ~~~~~~~~~~~~ -Pyramid provides an easy way to associate views with HTTP caching policies. -You can just tell Pyramid to configure your view with an ``http_cache`` -statement, and it will take care of the rest:: +Pyramid provides an easy way to associate views with HTTP caching policies. You +can just tell Pyramid to configure your view with an ``http_cache`` statement, +and it will take care of the rest:: @view_config(http_cache=3600) # 60 minutes def myview(request): .... @@ -412,8 +407,8 @@ statement, and it will take care of the rest:: Pyramid will add appropriate ``Cache-Control`` and ``Expires`` headers to responses generated when this view is invoked. -See the :meth:`~pyramid.config.Configurator.add_view` method's -``http_cache`` documentation for more information. +See the :meth:`~pyramid.config.Configurator.add_view` method's ``http_cache`` +documentation for more information. Sessions ~~~~~~~~ @@ -422,9 +417,9 @@ Pyramid has built-in HTTP sessioning. This allows you to associate data with otherwise anonymous users between requests. Lots of systems do this. But Pyramid also allows you to plug in your own sessioning system by creating some code that adheres to a documented interface. Currently there is a binding -package for the third-party Redis sessioning system that does exactly this. -But if you have a specialized need (perhaps you want to store your session data -in MongoDB), you can. You can even switch between implementations without +package for the third-party Redis sessioning system that does exactly this. But +if you have a specialized need (perhaps you want to store your session data in +MongoDB), you can. You can even switch between implementations without changing your application code. Example: :ref:`sessions_chapter`. @@ -432,17 +427,16 @@ Example: :ref:`sessions_chapter`. Speed ~~~~~ -The Pyramid core is, as far as we can tell, at least marginally faster than -any other existing Python web framework. It has been engineered from the -ground up for speed. It only does as much work as absolutely necessary when -you ask it to get a job done. Extraneous function calls and suboptimal -algorithms in its core codepaths are avoided. It is feasible to get, for -example, between 3500 and 4000 requests per second from a simple Pyramid view -on commodity dual-core laptop hardware and an appropriate WSGI server -(mod_wsgi or gunicorn). In any case, performance statistics are largely -useless without requirements and goals, but if you need speed, Pyramid will -almost certainly never be your application's bottleneck; at least no more -than Python will be a bottleneck. +The Pyramid core is, as far as we can tell, at least marginally faster than any +other existing Python web framework. It has been engineered from the ground up +for speed. It only does as much work as absolutely necessary when you ask it +to get a job done. Extraneous function calls and suboptimal algorithms in its +core codepaths are avoided. It is feasible to get, for example, between 3500 +and 4000 requests per second from a simple Pyramid view on commodity dual-core +laptop hardware and an appropriate WSGI server (mod_wsgi or gunicorn). In any +case, performance statistics are largely useless without requirements and +goals, but if you need speed, Pyramid will almost certainly never be your +application's bottleneck; at least no more than Python will be a bottleneck. Example: http://blog.curiasolutions.com/pages/the-great-web-framework-shootout.html @@ -456,9 +450,9 @@ views, but they're only invoked when an exception "bubbles up" to Pyramid itself. For example, you might register an exception view for the :exc:`Exception` exception, which will catch *all* exceptions, and present a pretty "well, this is embarrassing" page. Or you might choose to register an -exception view for only specific kinds of application-specific exceptions, -such as an exception that happens when a file is not found, or an exception -that happens when an action cannot be performed because the user doesn't have +exception view for only specific kinds of application-specific exceptions, such +as an exception that happens when a file is not found, or an exception that +happens when an action cannot be performed because the user doesn't have permission to do something. In the former case, you can show a pretty "Not Found" page; in the latter case you might show a login form. @@ -468,61 +462,59 @@ No singletons ~~~~~~~~~~~~~ Pyramid is written in such a way that it requires your application to have -exactly zero "singleton" data structures. Or put another way, Pyramid -doesn't require you to construct any "mutable globals". Or put even a -different way, an import of a Pyramid application needn't have any -"import-time side effects". This is esoteric-sounding, but if you've ever -tried to cope with parameterizing a Django ``settings.py`` file for multiple -installations of the same application, or if you've ever needed to -monkey-patch some framework fixture so that it behaves properly for your use -case, or if you've ever wanted to deploy your system using an asynchronous -server, you'll end up appreciating this feature. It just won't be a problem. -You can even run multiple copies of a similar but not identically configured -Pyramid application within the same Python process. This is good for shared -hosting environments, where RAM is at a premium. +exactly zero "singleton" data structures. Or put another way, Pyramid doesn't +require you to construct any "mutable globals". Or put even another different +way, an import of a Pyramid application needn't have any "import-time side +effects". This is esoteric-sounding, but if you've ever tried to cope with +parameterizing a Django ``settings.py`` file for multiple installations of the +same application, or if you've ever needed to monkey-patch some framework +fixture so that it behaves properly for your use case, or if you've ever wanted +to deploy your system using an asynchronous server, you'll end up appreciating +this feature. It just won't be a problem. You can even run multiple copies of +a similar but not identically configured Pyramid application within the same +Python process. This is good for shared hosting environments, where RAM is at +a premium. View predicates and many views per route ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unlike many other systems, Pyramid allows you to associate more than one view -per route. For example, you can create a route with the pattern ``/items`` -and when the route is matched, you can shuffle off the request to one view if -the request method is GET, another view if the request method is POST, etc. -A system known as "view predicates" allows for this. Request method matching -is the most basic thing you can do with a view predicate. You can also -associate views with other request parameters such as the elements in the -query string, the Accept header, whether the request is an XHR request or -not, and lots of other things. This feature allows you to keep your -individual views clean. They won't need much conditional logic, so they'll -be easier to test. +per route. For example, you can create a route with the pattern ``/items`` and +when the route is matched, you can shuffle off the request to one view if the +request method is GET, another view if the request method is POST, etc. A +system known as "view predicates" allows for this. Request method matching is +the most basic thing you can do with a view predicate. You can also associate +views with other request parameters, such as the elements in the query string, +the Accept header, whether the request is an XHR request or not, and lots of +other things. This feature allows you to keep your individual views clean. +They won't need much conditional logic, so they'll be easier to test. Example: :ref:`view_configuration_parameters`. Transaction management ~~~~~~~~~~~~~~~~~~~~~~ -Pyramid's :term:`scaffold` system renders projects that include a -*transaction management* system, stolen from Zope. When you use this -transaction management system, you cease being responsible for committing -your data anymore. Instead Pyramid takes care of committing: it commits at -the end of a request or aborts if there's an exception. Why is that a good -thing? Having a centralized place for transaction management is a great -thing. If instead of managing your transactions in a centralized place you -sprinkle ``session.commit`` calls in your application logic itself, you can -wind up in a bad place. Wherever you manually commit data to your database, -it's likely that some of your other code is going to run *after* your commit. -If that code goes on to do other important things after that commit, and an -error happens in the later code, you can easily wind up with inconsistent -data if you're not extremely careful. Some data will have been written to -the database that probably should not have. Having a centralized commit -point saves you from needing to think about this; it's great for lazy people -who also care about data integrity. Either the request completes -successfully, and all changes are committed, or it does not, and all changes -are aborted. - -Pyramid's transaction management system allows you to synchronize -commits between multiple databases. It also allows you to do things like -conditionally send email if a transaction commits, but otherwise keep quiet. +Pyramid's :term:`scaffold` system renders projects that include a *transaction +management* system, stolen from Zope. When you use this transaction management +system, you cease being responsible for committing your data anymore. Instead +Pyramid takes care of committing: it commits at the end of a request or aborts +if there's an exception. Why is that a good thing? Having a centralized place +for transaction management is a great thing. If, instead of managing your +transactions in a centralized place, you sprinkle ``session.commit`` calls in +your application logic itself, you can wind up in a bad place. Wherever you +manually commit data to your database, it's likely that some of your other code +is going to run *after* your commit. If that code goes on to do other important +things after that commit, and an error happens in the later code, you can +easily wind up with inconsistent data if you're not extremely careful. Some +data will have been written to the database that probably should not have. +Having a centralized commit point saves you from needing to think about this; +it's great for lazy people who also care about data integrity. Either the +request completes successfully, and all changes are committed, or it does not, +and all changes are aborted. + +Pyramid's transaction management system allows you to synchronize commits +between multiple databases. It also allows you to do things like conditionally +send email if a transaction commits, but otherwise keep quiet. Example: :ref:`bfg_sql_wiki_tutorial` (note the lack of commit statements anywhere in application code). @@ -530,18 +522,18 @@ anywhere in application code). Configuration conflict detection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -When a system is small, it's reasonably easy to keep it all in your head. -But when systems grow large, you may have hundreds or thousands of -configuration statements which add a view, add a route, and so forth. +When a system is small, it's reasonably easy to keep it all in your head. But +when systems grow large, you may have hundreds or thousands of configuration +statements which add a view, add a route, and so forth. -Pyramid's configuration system keeps track of your configuration statements. -If you accidentally add two that are identical, or Pyramid can't make -sense out of what it would mean to have both statements active at the same -time, it will complain loudly at startup time. It's not dumb though. It will -automatically resolve conflicting configuration statements on its own if you -use the configuration :meth:`~pyramid.config.Configurator.include` system. -"More local" statements are preferred over "less local" ones. This allows -you to intelligently factor large systems into smaller ones. +Pyramid's configuration system keeps track of your configuration statements. If +you accidentally add two that are identical, or Pyramid can't make sense out of +what it would mean to have both statements active at the same time, it will +complain loudly at startup time. It's not dumb though. It will automatically +resolve conflicting configuration statements on its own if you use the +configuration :meth:`~pyramid.config.Configurator.include` system. "More local" +statements are preferred over "less local" ones. This allows you to +intelligently factor large systems into smaller ones. Example: :ref:`conflict_detection`. @@ -551,17 +543,17 @@ Configuration extensibility Unlike other systems, Pyramid provides a structured "include" mechanism (see :meth:`~pyramid.config.Configurator.include`) that allows you to combine applications from multiple Python packages. All the configuration statements -that can be performed in your "main" Pyramid application can also be -performed by included packages, including the addition of views, routes, -subscribers, and even authentication and authorization policies. You can even -extend or override an existing application by including another application's -configuration in your own, overriding or adding new views and routes to -it. This has the potential to allow you to create a big application out of -many other smaller ones. For example, if you want to reuse an existing -application that already has a bunch of routes, you can just use the -``include`` statement with a ``route_prefix``. The new application will live -within your application at an URL prefix. It's not a big deal, and requires -little up-front engineering effort. +that can be performed in your "main" Pyramid application can also be performed +by included packages, including the addition of views, routes, subscribers, and +even authentication and authorization policies. You can even extend or override +an existing application by including another application's configuration in +your own, overriding or adding new views and routes to it. This has the +potential to allow you to create a big application out of many other smaller +ones. For example, if you want to reuse an existing application that already +has a bunch of routes, you can just use the ``include`` statement with a +``route_prefix``. The new application will live within your application at an +URL prefix. It's not a big deal, and requires little up-front engineering +effort. For example: @@ -584,16 +576,15 @@ For example: Flexible authentication and authorization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Pyramid includes a flexible, pluggable authentication and authorization -system. No matter where your user data is stored, or what scheme you'd like -to use to permit your users to access your data, you can use a predefined -Pyramid plugpoint to plug in your custom authentication and authorization -code. If you want to change these schemes later, you can just change it in -one place rather than everywhere in your code. It also ships with prebuilt -well-tested authentication and authorization schemes out of the box. But -what if you don't want to use Pyramid's built-in system? You don't have to. -You can just write your own bespoke security code as you would in any other -system. +Pyramid includes a flexible, pluggable authentication and authorization system. +No matter where your user data is stored, or what scheme you'd like to use to +permit your users to access your data, you can use a predefined Pyramid +plugpoint to plug in your custom authentication and authorization code. If you +want to change these schemes later, you can just change it in one place rather +than everywhere in your code. It also ships with prebuilt well-tested +authentication and authorization schemes out of the box. But what if you don't +want to use Pyramid's built-in system? You don't have to. You can just write +your own bespoke security code as you would in any other system. Example: :ref:`enabling_authorization_policy`. @@ -601,19 +592,19 @@ Traversal ~~~~~~~~~ :term:`Traversal` is a concept stolen from :term:`Zope`. It allows you to -create a tree of resources, each of which can be addressed by one or more -URLs. Each of those resources can have one or more *views* associated with -it. If your data isn't naturally treelike, or you're unwilling to create a -treelike representation of your data, you aren't going to find traversal -very useful. However, traversal is absolutely fantastic for sites that need -to be arbitrarily extensible: it's a lot easier to add a node to a tree than -it is to shoehorn a route into an ordered list of other routes, or to create -another entire instance of an application to service a department and glue -code to allow disparate apps to share data. It's a great fit for sites that -naturally lend themselves to changing departmental hierarchies, such as -content management systems and document management systems. Traversal also -lends itself well to systems that require very granular security ("Bob can -edit *this* document" as opposed to "Bob can edit documents"). +create a tree of resources, each of which can be addressed by one or more URLs. +Each of those resources can have one or more *views* associated with it. If +your data isn't naturally treelike, or you're unwilling to create a treelike +representation of your data, you aren't going to find traversal very useful. +However, traversal is absolutely fantastic for sites that need to be +arbitrarily extensible. It's a lot easier to add a node to a tree than it is to +shoehorn a route into an ordered list of other routes, or to create another +entire instance of an application to service a department and glue code to +allow disparate apps to share data. It's a great fit for sites that naturally +lend themselves to changing departmental hierarchies, such as content +management systems and document management systems. Traversal also lends +itself well to systems that require very granular security ("Bob can edit +*this* document" as opposed to "Bob can edit documents"). Examples: :ref:`hello_traversal_chapter` and :ref:`much_ado_about_traversal_chapter`. @@ -662,12 +653,11 @@ The former is "prettier", right? Out of the box, if you define the former view callable (the one that simply returns a string) in Pyramid, when it is executed, Pyramid will raise an -exception. This is because "explicit is better than implicit", in most -cases, and by default, Pyramid wants you to return a :term:`Response` object -from a view callable. This is because there's usually a heck of a lot more -to a response object than just its body. But if you're the kind of person -who values such aesthetics, we have an easy way to allow for this sort of -thing: +exception. This is because "explicit is better than implicit", in most cases, +and by default Pyramid wants you to return a :term:`Response` object from a +view callable. This is because there's usually a heck of a lot more to a +response object than just its body. But if you're the kind of person who +values such aesthetics, we have an easy way to allow for this sort of thing: .. code-block:: python :linenos: @@ -733,9 +723,9 @@ Once this is done, both of these view callables will work: def anotherview(request): return (403, 'text/plain', "Forbidden") -Pyramid defaults to explicit behavior, because it's the most generally -useful, but provides hooks that allow you to adapt the framework to localized -aesthetic desires. +Pyramid defaults to explicit behavior, because it's the most generally useful, +but provides hooks that allow you to adapt the framework to localized aesthetic +desires. .. seealso:: @@ -744,9 +734,9 @@ aesthetic desires. "Global" response object ~~~~~~~~~~~~~~~~~~~~~~~~ -"Constructing these response objects in my view callables is such a chore! -And I'm way too lazy to register a response adapter, as per the prior -section," you say. Fine. Be that way: +"Constructing these response objects in my view callables is such a chore! And +I'm way too lazy to register a response adapter, as per the prior section," you +say. Fine. Be that way: .. code-block:: python :linenos: @@ -765,13 +755,13 @@ Automating repetitive configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Does Pyramid's configurator allow you to do something, but you're a little -adventurous and just want it a little less verbose? Or you'd like to offer -up some handy configuration feature to other Pyramid users without requiring -that we change Pyramid? You can extend Pyramid's :term:`Configurator` with -your own directives. For example, let's say you find yourself calling +adventurous and just want it a little less verbose? Or you'd like to offer up +some handy configuration feature to other Pyramid users without requiring that +we change Pyramid? You can extend Pyramid's :term:`Configurator` with your own +directives. For example, let's say you find yourself calling :meth:`pyramid.config.Configurator.add_view` repetitively. Usually you can -take the boring away by using existing shortcuts, but let's say that this is -a case where there is no such shortcut: +take the boring away by using existing shortcuts, but let's say that this is a +case where there is no such shortcut: .. code-block:: python :linenos: @@ -817,7 +807,7 @@ the Configurator object: Your previously repetitive configuration lines have now morphed into one line. -You can share your configuration code with others this way too by packaging +You can share your configuration code with others this way, too, by packaging it up and calling :meth:`~pyramid.config.Configurator.add_directive` from within a function called when another user uses the :meth:`~pyramid.config.Configurator.include` method against your code. @@ -836,8 +826,7 @@ at the top of the screen based on an enumeration of views they registered. This is possible using Pyramid's :term:`introspector`. -Here's an example of using Pyramid's introspector from within a view -callable: +Here's an example of using Pyramid's introspector from within a view callable: .. code-block:: python :linenos: @@ -861,8 +850,8 @@ Python 3 compatibility Pyramid and most of its add-ons are Python 3 compatible. If you develop a Pyramid application today, you won't need to worry that five years from now -you'll be backwatered because there are language features you'd like to use -but your framework doesn't support newer Python versions. +you'll be backwatered because there are language features you'd like to use but +your framework doesn't support newer Python versions. Testing ~~~~~~~ @@ -886,8 +875,8 @@ It's our goal that no Pyramid question go unanswered. Whether you ask a question on IRC, on the Pylons-discuss mailing list, or on StackOverflow, you're likely to get a reasonably prompt response. We don't tolerate "support trolls" or other people who seem to get their rocks off by berating fellow -users in our various official support channels. We try to keep it well-lit -and new-user-friendly. +users in our various official support channels. We try to keep it well-lit and +new-user-friendly. Example: Visit irc\://freenode.net#pyramid (the ``#pyramid`` channel on irc.freenode.net in an IRC client) or the pylons-discuss maillist at @@ -896,13 +885,12 @@ http://groups.google.com/group/pylons-discuss/. Documentation ~~~~~~~~~~~~~ -It's a constant struggle, but we try to maintain a balance between -completeness and new-user-friendliness in the official narrative Pyramid -documentation (concrete suggestions for improvement are always appreciated, -by the way). We also maintain a "cookbook" of recipes, which are usually -demonstrations of common integration scenarios too specific to add to the -official narrative docs. In any case, the Pyramid documentation is -comprehensive. +It's a constant struggle, but we try to maintain a balance between completeness +and new-user-friendliness in the official narrative Pyramid documentation +(concrete suggestions for improvement are always appreciated, by the way). We +also maintain a "cookbook" of recipes, which are usually demonstrations of +common integration scenarios too specific to add to the official narrative +docs. In any case, the Pyramid documentation is comprehensive. Example: The Pyramid Cookbook at http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/. @@ -929,35 +917,34 @@ includes details about how :app:`Pyramid` relates to the Pylons Project. ------------------------------------------ The first release of Pyramid's predecessor (named :mod:`repoze.bfg`) was made -in July of 2008. At the end of 2010, we changed the name of -:mod:`repoze.bfg` to :app:`Pyramid`. It was merged into the Pylons project -as :app:`Pyramid` in November of that year. +in July of 2008. At the end of 2010, we changed the name of :mod:`repoze.bfg` +to :app:`Pyramid`. It was merged into the Pylons project as :app:`Pyramid` in +November of that year. -: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. +: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 :app:`Pyramid` trace their origins back to :term:`Zope`. -Like 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 :app:`Pyramid` were pioneered first in Zope. +Many features of :app:`Pyramid` trace their origins back to :term:`Zope`. Like +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 :app:`Pyramid` were pioneered first in Zope. 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, :app:`Pyramid` is mostly policy-free. It makes no assertions about which database you should use. Pyramid no longer has built-in templating facilities as of version 1.5a2, but instead officially supports bindings for templating -languages, including Chameleon, Jinja2, and Mako. In essence, it only -supplies a mechanism to map URLs to :term:`view` code, along with a set of -conventions for calling those views. You are free to use third-party -components that fit your needs in your applications. +languages, including Chameleon, Jinja2, and Mako. In essence, it only supplies +a mechanism to map URLs to :term:`view` code, along with a set of conventions +for calling those views. You are free to use third-party components that fit +your needs in your applications. -The concept of :term:`view` is used by :app:`Pyramid` mostly as it would be -by Django. :app:`Pyramid` has a documentation culture more like Django's -than like Zope's. +The concept of :term:`view` is used by :app:`Pyramid` mostly as it 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 :app:`Pyramid` application developer may use completely imperative code to perform common @@ -965,34 +952,34 @@ 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. Out of the box, Pyramid supports -imperative and decorator-based configuration; :term:`ZCML` may be used via an +imperative and decorator-based configuration. :term:`ZCML` may be used via an add-on package named ``pyramid_zcml``. -Also unlike :term:`Zope` and other "full-stack" frameworks such -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`; :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. -:app:`Pyramid` makes no such assumption, allowing you to use a -relational database, and neither encouraging nor discouraging the decision. - -Other Python web frameworks advertise themselves as members of a class -of web frameworks named `model-view-controller -`_ frameworks. -Insofar as this term has been claimed to represent a class of web -frameworks, :app:`Pyramid` also generally fits into this class. - -.. sidebar:: You Say :app:`Pyramid` is MVC, But Where's The Controller? - - The :app:`Pyramid` authors believe that the MVC pattern just doesn't - really fit the web very well. In a :app:`Pyramid` application, there is a - resource tree which represents the site structure, and views which tend - to present the data stored in the resource tree and a user-defined "domain - model". However, no facility provided *by the framework* actually - necessarily maps to the concept of a "controller" or "model". So if you - had to give it some acronym, I guess you'd say :app:`Pyramid` is actually - an "RV" framework rather than an "MVC" framework. "MVC", however, is - close enough as a general classification moniker for purposes of - comparison with other web frameworks. +Also unlike :term:`Zope` and other "full-stack" frameworks such 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`. :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. :app:`Pyramid` makes no such +assumption, allowing you to use a relational database, and neither encouraging +nor discouraging the decision. + +Other Python web frameworks advertise themselves as members of a class of web +frameworks named `model-view-controller +`_ frameworks. Insofar as +this term has been claimed to represent a class of web frameworks, +:app:`Pyramid` also generally fits into this class. + +.. sidebar:: You Say :app:`Pyramid` is MVC, but Where's the Controller? + + The :app:`Pyramid` authors believe that the MVC pattern just doesn't really + fit the web very well. In a :app:`Pyramid` application, there is a resource + tree which represents the site structure, and views which tend to present + the data stored in the resource tree and a user-defined "domain model". + However, no facility provided *by the framework* actually necessarily maps + to the concept of a "controller" or "model". So if you had to give it some + acronym, I guess you'd say :app:`Pyramid` is actually an "RV" framework + rather than an "MVC" framework. "MVC", however, is close enough as a + general classification moniker for purposes of comparison with other web + frameworks. -- cgit v1.2.3 From 384007c4e6e1c0c397b9c643c8c34bdf0ddf4b07 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 13 Jan 2016 13:24:26 -0800 Subject: update for python 3.5 --- docs/narr/introduction.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 7906dd85d..40f465b0a 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -861,10 +861,10 @@ tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the ``instrumental`` tool available on PyPI. It is automatically tested by the Jenkins tool on Python 2.6, Python 2.7, Python 3.2, Python 3.3, Python 3.4, -PyPy, and PyPy3 after each commit to its GitHub repository. Official Pyramid -add-ons are held to a similar testing standard. We still find bugs in Pyramid -and its official add-ons, but we've noticed we find a lot more of them while -working on other projects that don't have a good testing regime. +Python 3.5, PyPy, and PyPy3 after each commit to its GitHub repository. +Official Pyramid add-ons are held to a similar testing standard. We still find +bugs in Pyramid and its official add-ons, but we've noticed we find a lot more +of them while working on other projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ -- cgit v1.2.3 From 34515f33b3e391dd1c0c727bf5ef4af586b57889 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 14 Jan 2016 02:55:04 -0800 Subject: Rename Cookbook to Pyramid Community Cookbook - use .rst intersphinx labels for pages instead of broken URLs --- docs/narr/introduction.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 40f465b0a..422db557e 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -892,8 +892,7 @@ also maintain a "cookbook" of recipes, which are usually demonstrations of common integration scenarios too specific to add to the official narrative docs. In any case, the Pyramid documentation is comprehensive. -Example: The Pyramid Cookbook at -http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/. +Example: The :ref:`Pyramid Community Cookbook `. .. index:: single: Pylons Project -- cgit v1.2.3 From 4064028cadc63ed1aceb14e6c88827b88b12f839 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 20 Jan 2016 00:38:09 -0800 Subject: Update docs to reflect dropping Python 3.2 support --- docs/narr/introduction.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 422db557e..8db52dc21 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -860,11 +860,11 @@ Every release of Pyramid has 100% statement coverage via unit and integration tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the ``instrumental`` tool available on PyPI. It is automatically tested by the -Jenkins tool on Python 2.6, Python 2.7, Python 3.2, Python 3.3, Python 3.4, -Python 3.5, PyPy, and PyPy3 after each commit to its GitHub repository. -Official Pyramid add-ons are held to a similar testing standard. We still find -bugs in Pyramid and its official add-ons, but we've noticed we find a lot more -of them while working on other projects that don't have a good testing regime. +Jenkins tool on Python 2.6, Python 2.7, Python 3.3, Python 3.4, Python 3.5, +PyPy, and PyPy3 after each commit to its GitHub repository. Official Pyramid +add-ons are held to a similar testing standard. We still find bugs in Pyramid +and its official add-ons, but we've noticed we find a lot more of them while +working on other projects that don't have a good testing regime. Example: http://jenkins.pylonsproject.org/ -- cgit v1.2.3 From 682ca5afcf5cfa1d5f1802f5d95e2a9cf5622f3a Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Sun, 10 Apr 2016 20:55:24 -0600 Subject: Update introduction to testing It mentions that we use Jenkins, but our Travis is more open, and used for all commits, so add a reference to Travis as well. Also, remove Python 2.6 reference here. --- docs/narr/introduction.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'docs/narr/introduction.rst') diff --git a/docs/narr/introduction.rst b/docs/narr/introduction.rst index 8db52dc21..24c9f6b93 100644 --- a/docs/narr/introduction.rst +++ b/docs/narr/introduction.rst @@ -859,14 +859,15 @@ Testing Every release of Pyramid has 100% statement coverage via unit and integration tests, as measured by the ``coverage`` tool available on PyPI. It also has greater than 95% decision/condition coverage as measured by the -``instrumental`` tool available on PyPI. It is automatically tested by the -Jenkins tool on Python 2.6, Python 2.7, Python 3.3, Python 3.4, Python 3.5, -PyPy, and PyPy3 after each commit to its GitHub repository. Official Pyramid -add-ons are held to a similar testing standard. We still find bugs in Pyramid -and its official add-ons, but we've noticed we find a lot more of them while -working on other projects that don't have a good testing regime. - -Example: http://jenkins.pylonsproject.org/ +``instrumental`` tool available on PyPI. It is automatically tested by Travis, +and Jenkins on Python 2.7, Python 3.3, Python 3.4, Python 3.5, PyPy, and PyPy3 +after each commit to its GitHub repository. Official Pyramid add-ons are held +to a similar testing standard. We still find bugs in Pyramid and its official +add-ons, but we've noticed we find a lot more of them while working on other +projects that don't have a good testing regime. + +Travis: https://travis-ci.org/Pylons/pyramid +Jenkins: http://jenkins.pylonsproject.org/job/pyramid/ Support ~~~~~~~ -- cgit v1.2.3