docs/getting_started/about_guide.rst
File was deleted docs/getting_started/index.rst
@@ -4,80 +4,25 @@ Welcome to Pyramid, the Python web framework that lets you start small and finish big. Whether you are new to Python web development or you're an experienced developer that wants a quick look at the major an experienced developer wanting a quick look at the major features, this guide provides a convenient entry point with independent chapters for each topic. :doc:`quick_glance` =================== Python web development is a very big topic. Wouldn't it be great to have a quick overview, end-to-end, just to get oriented? This chapter shows "a little about a lot", full of short code snippets and links to deeper treatment of topics. Additionally, we showcase some facilities that make Pyramid unique for "applications with ambition." :doc:`about_guide` ================== Now that we have set the scene, we explain the purpose of this guide (and non-purpose), showing how it is organized. :doc:`scaffolds` About This Guide ================ Pyramid projects are organized using normal Python facilities for projects. Normal, though, is in the eye of the beholder. This chapter shows how to use scaffolds to automate the boilerplate and quickly start development of a new project. Evaluators want to jump right into a particular topic. This *Getting Started* guide is structured with chapter titles that focuses on a particular aspect of web development. Each chapter is autonomous and you don't have to follow from beginning to end. Topics: scaffolds, packaging, virtual environments By definition, each topic is covered at a high level. To make it easy to get to in-depth treatment, the chapters provide interlinking with the full treatment in the :ref:`html_narrative_documentation`. :doc:`configuration` ==================== :doc:`routes` ============= :doc:`views` ============ :doc:`templates` ================ :doc:`static_assets` ==================== :doc:`testing` ============== :doc:`forms` ============ :doc:`databases` ================ :doc:`security` =============== :doc:`json` =========== :doc:`sessions` =============== :doc:`internationalization` =========================== :doc:`special_views` ==================== :doc:`top_ten` ============== This guide is part of the official documentation. If you find a bug, you can report it using the same facilities as the described in the software's :ref:`support-and-development`. Contents ======== @@ -86,7 +31,6 @@ :maxdepth: 2 quick_glance about_guide scaffolds configuration routes docs/getting_started/quick_glance.rst
@@ -3,92 +3,141 @@ ============ Pyramid lets you start small and finish big. This :doc:`index` guide walks you through many of the key features. Let's put the emphasis on *start* by doing a quick tour through Pyramid. This *Quick Glance* is provides snippets instead of full examples. For working code, see the *Getting Started* chapters on each topic. walks you through many of Pyramid's key features. Let's put the emphasis on *start* by doing a quick tour through Pyramid, with snippets of code to illustrate major concepts. .. note:: Like the rest of Getting Started, we're using Python 3 in our samples. You can too, or you can use Python 2.7. our samples. Pyramid was one of the first (October 2011) web frameworks to fully support Python 3. You can use Python 3 as well for this guide, but you can also use Python 2.7. Setup ===== Python Setup ============ This is just a "quick glance", so we won't kill ourselves showing installation details. The guides fully cover each topic, including setup. In a nutshell: First things first: we need our Python environment in ship-shape. Pyramid encourages standard Python development practices (virtual environments, packaging tools, etc.) so let's get our working area in place. For Python 3.3: .. code-block:: bash $ pyvenv-3.3 env33 $ source env33/bin/activate $ curl -O http://python-distribute.org/distribute_setup.py $ python3.3 ./distribute_setup.py $ rm distribute* $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python $ easy_install-3.3 pip $ pip-3.3 install pyramid We use Python 3.3's builtin virtual environment tool ``pyvenv`` to make an isolated Python. It is so isolated, we don't have package installation tools! After setting those up and cleaning up, we install Pyramid into our virtual environment. We make a :term:`virtualenv` then activate it. We then get Python packaging tools installed so we can use the popular ``pip`` tool for installing packages. Normal first steps for any Python project. .. note:: Pyramid Installation ==================== Note the use of ``3.3`` on many of the commands, as a way to emphasize in this document which versions of the commands we are using. This is optional. We now have a standard starting point for Python. Getting Pyramid installed is easy: .. code-block:: bash $ pip install pyramid The Smallest ============ Our virtual environment now has the Pyramid software available to its Python. Hello World =========== Microframeworks have shown that learning starts best from a very small first step. Here's a tiny application in Pyramid: .. literalinclude:: quick_glance/app1.py .. literalinclude:: quick_glance/hello_world/app.py :linenos: This simple example is easy to run. Save this as ``app.py`` and run it: .. code-block:: bash $ python3 ./app.py $ python ./app.py Finally, open `http://localhost:8081/ <http://localhost:8081/>`_ in a Next, open `http://localhost:6543/ <http://localhost:6543/>`_ in a browser and you will see the ``Hello World!`` message. At a high level, we wrote a Python module, which when executed, started an HTTP server. This HTTP server ran a WSGI application with one "view". This view handled the ``http://localhost:8081/`` URL. New to Python web programming? If so, some lines in module merit explanation: More specifically: #. *Line 10*. ``if __name__ == '__main__':`` is Python's way of saying "Start here when running from the command line". #. We imported an HTTP server (``make_server``), a configuration system (``Configurator``), and a way to send HTTP responses (``Response``). #. *Lines 11-13*. Use Pyramid's :term:`configurator` to connect :term:`view` code to particular URL :term:`route`. #. We made a ``hello_world`` function that returned a ``Response``. #. *Lines 6-7*. Implement the view code that generates the :term:`response`. #. Our ``main`` function started the configuration, added a "route", and then mapped that route to a "view". #. *Lines 14-16*. Publish a :term:`WSGI` app using an HTTP server. #. To finish, we then made a WSGI app and served it. ``if __name__ == '__main__':`` is a standard Python technique to execute code when it is run from the command line instead of imported into another module. Handling Web Requests With webob ================================ .. note:: Developing for the web means processing web requests. As this is a critical part of a web application, web developers need a robust, mature set of software for web requests. The configuration of the route and the view are split. Other systems let you bundle those together. Pyramid makes you do the extra step, but for a reason: this lets you control the ordering. More on this later. Pyramid has always fit nicely into the existing world of Python web development (virtual environments, packaging, scaffolding, first to embrace Python 3, etc.) For request handling, Pyramid turned to the well-regarded :term:`WebOb` Python library for request and response handling. In our example above, Pyramid hands ``hello_world`` a ``request`` that is :ref:`based on WebOb <webob_chapter>`. Using Decorators and Matchdicts =============================== Let's see some features of requests and responses in action: .. literalinclude:: quick_glance/requests/app.py :pyobject: hello_world Views ===== In the example above, the ``hello_world`` function is a "view" (or more specifically, a :term:`view callable`. Views are the primary way to accept web requests and return responses. So far the view, its registration with the configuration, and the route to map it to a URL are all in the same Python module as the WSGI application launching. Let's move the views out to their own ``views .py`` module and change the ``app.py`` to scan that module looking for decorators that setup the views. First, our revised ``app.py``: .. literalinclude:: quick_glance/views/app.py :linenos: We added some more routes, but we also removed the view code. Our views, and their registrations (via decorators) are now in a module ``views.py`` which is scanned via: .. code-block:: python config.scan('views') Our ``views.py`` is now more self-contained: .. literalinclude:: quick_glance/views/views.py :linenos: - Raise exception, redirect - Change header - request object - "callable" Routing With Decorators and Matchdicts ====================================== Let's repeat the smallest step, but make it a little more functional and elegant by adding: @@ -101,20 +150,27 @@ Let's make update our ``app.py`` module: .. literalinclude:: quick_glance/app2.py .. literalinclude:: quick_glance/routing/app.py :linenos: When you run ``python3 ./app.py`` and visit a URL such as ``http://localhost:8081/hello/amy``, the response includes ``amy`` in When you run ``python ./app.py`` and visit a URL such as ``http://localhost:6543/hello/amy``, the response includes ``amy`` in the HTML. This module, while small, starts to show how many Pyramid applications are composed: #. We use a decorator around the view, to put the configuration closer to the code. #. *Line 7*. Pyramid's configuration supports :term:`imperative configuration`, such as the ``config.add_view`` in the previous example. You can also use :term:`declarative configuration`, in which a Python :term:`decorator` is placed on the line above the view. #. We tell the ``Configurator`` to go look for decorators. #. *Line 14*. When setting up the route, mark off a section of the URL to be data available to the view's :term:`matchdict`. #. *Line 15*. Tell the configurator to go look for decorators. Templates ========= @@ -139,7 +195,7 @@ .. code-block:: python @view_config(route_name='hello', renderer="app3.jinja2") @view_config(route_name='hello', renderer="hello_world.jinja2") def hello_world(request): return dict(name=request.matchdict['name']) @@ -170,7 +226,7 @@ config.add_static_view(name='static', path='static') This tells our WSGI application to map requests under ``http://localhost:8081/static/`` to files and directories inside a ``http://localhost:6543/static/`` to files and directories inside a ``static`` directory alongside our Python module. Next, make a directory ``static`` and place ``app.css`` inside: @@ -309,7 +365,7 @@ .. code-block:: bash $ cd hello_world $ python3.3 ./setup.py develop $ python ./setup.py develop What did we get? A top-level directory ``hello_world`` that includes some packaging files and a subdirectory ``hello_world`` that has @@ -444,7 +500,7 @@ .. code-block:: bash $ python3.3 ./setup.py develop $ python ./setup.py develop The Python package was now installed into our environment but we haven't told our web app to use it. We can do so imperatively in code: @@ -489,7 +545,7 @@ ) We changed ``setup.py`` which means we need to re-run ``python3.3 ./setup.py develop``. We can now run all our tests: ``python ./setup.py develop``. We can now run all our tests: .. code-block:: bash @@ -626,7 +682,7 @@ $ pcreate --scaffold alchemy hello_sqlalchemy $ cd hello_sqlalchemy $ python3.3 setup.py develop $ python setup.py develop We now have a working sample SQLAlchemy application with all dependencies installed. The sample project provides a console script to @@ -714,8 +770,6 @@ Notes - Change 8081 -> 6543 - See also, interlinking, teasers or "3 Extras" at the end of each section, links to a downloadable version of the Python module @@ -733,4 +787,4 @@ - Explain and link to WSGI, Python Packages - Richer routing - Richer routing docs/getting_started/quick_glance/hello_world/app.pycopy from docs/getting_started/quick_glance/app1.py copy to docs/getting_started/quick_glance/hello_world/app.py
File was copied from docs/getting_started/quick_glance/app1.py @@ -12,5 +12,5 @@ config.add_route('hello', '/') config.add_view(hello_world, route_name='hello') app = config.make_wsgi_app() server = make_server('0.0.0.0', 8081, app) server = make_server('0.0.0.0', 6543, app) server.serve_forever() docs/getting_started/quick_glance/jinja2/app.py
File was renamed from docs/getting_started/quick_glance/app3.py @@ -15,5 +15,5 @@ config.include('pyramid_jinja2') config.scan() app = config.make_wsgi_app() server = make_server('0.0.0.0', 8081, app) server = make_server('0.0.0.0', 6543, app) server.serve_forever() docs/getting_started/quick_glance/jinja2/hello_world.jinja2
docs/getting_started/quick_glance/json/app.py
File was renamed from docs/getting_started/quick_glance/app5.py @@ -22,5 +22,5 @@ config.include('pyramid_jinja2') config.scan() app = config.make_wsgi_app() server = make_server('0.0.0.0', 8081, app) server = make_server('0.0.0.0', 6543, app) server.serve_forever() docs/getting_started/quick_glance/package/CHANGES.txt
docs/getting_started/quick_glance/package/MANIFEST.in
docs/getting_started/quick_glance/package/README.txt
docs/getting_started/quick_glance/package/development.ini
docs/getting_started/quick_glance/package/hello_world/__init__.py
docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.moBinary files differ
docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po
docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.moBinary files differ
docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po
docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot
docs/getting_started/quick_glance/package/hello_world/models.py
docs/getting_started/quick_glance/package/hello_world/static/favicon.icodocs/getting_started/quick_glance/package/hello_world/static/logo.pngdocs/getting_started/quick_glance/package/hello_world/static/pylons.css
docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2
docs/getting_started/quick_glance/package/hello_world/tests.py
docs/getting_started/quick_glance/package/hello_world/views.py
docs/getting_started/quick_glance/package/message-extraction.ini
docs/getting_started/quick_glance/package/setup.cfg
docs/getting_started/quick_glance/package/setup.py
docs/getting_started/quick_glance/requests/app.py
File was renamed from docs/getting_started/quick_glance/app1.py @@ -12,5 +12,5 @@ config.add_route('hello', '/') config.add_view(hello_world, route_name='hello') app = config.make_wsgi_app() server = make_server('0.0.0.0', 8081, app) server = make_server('0.0.0.0', 6543, app) server.serve_forever() docs/getting_started/quick_glance/routing/app.py
File was renamed from docs/getting_started/quick_glance/app2.py @@ -14,5 +14,5 @@ config.add_route('hello', '/hello/{name}') config.scan() app = config.make_wsgi_app() server = make_server('0.0.0.0', 8081, app) server = make_server('0.0.0.0', 6543, app) server.serve_forever() docs/getting_started/quick_glance/view_classes/app.py
File was renamed from docs/getting_started/quick_glance/app6.py @@ -26,5 +26,5 @@ config.include('pyramid_jinja2') config.scan() app = config.make_wsgi_app() server = make_server('0.0.0.0', 8081, app) server = make_server('0.0.0.0', 6543, app) server.serve_forever() docs/getting_started/quick_glance/views/app.py
New file @@ -0,0 +1,10 @@ from wsgiref.simple_server import make_server from pyramid.config import Configurator if __name__ == '__main__': config = Configurator() config.add_route('hello', '/hello/{name}') config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) server.serve_forever() docs/getting_started/quick_glance/views/views.py
New file @@ -0,0 +1,7 @@ from pyramid.response import Response from pyramid.view import view_config @view_config(route_name='hello') def hello_world(request): return Response('<h1>Hello %(name)s!</h1>' % request.matchdict) docs/getting_started/scaffolds.rst
@@ -1,3 +1,10 @@ ==================================== Starting New Projects With Scaffolds ==================================== ==================================== Pyramid projects are organized using normal Python facilities for projects. Normal, though, is in the eye of the beholder. This chapter shows how to use scaffolds to automate the boilerplate and quickly start development of a new project. Topics: scaffolds, packaging, virtual environments docs/getting_started/static_assets/app.py
File was renamed from docs/getting_started/quick_glance/app4.py @@ -15,5 +15,5 @@ config.include('pyramid_jinja2') config.scan() app = config.make_wsgi_app() server = make_server('0.0.0.0', 8081, app) server = make_server('0.0.0.0', 6543, app) server.serve_forever() docs/getting_started/static_assets/hello_world.jinja2
docs/index.rst
@@ -48,10 +48,30 @@ Getting Started =============== Quick tour of major facilities in Pyramid, including a :doc:`getting_started/quick_glance` high-level overview. .. toctree:: :maxdepth: 2 :maxdepth: 1 getting_started/index getting_started/quick_glance getting_started/scaffolds getting_started/configuration getting_started/routes getting_started/views getting_started/templates getting_started/static_assets getting_started/testing getting_started/forms getting_started/databases getting_started/security getting_started/json getting_started/sessions getting_started/internationalization getting_started/special_views getting_started/top_ten .. _html_narrative_documentation: @@ -192,6 +212,8 @@ tagging, commenting, and file uploads. See the `KARL site <http://karlproject.org>`_ for download and installation details. .. _support-and-development: Support and Development =======================