summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-09-07 05:56:14 -0400
committerChris McDonough <chrism@plope.com>2011-09-07 05:56:14 -0400
commitbb93cbdf16ac03e354569959663d053a68685fc5 (patch)
treee96f57bd2c146a6bdd83b30a99f7b6ef63266dab /docs
parent8d453f872c2695e7f1699bfa665ea34a437b1e41 (diff)
downloadpyramid-bb93cbdf16ac03e354569959663d053a68685fc5.tar.gz
pyramid-bb93cbdf16ac03e354569959663d053a68685fc5.tar.bz2
pyramid-bb93cbdf16ac03e354569959663d053a68685fc5.zip
add squishy whats-unique section to introduction
Diffstat (limited to 'docs')
-rw-r--r--docs/narr/introduction.rst467
-rw-r--r--docs/narr/security.rst2
-rw-r--r--docs/narr/urldispatch.rst2
-rw-r--r--docs/narr/viewconfig.rst2
4 files changed, 470 insertions, 3 deletions
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 <http://repoze.org/license.html>`_.
+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
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index 8d30a76a7..5a18ca851 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -60,6 +60,8 @@ policies.
.. index::
single: authorization policy
+.. _enabling_authorization_policy:
+
Enabling an Authorization Policy
--------------------------------
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index 0ec440f4d..52f6115eb 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -590,6 +590,8 @@ Or provide the literal string ``/`` as the pattern:
single: generating route URLs
single: route URLs
+.. _generating_route_urls:
+
Generating Route URLs
---------------------
diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst
index 26cca2ad1..af5d7f242 100644
--- a/docs/narr/viewconfig.rst
+++ b/docs/narr/viewconfig.rst
@@ -504,6 +504,8 @@ configuration`. However, they both do the same thing.
.. index::
single: view_config placement
+.. _view_config_placement:
+
``@view_config`` Placement
++++++++++++++++++++++++++