diff options
| author | Chris McDonough <chrism@plope.com> | 2011-09-07 05:56:14 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-09-07 05:56:14 -0400 |
| commit | bb93cbdf16ac03e354569959663d053a68685fc5 (patch) | |
| tree | e96f57bd2c146a6bdd83b30a99f7b6ef63266dab /docs | |
| parent | 8d453f872c2695e7f1699bfa665ea34a437b1e41 (diff) | |
| download | pyramid-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.rst | 467 | ||||
| -rw-r--r-- | docs/narr/security.rst | 2 | ||||
| -rw-r--r-- | docs/narr/urldispatch.rst | 2 | ||||
| -rw-r--r-- | docs/narr/viewconfig.rst | 2 |
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 ++++++++++++++++++++++++++ |
