From 47eaa189e115936a86357380accd8d472e4d9a6c Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 11 Jun 2013 14:54:58 -0400 Subject: About half of the first pass is done. --- docs/getting_started/about_guide.rst | 14 + docs/getting_started/configuration.rst | 4 + docs/getting_started/databases.rst | 4 + docs/getting_started/forms.rst | 3 + docs/getting_started/index.rst | 104 ++++ docs/getting_started/internationalization.rst | 3 + docs/getting_started/json.rst | 4 + docs/getting_started/quick_glance.rst | 539 +++++++++++++++++++++ docs/getting_started/quick_glance/app1.py | 16 + docs/getting_started/quick_glance/app2.py | 18 + docs/getting_started/quick_glance/app3.jinja2 | 9 + docs/getting_started/quick_glance/app3.py | 19 + docs/getting_started/quick_glance/app4.jinja2 | 10 + docs/getting_started/quick_glance/app4.py | 19 + docs/getting_started/quick_glance/app5.py | 26 + docs/getting_started/quick_glance/app6.py | 30 ++ .../quick_glance/hello_world/CHANGES.txt | 4 + .../quick_glance/hello_world/MANIFEST.in | 2 + .../quick_glance/hello_world/README.txt | 4 + .../quick_glance/hello_world/development.ini | 52 ++ .../hello_world/hello_world/__init__.py | 23 + .../locale/de/LC_MESSAGES/hello_world.mo | Bin 0 -> 460 bytes .../locale/de/LC_MESSAGES/hello_world.po | 21 + .../locale/fr/LC_MESSAGES/hello_world.mo | Bin 0 -> 461 bytes .../locale/fr/LC_MESSAGES/hello_world.po | 21 + .../hello_world/hello_world/locale/hello_world.pot | 21 + .../quick_glance/hello_world/hello_world/models.py | 8 + .../hello_world/hello_world/static/favicon.ico | Bin 0 -> 1406 bytes .../hello_world/hello_world/static/logo.png | Bin 0 -> 6641 bytes .../hello_world/hello_world/static/pylons.css | 73 +++ .../hello_world/templates/mytemplate.jinja2 | 87 ++++ .../quick_glance/hello_world/hello_world/tests.py | 21 + .../quick_glance/hello_world/hello_world/views.py | 6 + .../hello_world/message-extraction.ini | 3 + .../quick_glance/hello_world/setup.cfg | 28 ++ .../quick_glance/hello_world/setup.py | 39 ++ docs/getting_started/quick_glance/static/app.css | 4 + docs/getting_started/routes.rst | 3 + docs/getting_started/scaffolds.rst | 3 + docs/getting_started/security.rst | 3 + docs/getting_started/sessions.rst | 3 + docs/getting_started/special_views.rst | 3 + docs/getting_started/static_assets.rst | 4 + docs/getting_started/templates.rst | 4 + docs/getting_started/testing.rst | 4 + docs/getting_started/top_ten.rst | 30 ++ docs/getting_started/views.rst | 3 + docs/index.rst | 10 + docs/narr/project.rst | 2 + 49 files changed, 1311 insertions(+) create mode 100644 docs/getting_started/about_guide.rst create mode 100644 docs/getting_started/configuration.rst create mode 100644 docs/getting_started/databases.rst create mode 100644 docs/getting_started/forms.rst create mode 100644 docs/getting_started/index.rst create mode 100644 docs/getting_started/internationalization.rst create mode 100644 docs/getting_started/json.rst create mode 100644 docs/getting_started/quick_glance.rst create mode 100644 docs/getting_started/quick_glance/app1.py create mode 100644 docs/getting_started/quick_glance/app2.py create mode 100644 docs/getting_started/quick_glance/app3.jinja2 create mode 100644 docs/getting_started/quick_glance/app3.py create mode 100644 docs/getting_started/quick_glance/app4.jinja2 create mode 100644 docs/getting_started/quick_glance/app4.py create mode 100644 docs/getting_started/quick_glance/app5.py create mode 100644 docs/getting_started/quick_glance/app6.py create mode 100644 docs/getting_started/quick_glance/hello_world/CHANGES.txt create mode 100644 docs/getting_started/quick_glance/hello_world/MANIFEST.in create mode 100644 docs/getting_started/quick_glance/hello_world/README.txt create mode 100644 docs/getting_started/quick_glance/hello_world/development.ini create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/__init__.py create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.mo create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.po create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.mo create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.po create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/hello_world.pot create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/models.py create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/static/favicon.ico create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/static/logo.png create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/static/pylons.css create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/tests.py create mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/views.py create mode 100644 docs/getting_started/quick_glance/hello_world/message-extraction.ini create mode 100644 docs/getting_started/quick_glance/hello_world/setup.cfg create mode 100644 docs/getting_started/quick_glance/hello_world/setup.py create mode 100644 docs/getting_started/quick_glance/static/app.css create mode 100644 docs/getting_started/routes.rst create mode 100644 docs/getting_started/scaffolds.rst create mode 100644 docs/getting_started/security.rst create mode 100644 docs/getting_started/sessions.rst create mode 100644 docs/getting_started/special_views.rst create mode 100644 docs/getting_started/static_assets.rst create mode 100644 docs/getting_started/templates.rst create mode 100644 docs/getting_started/testing.rst create mode 100644 docs/getting_started/top_ten.rst create mode 100644 docs/getting_started/views.rst diff --git a/docs/getting_started/about_guide.rst b/docs/getting_started/about_guide.rst new file mode 100644 index 000000000..812b07457 --- /dev/null +++ b/docs/getting_started/about_guide.rst @@ -0,0 +1,14 @@ +================ +About This Guide +================ + + +- Chapter titles are meaningful + +- Each chapter is autonomous, no one-big-application here + +- Interlinking + +- Reporting bugs or ideas + +- SO for questions \ No newline at end of file diff --git a/docs/getting_started/configuration.rst b/docs/getting_started/configuration.rst new file mode 100644 index 000000000..30280c7e1 --- /dev/null +++ b/docs/getting_started/configuration.rst @@ -0,0 +1,4 @@ +============================================ +Managing Project Settings With Configuration +============================================ + diff --git a/docs/getting_started/databases.rst b/docs/getting_started/databases.rst new file mode 100644 index 000000000..f982643af --- /dev/null +++ b/docs/getting_started/databases.rst @@ -0,0 +1,4 @@ +========================= +Databases With SQLAlchemy +========================= + diff --git a/docs/getting_started/forms.rst b/docs/getting_started/forms.rst new file mode 100644 index 000000000..039bfbce4 --- /dev/null +++ b/docs/getting_started/forms.rst @@ -0,0 +1,3 @@ +================================ +Forms and Validation With Deform +================================ diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst new file mode 100644 index 000000000..6396a8e6c --- /dev/null +++ b/docs/getting_started/index.rst @@ -0,0 +1,104 @@ +============================ +Getting Started With Pyramid +============================ + +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 +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` +================ + +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 + +: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` +============== + +Contents +======== + +.. toctree:: + :maxdepth: 2 + + quick_glance + about_guide + scaffolds + configuration + routes + views + templates + static_assets + testing + forms + databases + security + json + sessions + internationalization + special_views + top_ten \ No newline at end of file diff --git a/docs/getting_started/internationalization.rst b/docs/getting_started/internationalization.rst new file mode 100644 index 000000000..cc93406b1 --- /dev/null +++ b/docs/getting_started/internationalization.rst @@ -0,0 +1,3 @@ +============================================= +Multiple Languages Using Internationalization +============================================= diff --git a/docs/getting_started/json.rst b/docs/getting_started/json.rst new file mode 100644 index 000000000..006b44fc3 --- /dev/null +++ b/docs/getting_started/json.rst @@ -0,0 +1,4 @@ +================================= +Modern Web Development Using JSON +================================= + diff --git a/docs/getting_started/quick_glance.rst b/docs/getting_started/quick_glance.rst new file mode 100644 index 000000000..13ae22ba5 --- /dev/null +++ b/docs/getting_started/quick_glance.rst @@ -0,0 +1,539 @@ +============ +Quick Glance +============ + +Pyramid lets you start small and finish big. The +: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 shorthand, snippet-oriented. It is not intended +as full example. Instead, the other chapters will provide complete +examples. + +.. 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. + +The Smallest +============ + +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 + +This simple example is easy to run. Save this as ``app.py`` and run it: + +.. code-block:: bash + + $ python3 ./app.py + +Finally, open `http://localhost:8081/ `_ 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. + +More specifically: + +#. We imported an HTTP server (``make_server``), a configuration system + (``Configurator``), and a way to send HTTP responses (``Response``). + +#. We made a ``hello_world`` function that returned a ``Response``. + +#. Our ``main`` function started the configuration, added a "route", + and then mapped that route to a "view". + +#. 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. + +.. note:: + + 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. + +Using Decorators and Matchdicts +=============================== + +Let's repeat the smallest step, but make it a little more functional +and elegant by adding: + +- Echo back a name sent in via the URL + +- The URL is below the top of the site + +- Use a decorator to register the view + +Let's make update our ``app.py`` module: + +.. literalinclude:: quick_glance/app2.py + :linenos: + +When you run ``python3 ./app.py`` and visit a URL such as +``http://localhost:8081/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. + +#. We tell the ``Configurator`` to go look for decorators. + +Templates +========= + +You usually won't embed an HTML string directly in Python, but instead, +will use a templating language. Pyramid comes bundled with Chameleon +and Mako, but Jinja2 is popular. Let's install it: + +.. code-block:: bash + + $ pip install pyramid_jinja2 + +With the package installed, we can include the template bindings into +our configuration: + +.. code-block:: python + + config.include('pyramid_jinja2') + +Our view changes. We only return Python data and let the ``renderer`` +argument tell Pyramid to pass the response through Jinja2: + +.. code-block:: python + + @view_config(route_name='hello', renderer="app3.jinja2") + def hello_world(request): + return dict(name=request.matchdict['name']) + +Our template is HTML-oriented with a little logic in the ``

``: + +.. code-block:: html + + + + + Quick Glance + + +

Hello {{ name }}!

+ + + +Static Assets +============= + +Of course the Web is more than just markup. You need static assets: +CSS, JS, and images. Let's point our web app at a directory where +Pyramid will serve some static assets. First, another call to the +``Configurator``: + +.. code-block:: python + + 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 +``static`` directory alongside our Python module. + +Next, make a directory ``static`` and place ``app.css`` inside: + +.. code-block:: css + + body { + margin: 2em; + font-family: sans-serif; + } + +All we need to do now is point to it in the ```` of our Jinja2 +template: + +.. code-block:: html + + + +Returning JSON +============== + +Modern web apps are more than rendered HTML. Dynamic pages now use +JavaScript update the UI in the browser by requesting server data as +JSON. + +Pyramid supports this with a JSON renderer: + +.. code-block:: python + + @view_config(route_name='hello_json', renderer='json') + def hello_json(request): + return [1, 2, 3] + +This wires up a view that returns some data through the JSON +"renderer", which calls Python's JSON support to serialize the data +into JSON, set the appropriate HTTP headers, and more. + +The view needs a route added to the ``Configurator``: + +.. code-block:: python + + config.add_route('hello_json', 'hello.json') + + +View Classes +============ + +Free-standing functions are the regular way to do views. Many times, +though, you have several views that are closely related. For example, +a document might have many different ways to look at it. + +For some people, grouping these together makes logical sense. A view +class lets you group views, sharing some state assignments, and +using helper functions as class methods. + +Let's re-organize our two views into methods on a view class: + +.. code-block:: python + + class HelloWorldViews: + def __init__(self, request): + self.request = request + + @view_config(route_name='hello', renderer='app4.jinja2') + def hello_world(self): + return dict(name=self.request.matchdict['name']) + + + @view_config(route_name='hello_json', renderer='json') + def hello_json(self): + return [1, 2, 3] + +Everything else remains the same. + +Quick Project Startup with Scaffolds +==================================== + +So far we have done all of our *Quick Glance* as a single Python file. +No Python packages, no structure. Most Pyramid projects, though, +aren't developed this way. + +To ease the process of getting started, Pyramid provides *scaffolds* +that generate sample projects. Not just Pyramid itself: add-ons such as +``pyramid_jinja2`` (or your own projects) can register there own +scaffolds. + +We use Pyramid's ``pcreate`` command to generate our starting point +from a scaffold. What does this command look like? + +.. code-block:: bash + + $ pcreate --help + Usage: pcreate [options] output_directory + + Render Pyramid scaffolding to an output directory + + Options: + -h, --help show this help message and exit + -s SCAFFOLD_NAME, --scaffold=SCAFFOLD_NAME + Add a scaffold to the create process (multiple -s args + accepted) + -t SCAFFOLD_NAME, --template=SCAFFOLD_NAME + A backwards compatibility alias for -s/--scaffold. + Add a scaffold to the create process (multiple -t args + accepted) + -l, --list List all available scaffold names + --list-templates A backwards compatibility alias for -l/--list. List + all available scaffold names. + --simulate Simulate but do no work + --overwrite Always overwrite + --interactive When a file would be overwritten, interrogate + +Let's see what our Pyramid install supports as starting-point scaffolds: + +.. code-block:: bash + + $ pcreate --list + Available scaffolds: + alchemy: Pyramid SQLAlchemy project using url dispatch + pyramid_jinja2_starter: pyramid jinja2 starter project + starter: Pyramid starter project + zodb: Pyramid ZODB project using traversal + +The ``pyramid_jinja2_starter`` looks interesting. From the parent +directory of where we want our Python package to be generated, +let's use that scaffold to make our project: + +.. code-block:: bash + + $ pcreate --scaffold pyramid_jinja2_starter hello_world + +After printing a bunch of lines about the files being generated, +we now have a Python package. As described in the *official +instructions*, we need to install this as a development package: + +.. code-block:: bash + + $ cd hello_world + $ python3.3 ./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 +sample files for our application: + +.. code-block:: bash + + $ ls + CHANGES.txt development.ini hello_world.egg-info + MANIFEST.in message-extraction.ini setup.cfg + README.txt hello_world setup.py + + $ ls hello_world + __init__.py locale static tests.py + __pycache__ models.py templates views.py + +We are moving in the direction of a full-featured Pyramid project, +with a proper setup for Python standards (packaging) and Pyramid +configuration. This includes a new way of running your application: + +.. code-block:: bash + + $ pserve development.ini + +With ``pserve``, your application isn't responsible for finding a WSGI +server and launching your WSGI app. Also, much of the wiring of your +application can be moved to a declarative ``.ini`` configuration file. + +In your browser, visit +`http://localhost:6543/ `_ and you'll see that +things look very different. In the next few sections we'll cover some +decisions made by this scaffold. + +Let's look at ``pserve`` and configuration in more depth. + +Application Running with ``pserve`` +=================================== + +When you install Pyramid, a small command program called ``pserve`` is +written to your ``bin`` directory. This program is an executable Python +module. It's very small, getting most of its brains via import. + +You can run ``pserve`` with ``--help`` to see some of its options. +Doing so reveals that you can ask ``pserve`` to watch your development +files and reload the server when they change: + +.. code-block:: bash + + $ pserve development.ini --reload + +By design, ``pserve`` itself isn't all that interesting. Instead, +its brains from your project's wiring, as expressed in the +configuration file you supply it. + +.. seealso:: See Also: :ref:`what_is_this_pserve_thing` + +Three Cool Things About ``pserve`` +---------------------------------- + +1. *Multiple .ini files*. You might have some settings in + development mode or some in production mode. Maybe you are writing an + add-on that needs to be wired-up by other people. + +2. *Choice of WSGI server*. ``pserve`` itself isn't a WSGI server. + Instead, it loads the server you want from the configuration file. + +3. *Friends of pserve*. With the ``pserve``/``.ini`` approach you + also get other commands that help during development: ``pshell``, + ``proutes``, ``pviews``, ``prequest``, etc. + +Configuration with ``.ini`` Files +================================= + +Earlier in *Quick Glance* we first met Pyramid's configuration system. +At that point we did all configuration in Python code, +aka *imperatively*. For example, the port number chosen for our HTTP +server was right there in Python code. Our scaffold has moved this +decision, and more, into *declarative* configuration in the +``development.ini`` file. + +Let's take a quick high-level look. First, the ``.ini`` file is divided +into sections: + +- ``[app:hello_world]`` configures our WSGI app + +- ``[pipeline:main]`` sets up our WSGI "pipeline" + +- ``[server:main]`` holds our WSGI server settings + +- Various sections afterwards configure our Python logging system + +Let's look at a few decisions made in this configuration: + +#. *Choice of web server*. The ``use = egg:pyramid#wsgiref`` tell + ``pserve`` to the ``wsgiref`` server that is wrapped in the Pyramid + package. + +#. *Port number*. ``port = 6543`` tells ``wsgiref`` to listen on port + 6543. + +#. *WSGI app*. What package has our WSGI application in it? + ``use = egg:hello_world`` in the app section tells the + configuration what application to load. + +#. *Easier development by automatic template reloading*. In development + mode, you shouldn't have to restart the server when editing a Jinja2 + template. ``reload_templates = true`` sets this policy, + which might be different in production. + +Additionally, the ``development.ini`` generated by this scaffold wired +up Python's standard logging. We'll now see in the console, for example, +a log on every request that comes in, as well traceback information. + +Easier Development with ``debugtoolbar`` +======================================== + +As we introduce the basics we also want to show how to be productive in +development and debugging. For example, we just discussed template +reloading and earlier we showed ``--reload`` for application reloading. + +``pyramid_debugtoolbar`` is a popular Pyramid add-on which makes +several tools available in your browser. Adding it to your project +illustrates several points about configuration. + +First, change your ``setup.py`` to say: + +.. code-block:: python + + requires=['pyramid>=1.0.2', 'pyramid_jinja2'] + +...and re-run your setup: + +.. code-block:: bash + + $ python3.3 ./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: + +.. code-block:: python + + config.include('pyramid_debugtoolbar') + +Instead, let's do it in configuration by modifying our +``development.ini`` instead: + +.. code-block:: ini + + [app:hello_world] + pyramid.includes = pyramid_debugtoolbar + +That is, add ``pyramid.includes = pyramid_debugtoolbar`` anywhere in the +``[app:hello_world]`` section. You'll now see an attractive (and +collapsible) menu in the right of your browser giving you introspective +access to debugging information. Even better, if your web application +generates an error, you will see a nice traceback on the screen. + +Unit Tests and ``nose`` +======================= + +Yikes! We got this far and we haven't yet discussed tests. Particularly +egregious, as Pyramid has had a deep commitment to full test coverage +since before it was released. + +Our ``pyramid_jinja2_starter`` scaffold generated a ``tests.py`` module +with one unit test in it. To run it, let's install the handy ``nose`` +test runner by editing ``setup.py``. While we're at it, we'll throw in +the ``coverage`` tool which yells at us for code that isn't tested: + +.. code-block:: python + + setup(name='hello_world', + # Some lines removed... + extras_require={ + 'testing': ['nose', 'coverage'], + } + ) + +We changed ``setup.py`` which means we need to re-run +``python3.3 ./setup.py develop``. We can now run all our tests: + +.. code-block:: bash + + $ nosetests + . + Name Stmts Miss Cover Missing + --------------------------------------------------- + hello_world 12 8 33% 11-23 + hello_world.models 5 1 80% 8 + hello_world.tests 14 0 100% + hello_world.views 4 0 100% + --------------------------------------------------- + TOTAL 35 9 74% + ---------------------------------------------------------------------- + Ran 1 test in 0.931s + + OK + +Our unit test passed. What did our test look like? + +.. code-block:: python + + import unittest + from pyramid import testing + + + class ViewTests(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from hello_world.views import my_view + + request = testing.DummyRequest() + response = my_view(request) + self.assertEqual(response['project'], 'hello_world') + +Pyramid supplies helpers for test writing, which we use in the +test setup and teardown. Our one test imports the view, +makes a dummy request, and sees if the view returns what we expected. + + + + - logging + + - resources, asset specs, tests, + +sessions, logging, special views +databases, forms, security + +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 + +- Read "pyramid for humans" and getting started as an attempt to kill + those + +- Do a better job at the "why" + +- Explain imperative vs. declarative configuration and link to "why + configuration" + +- For see also, point also to Getting Started sections + +- Debugging + +- Template reloading + +- Explain and link to WSGI, Python Packages \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app1.py b/docs/getting_started/quick_glance/app1.py new file mode 100644 index 000000000..cffe53ecf --- /dev/null +++ b/docs/getting_started/quick_glance/app1.py @@ -0,0 +1,16 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response + + +def hello_world(request): + return Response('

Hello World!

') + + +if __name__ == '__main__': + config = Configurator() + 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.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app2.py b/docs/getting_started/quick_glance/app2.py new file mode 100644 index 000000000..49ccd3be1 --- /dev/null +++ b/docs/getting_started/quick_glance/app2.py @@ -0,0 +1,18 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response +from pyramid.view import view_config + + +@view_config(route_name='hello') +def hello_world(request): + return Response('

Hello %(name)s!

' % request.matchdict) + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8081, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app3.jinja2 b/docs/getting_started/quick_glance/app3.jinja2 new file mode 100644 index 000000000..6d9f0cd5f --- /dev/null +++ b/docs/getting_started/quick_glance/app3.jinja2 @@ -0,0 +1,9 @@ + + + + Quick Glance + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app3.py b/docs/getting_started/quick_glance/app3.py new file mode 100644 index 000000000..549cb5f54 --- /dev/null +++ b/docs/getting_started/quick_glance/app3.py @@ -0,0 +1,19 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='app3.jinja2') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.include('pyramid_jinja2') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8081, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app4.jinja2 b/docs/getting_started/quick_glance/app4.jinja2 new file mode 100644 index 000000000..3d0f28c1f --- /dev/null +++ b/docs/getting_started/quick_glance/app4.jinja2 @@ -0,0 +1,10 @@ + + + + Quick Glance + + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app4.py b/docs/getting_started/quick_glance/app4.py new file mode 100644 index 000000000..245ed0b68 --- /dev/null +++ b/docs/getting_started/quick_glance/app4.py @@ -0,0 +1,19 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='app4.jinja2') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.add_static_view(name='static', path='static') + config.include('pyramid_jinja2') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8081, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app5.py b/docs/getting_started/quick_glance/app5.py new file mode 100644 index 000000000..245a0a5ae --- /dev/null +++ b/docs/getting_started/quick_glance/app5.py @@ -0,0 +1,26 @@ +from wsgiref.simple_server import make_server + +from pyramid.config import Configurator +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='app4.jinja2') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +@view_config(route_name='hello_json', renderer='json') +def hello_json(request): + return [1, 2, 3] + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.add_route('hello_json', 'hello.json') + config.add_static_view(name='static', path='static') + config.include('pyramid_jinja2') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8081, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app6.py b/docs/getting_started/quick_glance/app6.py new file mode 100644 index 000000000..155becc54 --- /dev/null +++ b/docs/getting_started/quick_glance/app6.py @@ -0,0 +1,30 @@ +from wsgiref.simple_server import make_server + +from pyramid.config import Configurator +from pyramid.view import view_config + + +class HelloWorldViews: + def __init__(self, request): + self.request = request + + @view_config(route_name='hello', renderer='app4.jinja2') + def hello_world(self): + return dict(name=self.request.matchdict['name']) + + + @view_config(route_name='hello_json', renderer='json') + def hello_json(self): + return [1, 2, 3] + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.add_route('hello_json', 'hello.json') + config.add_static_view(name='static', path='static') + config.include('pyramid_jinja2') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 8081, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/hello_world/CHANGES.txt b/docs/getting_started/quick_glance/hello_world/CHANGES.txt new file mode 100644 index 000000000..ffa255da8 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version diff --git a/docs/getting_started/quick_glance/hello_world/MANIFEST.in b/docs/getting_started/quick_glance/hello_world/MANIFEST.in new file mode 100644 index 000000000..18fbd855c --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/getting_started/quick_glance/hello_world/README.txt b/docs/getting_started/quick_glance/hello_world/README.txt new file mode 100644 index 000000000..63aaf6fbd --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/README.txt @@ -0,0 +1,4 @@ +hello_world README + + + diff --git a/docs/getting_started/quick_glance/hello_world/development.ini b/docs/getting_started/quick_glance/hello_world/development.ini new file mode 100644 index 000000000..9aa5f40cf --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/development.ini @@ -0,0 +1,52 @@ +[app:hello_world] +pyramid.includes = pyramid_debugtoolbar +use = egg:hello_world +reload_templates = true +debug_authorization = false +debug_notfound = false +debug_routematch = false +debug_templates = true +default_locale_name = en +jinja2.directories = hello_world:templates + + + +[pipeline:main] +pipeline = + hello_world + +[server:main] +use = egg:pyramid#wsgiref +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_hello_world] +level = DEBUG +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/__init__.py b/docs/getting_started/quick_glance/hello_world/hello_world/__init__.py new file mode 100644 index 000000000..9b5753c26 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/__init__.py @@ -0,0 +1,23 @@ +from pyramid.config import Configurator +from pyramid_jinja2 import renderer_factory +from hello_world.models import get_root + +def main(global_config, **settings): + """ This function returns a WSGI application. + + It is usually called by the PasteDeploy framework during + ``paster serve``. + """ + settings = dict(settings) + settings.setdefault('jinja2.i18n.domain', 'hello_world') + + config = Configurator(root_factory=get_root, settings=settings) + config.add_translation_dirs('locale/') + config.include('pyramid_jinja2') + + config.add_static_view('static', 'static') + config.add_view('hello_world.views.my_view', + context='hello_world.models.MyModel', + renderer="mytemplate.jinja2") + + return config.make_wsgi_app() diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.mo b/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.mo new file mode 100644 index 000000000..40bf0c271 Binary files /dev/null and b/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.mo differ diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.po b/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.po new file mode 100644 index 000000000..0df243dba --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.po @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "Hallo!" diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.mo b/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.mo new file mode 100644 index 000000000..4fc438bfe Binary files /dev/null and b/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.mo differ diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.po b/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.po new file mode 100644 index 000000000..dc0aae5d7 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.po @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "Bonjour!" diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/hello_world.pot b/docs/getting_started/quick_glance/hello_world/hello_world/locale/hello_world.pot new file mode 100644 index 000000000..9c9460cb2 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/locale/hello_world.pot @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "" diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/models.py b/docs/getting_started/quick_glance/hello_world/hello_world/models.py new file mode 100644 index 000000000..edd361c9c --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/models.py @@ -0,0 +1,8 @@ +class MyModel(object): + pass + +root = MyModel() + + +def get_root(request): + return root diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/static/favicon.ico b/docs/getting_started/quick_glance/hello_world/hello_world/static/favicon.ico new file mode 100644 index 000000000..71f837c9e Binary files /dev/null and b/docs/getting_started/quick_glance/hello_world/hello_world/static/favicon.ico differ diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/static/logo.png b/docs/getting_started/quick_glance/hello_world/hello_world/static/logo.png new file mode 100644 index 000000000..88f5d9865 Binary files /dev/null and b/docs/getting_started/quick_glance/hello_world/hello_world/static/logo.png differ diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/static/pylons.css b/docs/getting_started/quick_glance/hello_world/hello_world/static/pylons.css new file mode 100644 index 000000000..42e2e320e --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/static/pylons.css @@ -0,0 +1,73 @@ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ +vertical-align:baseline;background:transparent;} +body{line-height:1;} +ol,ul{list-style:none;} +blockquote,q{quotes:none;} +blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} +/* remember to define focus styles! */ +:focus{outline:0;} +/* remember to highlight inserts somehow! */ +ins{text-decoration:none;} +del{text-decoration:line-through;} +/* tables still need 'cellspacing="0"' in the markup */ +table{border-collapse:collapse;border-spacing:0;} +/* restyling */ +sub{vertical-align:sub;font-size:smaller;line-height:normal;} +sup{vertical-align:super;font-size:smaller;line-height:normal;} +/* lists */ +ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} +ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} +li{display:list-item;} +/* nested lists have no top/bottom margins */ +ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} +/* 2 deep unordered lists use a circle */ +ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} +/* 3 deep (or more) unordered lists use a square */ +ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} +.hidden{display:none;} +p{line-height:1.5em;} +h1{font-size:1.75em;/* 28px */ +line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;/* 24px */ +line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;/* 20px */ +line-height:1.7em;font-family:helvetica,verdana;} +h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} +html,body{width:100%;height:100%;} +body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} +a{color:#1b61d6;text-decoration:none;} +a:hover{color:#e88f00;text-decoration:underline;} +body h1, +body h2, +body h3, +body h4, +body h5, +body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} +#wrap {min-height: 100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} +#header{background-color:#e88f00;top:0;font-size:14px;} +#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} +.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +.wrapper{width:100%} +#top,#bottom{width:100%;} +#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} +#bottom{color:#222;background-color:#ffffff;overflow:auto;padding-bottom:80px;} +.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} +.top{padding-top:100px;} +.app-welcome{margin-top:25px;} +.app-name{color:#000000;font-weight:bold;} +.bottom{padding-top:50px;} +#left{width:325px;float:left;padding-right:25px;} +#right{width:325px;float:right;padding-left:25px;} +.align-left{text-align:left;} +.align-right{text-align:right;} +.align-center{text-align:center;} +ul.links{margin:0;padding:0;} +ul.links li{list-style-type:none;font-size:14px;} +form{border-style:none;} +fieldset{border-style:none;} +input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} +input[type=text]{} +input[type=submit]{background-color:#ddd;font-weight:bold;} +/*Opera Fix*/ +body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 b/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 new file mode 100644 index 000000000..a796c7273 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 @@ -0,0 +1,87 @@ + + + + The Pyramid Web Application Development Framework + + + + + + + + + + +
+ +
+
+ Logo +

+ Welcome to {{project}}, an application generated by
+ the Pyramid web application development framework. +

+
+
+
+
+

{% trans %}Hello!{% endtrans %}

+

Request performed with {{ request.locale_name }} locale.

+
+
+
+

Search Pyramid documentation

+
+ + +
+
+ +
+
+
+ + + diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/tests.py b/docs/getting_started/quick_glance/hello_world/hello_world/tests.py new file mode 100644 index 000000000..a81c29eb0 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/tests.py @@ -0,0 +1,21 @@ +import unittest +from pyramid import testing +from pyramid.i18n import TranslationStringFactory + +_ = TranslationStringFactory('hello_world') + + +class ViewTests(unittest.TestCase): + + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from hello_world.views import my_view + request = testing.DummyRequest() + response = my_view(request) + self.assertEqual(response['project'], 'hello_world') + diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/views.py b/docs/getting_started/quick_glance/hello_world/hello_world/views.py new file mode 100644 index 000000000..c271d45dd --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/hello_world/views.py @@ -0,0 +1,6 @@ +from pyramid.i18n import TranslationStringFactory + +_ = TranslationStringFactory('hello_world') + +def my_view(request): + return {'project':'hello_world'} diff --git a/docs/getting_started/quick_glance/hello_world/message-extraction.ini b/docs/getting_started/quick_glance/hello_world/message-extraction.ini new file mode 100644 index 000000000..0c3d54bc1 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/message-extraction.ini @@ -0,0 +1,3 @@ +[python: **.py] +[jinja2: **.jinja2] +encoding = utf-8 diff --git a/docs/getting_started/quick_glance/hello_world/setup.cfg b/docs/getting_started/quick_glance/hello_world/setup.cfg new file mode 100644 index 000000000..186e796fc --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/setup.cfg @@ -0,0 +1,28 @@ +[nosetests] +match = ^test +nocapture = 1 +cover-package = hello_world +with-coverage = 1 +cover-erase = 1 + +[compile_catalog] +directory = hello_world/locale +domain = hello_world +statistics = true + +[extract_messages] +add_comments = TRANSLATORS: +output_file = hello_world/locale/hello_world.pot +width = 80 +mapping_file = message-extraction.ini + +[init_catalog] +domain = hello_world +input_file = hello_world/locale/hello_world.pot +output_dir = hello_world/locale + +[update_catalog] +domain = hello_world +input_file = hello_world/locale/hello_world.pot +output_dir = hello_world/locale +previous = true diff --git a/docs/getting_started/quick_glance/hello_world/setup.py b/docs/getting_started/quick_glance/hello_world/setup.py new file mode 100644 index 000000000..6269accf1 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/setup.py @@ -0,0 +1,39 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +README = open(os.path.join(here, 'README.txt')).read() +CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + +requires = ['pyramid>=1.0.2', 'pyramid_jinja2', 'pyramid_debugtoolbar'] + +setup(name='hello_world', + version='0.0', + description='hello_world', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pylons", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + tests_require=requires, + test_suite="hello_world", + entry_points="""\ + [paste.app_factory] + main = hello_world:main + """, + paster_plugins=['pyramid'], + extras_require={ + 'testing': ['nose', ], + } +) \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static/app.css b/docs/getting_started/quick_glance/static/app.css new file mode 100644 index 000000000..f8acf3164 --- /dev/null +++ b/docs/getting_started/quick_glance/static/app.css @@ -0,0 +1,4 @@ +body { + margin: 2em; + font-family: sans-serif; +} \ No newline at end of file diff --git a/docs/getting_started/routes.rst b/docs/getting_started/routes.rst new file mode 100644 index 000000000..ec4fc988c --- /dev/null +++ b/docs/getting_started/routes.rst @@ -0,0 +1,3 @@ +=========================== +Designing URLs Using Routes +=========================== diff --git a/docs/getting_started/scaffolds.rst b/docs/getting_started/scaffolds.rst new file mode 100644 index 000000000..437291089 --- /dev/null +++ b/docs/getting_started/scaffolds.rst @@ -0,0 +1,3 @@ +==================================== +Starting New Projects With Scaffolds +==================================== \ No newline at end of file diff --git a/docs/getting_started/security.rst b/docs/getting_started/security.rst new file mode 100644 index 000000000..5ba1fb103 --- /dev/null +++ b/docs/getting_started/security.rst @@ -0,0 +1,3 @@ +============================================== +Security With Authentication and Authorization +============================================== diff --git a/docs/getting_started/sessions.rst b/docs/getting_started/sessions.rst new file mode 100644 index 000000000..02e51f9e3 --- /dev/null +++ b/docs/getting_started/sessions.rst @@ -0,0 +1,3 @@ +=============================== +Site Visitor Data With Sessions +=============================== diff --git a/docs/getting_started/special_views.rst b/docs/getting_started/special_views.rst new file mode 100644 index 000000000..c2b384bdb --- /dev/null +++ b/docs/getting_started/special_views.rst @@ -0,0 +1,3 @@ +========================================= +NotFound, Errors, and Other Special Views +========================================= diff --git a/docs/getting_started/static_assets.rst b/docs/getting_started/static_assets.rst new file mode 100644 index 000000000..b605260a7 --- /dev/null +++ b/docs/getting_started/static_assets.rst @@ -0,0 +1,4 @@ +====================================================== +Serving CSS, JavaScript, and Images With Static Assets +====================================================== + diff --git a/docs/getting_started/templates.rst b/docs/getting_started/templates.rst new file mode 100644 index 000000000..32cfea848 --- /dev/null +++ b/docs/getting_started/templates.rst @@ -0,0 +1,4 @@ +============================= +Rendering HTML With Templates +============================= + diff --git a/docs/getting_started/testing.rst b/docs/getting_started/testing.rst new file mode 100644 index 000000000..af2b335b7 --- /dev/null +++ b/docs/getting_started/testing.rst @@ -0,0 +1,4 @@ +================================================= +Coding For Quality With Unit and Functional Tests +================================================= + diff --git a/docs/getting_started/top_ten.rst b/docs/getting_started/top_ten.rst new file mode 100644 index 000000000..071f41d1c --- /dev/null +++ b/docs/getting_started/top_ten.rst @@ -0,0 +1,30 @@ +============================== +Top Killer Features In Pyramid +============================== + +"Making your own framework" + +- Transactions + +- Configuration + + - config.include + +- Advanced views and view predicates + +Custom views +============ + +- Corneice does this + +- Events + +- Ordered routes + +- Custom renderers + +- Tweens + +- Asset specifications + +- Traversal diff --git a/docs/getting_started/views.rst b/docs/getting_started/views.rst new file mode 100644 index 000000000..347d5aae7 --- /dev/null +++ b/docs/getting_started/views.rst @@ -0,0 +1,3 @@ +================================ +Handling Web Requests With Views +================================ diff --git a/docs/index.rst b/docs/index.rst index bc711f8ff..3c3adb9a6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -43,6 +43,16 @@ What's New whatsnew-1.1 whatsnew-1.0 +.. _html_getting_started: + +Getting Started +=============== + +.. toctree:: + :maxdepth: 2 + + getting_started/index + .. _html_narrative_documentation: Narrative documentation diff --git a/docs/narr/project.rst b/docs/narr/project.rst index 9d69a65a5..8cf67e104 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -992,6 +992,8 @@ prompt with a similar configuration as would be loaded if you were running your Pyramid application via ``pserve``. This can be a useful debugging tool. See :ref:`interactive_shell` for more details. +.. _what_is_this_pserve_thing: + What Is This ``pserve`` Thing ----------------------------- -- cgit v1.2.3 From 83fefbf3f92183d1d899c8449a03546dd3c022a3 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Sat, 3 Aug 2013 11:23:20 -0400 Subject: "Web Application Development Framework" -> "Web Framework". Yay. --- docs/conf.py | 10 +- docs/copyright.rst | 2 +- docs/getting_started/quick_glance.rst | 219 +++++++++++++++++++-- .../hello_world/templates/mytemplate.jinja2 | 6 +- docs/getting_started/top_ten.rst | 2 + docs/index.rst | 2 +- .../MyProject/myproject/templates/mytemplate.pt | 4 +- .../authorization/tutorial/templates/mytemplate.pt | 4 +- .../basiclayout/tutorial/templates/mytemplate.pt | 4 +- .../src/models/tutorial/templates/mytemplate.pt | 4 +- .../src/tests/tutorial/templates/mytemplate.pt | 4 +- .../src/views/tutorial/templates/mytemplate.pt | 4 +- .../authorization/tutorial/templates/mytemplate.pt | 4 +- .../basiclayout/tutorial/templates/mytemplate.pt | 4 +- .../src/models/tutorial/templates/mytemplate.pt | 4 +- .../src/tests/tutorial/templates/mytemplate.pt | 4 +- .../src/views/tutorial/templates/mytemplate.pt | 4 +- .../alchemy/+package+/templates/mytemplate.pt_tmpl | 4 +- .../starter/+package+/templates/mytemplate.pt_tmpl | 4 +- .../zodb/+package+/templates/mytemplate.pt | 4 +- .../+package+/templates/mytemplate.pt_tmpl | 4 +- setup.py | 2 +- 22 files changed, 251 insertions(+), 52 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 84b01a791..9b2f2f083 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -85,7 +85,7 @@ source_suffix = '.rst' master_doc = 'index' # General substitutions. -project = 'The Pyramid Web Application Development Framework' +project = 'The Pyramid Web Framework' thisyear = datetime.datetime.now().year copyright = '2008-%s, Agendaless Consulting' % thisyear @@ -179,7 +179,7 @@ html_theme_options = dict( # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -html_title = 'The Pyramid Web Application Development Framework v%s' % release +html_title = 'The Pyramid Web Framework v%s' % release # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = 'Home' @@ -251,7 +251,7 @@ latex_additional_files = ['_static/latex-note.png', '_static/latex-warning.png'] # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ ('latexindex', 'pyramid.tex', - 'The Pyramid Web Application Development Framework', + 'The Pyramid Web Framework', 'Chris McDonough', 'manual'), ] @@ -491,7 +491,7 @@ def resig(app, what, name, obj, options, signature, return_annotation): # -- Options for Epub output --------------------------------------------------- # Bibliographic Dublin Core info. -epub_title = 'The Pyramid Web Application Development Framework, Version %s' \ +epub_title = 'The Pyramid Web Framework, Version %s' \ % release epub_author = 'Chris McDonough' epub_publisher = 'Agendaless Consulting' @@ -509,7 +509,7 @@ epub_scheme = 'ISBN' epub_identifier = '0615445675' # A unique identification for the text. -epub_uid = 'The Pyramid Web Application Development Framework, Version %s' \ +epub_uid = 'The Pyramid Web Framework, Version %s' \ % release # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. diff --git a/docs/copyright.rst b/docs/copyright.rst index 8f3a5f5e7..980335827 100644 --- a/docs/copyright.rst +++ b/docs/copyright.rst @@ -1,7 +1,7 @@ Copyright, Trademarks, and Attributions ======================================= -*The Pyramid Web Application Development Framework, Version 1.1* +*The Pyramid Web Framework, Version 1.1* by Chris McDonough diff --git a/docs/getting_started/quick_glance.rst b/docs/getting_started/quick_glance.rst index 13ae22ba5..da65f2e51 100644 --- a/docs/getting_started/quick_glance.rst +++ b/docs/getting_started/quick_glance.rst @@ -2,20 +2,48 @@ Quick Glance ============ -Pyramid lets you start small and finish big. The -:doc:`index` guide +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 shorthand, snippet-oriented. It is not intended -as full example. Instead, the other chapters will provide complete -examples. +This *Quick Glance* is provides snippets instead of full examples. For +working code, see the *Getting Started* chapters on each topic. .. 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. +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: + +.. 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* + $ 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. + +.. note:: + + 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. + + + The Smallest ============ @@ -506,14 +534,183 @@ Pyramid supplies helpers for test writing, which we use in the test setup and teardown. Our one test imports the view, makes a dummy request, and sees if the view returns what we expected. +Logging +======= + +It's important to know what is going on inside our web application. +In development we might need to collect some output. In production, +we might need to detect situations when other people use the site. We +need *logging*. + +Fortunately Pyramid uses the normal Python approach to logging. The +scaffold generated, in your ``development.ini``, a number of lines that +configure the logging for you to some reasonable defaults. You then see +messages sent by Pyramid (for example, when a new request comes in.) + +Maybe you would like to log messages in your code? In your Python +module, import and setup the logging: + +.. code-block:: python + + import logging + log = logging.getLogger(__name__) + +You can now, in your code, log messages: + +.. code-block:: python + + log.debug('Some Message') +This will log ``Some Message`` at a ``debug`` log level, +to the application-configured logger in your ``development.ini``. What +controls that? These sections in the configuration file: + +.. code-block:: ini + + [loggers] + keys = root, hello_world + + [logger_hello_world] + level = DEBUG + handlers = + qualname = hello_world + +Our application, a package named ``hello_world``, is setup as a logger +and configured to log messages at a ``DEBUG`` or higher level. + +Sessions +======== + +When people use your web application, they frequently perform a task +that requires semi-permanent data to be saved. For example,a shopping +cart. These are frequently called *sessions*. + +Pyramid has basic built-in support for sessions, with add-ons such as +*Beaker* (or your own custom sessioning engine) that provide richer +session support. For the built-in session support, you first import +the "factory" which provides the sessioning: + +.. code-block:: python + + from pyramid.session import UnencryptedCookieSessionFactoryConfig + my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet') + +We tell the configuration system that this is the source of our +sessioning support when setting up the ``Configurator``: + +.. code-block:: python + + config = Configurator(session_factory = my_session_factory) + +This now lets us use the session in our application code: + +.. code-block:: python + + session = request.session + if 'abc' in session: + session['fred'] = 'yes' + +Databases +========= - - logging +Web applications mean data. Data means databases. Frequently SQL +databases. SQL Databases frequently mean an "ORM" +(object-relational mapper.) In Python, ORM usually leads to the +mega-quality *SQLAlchemy*, a Python package that greatly eases working +with databases. - - resources, asset specs, tests, +Pyramid and SQLAlchemy are great friends. That friendship includes a +scaffold! + +.. code-block:: bash + + $ pcreate --scaffold alchemy hello_sqlalchemy + $ cd hello_sqlalchemy + $ python3.3 setup.py develop + +We now have a working sample SQLAlchemy application with all +dependencies installed. The sample project provides a console script to +initialize a SQLite database with tables. Let's run it and then start +the application: + +.. code-block:: bash + + $ initialize_hello_sqlalchemy_db development.ini + $ pserve development.ini + +We can now visit our sample at +`http://localhost:6543/ `_. Some choices that +the scaffold helped us with: + +- A ``setup.py`` with appropriate dependencies + +- Connection strings and integration in our ``development.ini`` file + +- A console script which we ran above to initialize the database + +- The SQLAlchemy engine integrated into the ``Configurator`` on + application startup + +- Python modules for the SQLAlchemy models and the Pyramid views that + go with them + +- Some unit tests...yummy! + +As mentioned above, an ORM is software that eases the mapping of +database structures into a programming language. SQLAlchemy uses models +for this, and its scaffold generated a sample model: + +.. code-block:: python + + class MyModel(Base): + __tablename__ = 'models' + id = Column(Integer, primary_key=True) + name = Column(Text, unique=True) + value = Column(Integer) + + def __init__(self, name, value): + self.name = name + self.value = value + +The Python module also includes this: + +.. code-block:: python + + from zope.sqlalchemy import ZopeTransactionExtension + +The generated application includes the optional support for +``pyramid_tm``, a unique transaction monitor that integrates your +database transactions with your code for transparent rollback and commit. + +View code, which mediates the logic between web requests and the rest +of the system, can then easily get at the data: + +.. code-block:: python + + one = DBSession.query(MyModel).filter(MyModel.name == 'one').first() + + +Forms +===== + +Developers have lots of opinions about forms, and thus there are many +form libraries for Python. Pyramid doesn't directly bundle a form +library, but *Deform* is a popular choice. Let's see it in action. +First we install it: + +.. code-block:: bash + + $ pip-3.3 install deform + + + +Authentication +============== + + +Authorization +============= -sessions, logging, special views -databases, forms, security Notes @@ -534,6 +731,6 @@ Notes - Debugging -- Template reloading +- Explain and link to WSGI, Python Packages -- Explain and link to WSGI, Python Packages \ No newline at end of file +- Richer routing \ No newline at end of file diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 b/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 index a796c7273..998edfe12 100644 --- a/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 +++ b/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -21,14 +21,14 @@
Logo

Welcome to {{project}}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/getting_started/top_ten.rst b/docs/getting_started/top_ten.rst index 071f41d1c..a11d2898c 100644 --- a/docs/getting_started/top_ten.rst +++ b/docs/getting_started/top_ten.rst @@ -28,3 +28,5 @@ Custom views - Asset specifications - Traversal + +- Transactions \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 3c3adb9a6..4bbd2fd93 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,7 +1,7 @@ .. _index: ================================================= -The Pyramid Web Application Development Framework +The Pyramid Web Framework ================================================= :app:`Pyramid` is a small, fast, down-to-earth Python web application diff --git a/docs/narr/MyProject/myproject/templates/mytemplate.pt b/docs/narr/MyProject/myproject/templates/mytemplate.pt index 0bfac946e..0fccba624 100644 --- a/docs/narr/MyProject/myproject/templates/mytemplate.pt +++ b/docs/narr/MyProject/myproject/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt index e8672104d..13b41f823 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/authorization/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt index e8672104d..13b41f823 100644 --- a/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/basiclayout/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt index e8672104d..13b41f823 100644 --- a/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/models/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt index e8672104d..13b41f823 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/tests/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt index 84824f605..50102aa20 100644 --- a/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki/src/views/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt index 14b88d16a..cf3da2073 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt index ee9fdb7fa..ca4e0af26 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt index ee9fdb7fa..ca4e0af26 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/models/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt index 9c077568d..6c1ca924a 100644 --- a/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/tests/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt index ee9fdb7fa..ca4e0af26 100644 --- a/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/views/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl index 99b3fe31c..24651643c 100644 --- a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl +++ b/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl index 34706ec2f..c9a211935 100644 --- a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl +++ b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt index 200dac6d0..5a2ce2bd7 100644 --- a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt +++ b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl b/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl index 3cd9c66a4..856bc22e7 100644 --- a/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl +++ b/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

Welcome to ${project}, an application generated by
- the Pyramid web application development framework. + the Pyramid Web Framework.

diff --git a/setup.py b/setup.py index 4a3cecd98..0d3d296cb 100644 --- a/setup.py +++ b/setup.py @@ -71,7 +71,7 @@ testing_extras = tests_require + [ setup(name='pyramid', version='1.4', - description=('The Pyramid web application development framework, a ' + description=('The Pyramid Web Framework, a ' 'Pylons project'), long_description=README + '\n\n' + CHANGES, classifiers=[ -- cgit v1.2.3 From efcf8f1c8b1e1140a5e9d9bb6fea558150ae7c29 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Sat, 3 Aug 2013 11:34:05 -0400 Subject: Some more occurrences of "application framework". --- docs/authorintro.rst | 2 +- docs/index.rst | 4 ++-- docs/latexindex.rst | 2 +- docs/narr/templates.rst | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/authorintro.rst b/docs/authorintro.rst index f1a9d1484..1fc4c8513 100644 --- a/docs/authorintro.rst +++ b/docs/authorintro.rst @@ -2,7 +2,7 @@ Author Introduction ===================== -Welcome to "The :app:`Pyramid` Web Application Framework". In this +Welcome to "The :app:`Pyramid` Web Framework". In this introduction, I'll describe the audience for this book, I'll describe the book content, I'll provide some context regarding the genesis of :app:`Pyramid`, and I'll thank some important people. diff --git a/docs/index.rst b/docs/index.rst index 4bbd2fd93..09bbb5a9a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,8 +4,8 @@ The Pyramid Web Framework ================================================= -:app:`Pyramid` is a small, fast, down-to-earth Python web application -development framework. It is developed as part of the `Pylons Project +:app:`Pyramid` is a small, fast, down-to-earth Python web framework. It +is developed as part of the `Pylons Project `_. It is licensed under a `BSD-like license `_. diff --git a/docs/latexindex.rst b/docs/latexindex.rst index 6bb875f73..e2266d741 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -1,7 +1,7 @@ .. _latexindex: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -The :app:`Pyramid` Web Application Framework +The :app:`Pyramid` Web Framework @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ .. frontmatter:: diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index d4cf20b93..f1e1634b8 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -711,7 +711,7 @@ look like:

Welcome to ${project}, an application generated by the pyramid web application framework.

+ >pyramid web framework. -- cgit v1.2.3 From 2c0a464b31757cfacddecdaf5641aac94ce76744 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Aug 2013 02:22:32 -0700 Subject: Adding my stab at a "getting started". --- docs/getting_started/gettingstarted.rst | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docs/getting_started/gettingstarted.rst diff --git a/docs/getting_started/gettingstarted.rst b/docs/getting_started/gettingstarted.rst new file mode 100644 index 000000000..f340e3cc8 --- /dev/null +++ b/docs/getting_started/gettingstarted.rst @@ -0,0 +1,61 @@ +=============== +Getting Started +=============== + +What is Pyramid? +---------------- + +Pyramid is a web application development framework. Pyramid is lean, fast, stable, well-tested, and thoroughly documented. Pyramid is written in Python, and is open source software released under a `BSD-like license `_. + +Pyramid helps you "start small, finish big". You can create a simple web application using Pyramid with only basic knowledge. As you become more familiar with Pyramid, you'll find there is plenty of room to grow. Code you started with early on can be re-used in mature, large, powerful applications. + +Pyramid has dozens of features — URL generation, authentication and authorization, [one or two more?] — just like any other web application framework. Several features are unique and make Pyramid stand out from the crowd. + +* Traversal +* Python 3 compatibility +* Tweens +* Debug Toolbar + +Installation Guide +------------------ +The Installation Guide describes how to install everything needed to get started with Pyramid. It also offers practical advice on working with projects. Whether you're new to Pyramid, Python, programming, or web application development, the Installation Guide will help you get your first Pyramid application up and running and deployed into production. + +Developer Guide +--------------- +The Developer Guide describes Pyramid in depth. Formerly called "narrative documentation", the Developer Guide uses technical terms more familiar to the seasoned web application developer. Beginners may be challenged, to put it mildly, but it's a challenge worth accepting. Developers who have already installed Pyramid, worked through a few tutorials, and are ready to write their own applications will find that this guide offers a comprehensive understanding of Pyramid. + +API Guide +--------- +The API Guide is a comprehensive reference for every public application programming interface (API) exposed by Pyramid. The API Guide lists each item, its arguments, definition, narrative description, its inner workings, and the values and objects it returns in great detail. + +Tutorials and Screencasts +------------------------- +There are several tutorials and screencasts that give beginners and new-comers to Pyramid hands-on experience with writing Pyramid applications. + +http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/ + +Add-ons +------- +Pyramid is extensible through add-ons. + +http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation + +Support +------- +https://github.com/Pylons/pylonsrtd/blob/master/index.rst#support + +Pylons-discuss Google group/mail list + +'#pyramid' IRC channel on irc.freenode.net + +issue tracker on GitHub http://github.com/Pylons/pyramid/issues + +Contributing +------------ +Guidelines for contributing to Pyramid are available at the following URL. + +https://github.com/Pylons/pylonsrtd/tree/master/community + +Community +--------- +http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/ -- cgit v1.2.3 From c94613370685da566a8b955202fb9676f56e8d80 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 5 Aug 2013 02:37:48 -0700 Subject: add line breaks --- docs/getting_started/gettingstarted.rst | 37 ++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/docs/getting_started/gettingstarted.rst b/docs/getting_started/gettingstarted.rst index f340e3cc8..191a6a090 100644 --- a/docs/getting_started/gettingstarted.rst +++ b/docs/getting_started/gettingstarted.rst @@ -5,11 +5,20 @@ Getting Started What is Pyramid? ---------------- -Pyramid is a web application development framework. Pyramid is lean, fast, stable, well-tested, and thoroughly documented. Pyramid is written in Python, and is open source software released under a `BSD-like license `_. +Pyramid is a web application development framework. Pyramid is lean, fast, +stable, well-tested, and thoroughly documented. Pyramid is written in Python, +and is open source software released under a `BSD-like license +`_. -Pyramid helps you "start small, finish big". You can create a simple web application using Pyramid with only basic knowledge. As you become more familiar with Pyramid, you'll find there is plenty of room to grow. Code you started with early on can be re-used in mature, large, powerful applications. +Pyramid helps you "start small, finish big". You can create a simple web +application using Pyramid with only basic knowledge. As you become more +familiar with Pyramid, you'll find there is plenty of room to grow. Code you +started with early on can be re-used in mature, large, powerful applications. -Pyramid has dozens of features — URL generation, authentication and authorization, [one or two more?] — just like any other web application framework. Several features are unique and make Pyramid stand out from the crowd. +Pyramid has dozens of features — URL generation, authentication and +authorization, [one or two more?] — just like any other web application +framework. Several features are unique and make Pyramid stand out from the +crowd. * Traversal * Python 3 compatibility @@ -18,19 +27,33 @@ Pyramid has dozens of features — URL generation, authentication and authorizat Installation Guide ------------------ -The Installation Guide describes how to install everything needed to get started with Pyramid. It also offers practical advice on working with projects. Whether you're new to Pyramid, Python, programming, or web application development, the Installation Guide will help you get your first Pyramid application up and running and deployed into production. +The Installation Guide describes how to install everything needed to get +started with Pyramid. It also offers practical advice on working with +projects. Whether you're new to Pyramid, Python, programming, or web +application development, the Installation Guide will help you get your first +Pyramid application up and running and deployed into production. Developer Guide --------------- -The Developer Guide describes Pyramid in depth. Formerly called "narrative documentation", the Developer Guide uses technical terms more familiar to the seasoned web application developer. Beginners may be challenged, to put it mildly, but it's a challenge worth accepting. Developers who have already installed Pyramid, worked through a few tutorials, and are ready to write their own applications will find that this guide offers a comprehensive understanding of Pyramid. +The Developer Guide describes Pyramid in depth. Formerly called "narrative +documentation", the Developer Guide uses technical terms more familiar to the +seasoned web application developer. Beginners may be challenged, to put it +mildly, but it's a challenge worth accepting. Developers who have already +installed Pyramid, worked through a few tutorials, and are ready to write their +own applications will find that this guide offers a comprehensive understanding +of Pyramid. API Guide --------- -The API Guide is a comprehensive reference for every public application programming interface (API) exposed by Pyramid. The API Guide lists each item, its arguments, definition, narrative description, its inner workings, and the values and objects it returns in great detail. +The API Guide is a comprehensive reference for every public application +programming interface (API) exposed by Pyramid. The API Guide lists each item, +its arguments, definition, narrative description, its inner workings, and the +values and objects it returns in great detail. Tutorials and Screencasts ------------------------- -There are several tutorials and screencasts that give beginners and new-comers to Pyramid hands-on experience with writing Pyramid applications. +There are several tutorials and screencasts that give beginners and new-comers +to Pyramid hands-on experience with writing Pyramid applications. http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/ -- cgit v1.2.3 From 71b83e5ea328b654f8463f567ecc054a55a7a90b Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 6 Aug 2013 10:12:42 -0400 Subject: Move sample code into subdirectories. Add sections for requests and views. --- docs/getting_started/about_guide.rst | 14 -- docs/getting_started/index.rst | 80 ++------- docs/getting_started/quick_glance.rst | 180 +++++++++++++-------- docs/getting_started/quick_glance/app1.py | 16 -- docs/getting_started/quick_glance/app2.py | 18 --- docs/getting_started/quick_glance/app3.jinja2 | 9 -- docs/getting_started/quick_glance/app3.py | 19 --- docs/getting_started/quick_glance/app4.jinja2 | 10 -- docs/getting_started/quick_glance/app4.py | 19 --- docs/getting_started/quick_glance/app5.py | 26 --- docs/getting_started/quick_glance/app6.py | 30 ---- .../quick_glance/hello_world/CHANGES.txt | 4 - .../quick_glance/hello_world/MANIFEST.in | 2 - .../quick_glance/hello_world/README.txt | 4 - .../quick_glance/hello_world/app.py | 16 ++ .../quick_glance/hello_world/development.ini | 52 ------ .../hello_world/hello_world/__init__.py | 23 --- .../locale/de/LC_MESSAGES/hello_world.mo | Bin 460 -> 0 bytes .../locale/de/LC_MESSAGES/hello_world.po | 21 --- .../locale/fr/LC_MESSAGES/hello_world.mo | Bin 461 -> 0 bytes .../locale/fr/LC_MESSAGES/hello_world.po | 21 --- .../hello_world/hello_world/locale/hello_world.pot | 21 --- .../quick_glance/hello_world/hello_world/models.py | 8 - .../hello_world/hello_world/static/favicon.ico | Bin 1406 -> 0 bytes .../hello_world/hello_world/static/logo.png | Bin 6641 -> 0 bytes .../hello_world/hello_world/static/pylons.css | 73 --------- .../hello_world/templates/mytemplate.jinja2 | 87 ---------- .../quick_glance/hello_world/hello_world/tests.py | 21 --- .../quick_glance/hello_world/hello_world/views.py | 6 - .../hello_world/message-extraction.ini | 3 - .../quick_glance/hello_world/setup.cfg | 28 ---- .../quick_glance/hello_world/setup.py | 39 ----- docs/getting_started/quick_glance/jinja2/app.py | 19 +++ .../quick_glance/jinja2/hello_world.jinja2 | 9 ++ docs/getting_started/quick_glance/json/app.py | 26 +++ .../quick_glance/package/CHANGES.txt | 4 + .../quick_glance/package/MANIFEST.in | 2 + .../quick_glance/package/README.txt | 4 + .../quick_glance/package/development.ini | 52 ++++++ .../quick_glance/package/hello_world/__init__.py | 23 +++ .../locale/de/LC_MESSAGES/hello_world.mo | Bin 0 -> 460 bytes .../locale/de/LC_MESSAGES/hello_world.po | 21 +++ .../locale/fr/LC_MESSAGES/hello_world.mo | Bin 0 -> 461 bytes .../locale/fr/LC_MESSAGES/hello_world.po | 21 +++ .../package/hello_world/locale/hello_world.pot | 21 +++ .../quick_glance/package/hello_world/models.py | 8 + .../package/hello_world/static/favicon.ico | Bin 0 -> 1406 bytes .../package/hello_world/static/logo.png | Bin 0 -> 6641 bytes .../package/hello_world/static/pylons.css | 73 +++++++++ .../hello_world/templates/mytemplate.jinja2 | 87 ++++++++++ .../quick_glance/package/hello_world/tests.py | 21 +++ .../quick_glance/package/hello_world/views.py | 6 + .../quick_glance/package/message-extraction.ini | 3 + .../getting_started/quick_glance/package/setup.cfg | 28 ++++ docs/getting_started/quick_glance/package/setup.py | 39 +++++ docs/getting_started/quick_glance/requests/app.py | 16 ++ docs/getting_started/quick_glance/routing/app.py | 18 +++ .../quick_glance/view_classes/app.py | 30 ++++ docs/getting_started/quick_glance/views/app.py | 10 ++ docs/getting_started/quick_glance/views/views.py | 7 + docs/getting_started/scaffolds.rst | 9 +- docs/getting_started/static_assets/app.py | 19 +++ .../static_assets/hello_world.jinja2 | 10 ++ docs/index.rst | 24 ++- 64 files changed, 753 insertions(+), 707 deletions(-) delete mode 100644 docs/getting_started/about_guide.rst delete mode 100644 docs/getting_started/quick_glance/app1.py delete mode 100644 docs/getting_started/quick_glance/app2.py delete mode 100644 docs/getting_started/quick_glance/app3.jinja2 delete mode 100644 docs/getting_started/quick_glance/app3.py delete mode 100644 docs/getting_started/quick_glance/app4.jinja2 delete mode 100644 docs/getting_started/quick_glance/app4.py delete mode 100644 docs/getting_started/quick_glance/app5.py delete mode 100644 docs/getting_started/quick_glance/app6.py delete mode 100644 docs/getting_started/quick_glance/hello_world/CHANGES.txt delete mode 100644 docs/getting_started/quick_glance/hello_world/MANIFEST.in delete mode 100644 docs/getting_started/quick_glance/hello_world/README.txt create mode 100644 docs/getting_started/quick_glance/hello_world/app.py delete mode 100644 docs/getting_started/quick_glance/hello_world/development.ini delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/__init__.py delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.mo delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.po delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.mo delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.po delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/locale/hello_world.pot delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/models.py delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/static/favicon.ico delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/static/logo.png delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/static/pylons.css delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/tests.py delete mode 100644 docs/getting_started/quick_glance/hello_world/hello_world/views.py delete mode 100644 docs/getting_started/quick_glance/hello_world/message-extraction.ini delete mode 100644 docs/getting_started/quick_glance/hello_world/setup.cfg delete mode 100644 docs/getting_started/quick_glance/hello_world/setup.py create mode 100644 docs/getting_started/quick_glance/jinja2/app.py create mode 100644 docs/getting_started/quick_glance/jinja2/hello_world.jinja2 create mode 100644 docs/getting_started/quick_glance/json/app.py create mode 100644 docs/getting_started/quick_glance/package/CHANGES.txt create mode 100644 docs/getting_started/quick_glance/package/MANIFEST.in create mode 100644 docs/getting_started/quick_glance/package/README.txt create mode 100644 docs/getting_started/quick_glance/package/development.ini create mode 100644 docs/getting_started/quick_glance/package/hello_world/__init__.py create mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo create mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po create mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo create mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po create mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot create mode 100644 docs/getting_started/quick_glance/package/hello_world/models.py create mode 100644 docs/getting_started/quick_glance/package/hello_world/static/favicon.ico create mode 100644 docs/getting_started/quick_glance/package/hello_world/static/logo.png create mode 100644 docs/getting_started/quick_glance/package/hello_world/static/pylons.css create mode 100644 docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 create mode 100644 docs/getting_started/quick_glance/package/hello_world/tests.py create mode 100644 docs/getting_started/quick_glance/package/hello_world/views.py create mode 100644 docs/getting_started/quick_glance/package/message-extraction.ini create mode 100644 docs/getting_started/quick_glance/package/setup.cfg create mode 100644 docs/getting_started/quick_glance/package/setup.py create mode 100644 docs/getting_started/quick_glance/requests/app.py create mode 100644 docs/getting_started/quick_glance/routing/app.py create mode 100644 docs/getting_started/quick_glance/view_classes/app.py create mode 100644 docs/getting_started/quick_glance/views/app.py create mode 100644 docs/getting_started/quick_glance/views/views.py create mode 100644 docs/getting_started/static_assets/app.py create mode 100644 docs/getting_started/static_assets/hello_world.jinja2 diff --git a/docs/getting_started/about_guide.rst b/docs/getting_started/about_guide.rst deleted file mode 100644 index 812b07457..000000000 --- a/docs/getting_started/about_guide.rst +++ /dev/null @@ -1,14 +0,0 @@ -================ -About This Guide -================ - - -- Chapter titles are meaningful - -- Each chapter is autonomous, no one-big-application here - -- Interlinking - -- Reporting bugs or ideas - -- SO for questions \ No newline at end of file diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst index 6396a8e6c..61964056e 100644 --- a/docs/getting_started/index.rst +++ b/docs/getting_started/index.rst @@ -4,80 +4,25 @@ Getting Started With Pyramid 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. - -Topics: scaffolds, packaging, virtual environments - -: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` -=========================== - +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. -:doc:`special_views` -==================== +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:`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 @@ Contents :maxdepth: 2 quick_glance - about_guide scaffolds configuration routes diff --git a/docs/getting_started/quick_glance.rst b/docs/getting_started/quick_glance.rst index da65f2e51..d58303e29 100644 --- a/docs/getting_started/quick_glance.rst +++ b/docs/getting_started/quick_glance.rst @@ -3,92 +3,141 @@ Quick Glance ============ 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/ `_ in a +Next, open `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. + +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 `. + +Let's see some features of requests and responses in action: + +.. literalinclude:: quick_glance/requests/app.py + :pyobject: hello_world + + + +Views +===== - 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. +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. -Using Decorators and Matchdicts -=============================== +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 @@ and elegant by adding: 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. + +#. *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. -#. We tell the ``Configurator`` to go look for decorators. Templates ========= @@ -139,7 +195,7 @@ argument tell Pyramid to pass the response through Jinja2: .. 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 @@ Pyramid will serve some static assets. First, another call to the 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 @@ instructions*, we need to install this as a development package: .. 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 @@ First, change your ``setup.py`` to say: .. 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 @@ the ``coverage`` tool which yells at us for code that isn't tested: ) 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 @@ scaffold! $ 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 @@ Authorization 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 @@ Notes - Explain and link to WSGI, Python Packages -- Richer routing \ No newline at end of file +- Richer routing diff --git a/docs/getting_started/quick_glance/app1.py b/docs/getting_started/quick_glance/app1.py deleted file mode 100644 index cffe53ecf..000000000 --- a/docs/getting_started/quick_glance/app1.py +++ /dev/null @@ -1,16 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator -from pyramid.response import Response - - -def hello_world(request): - return Response('

Hello World!

') - - -if __name__ == '__main__': - config = Configurator() - 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.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app2.py b/docs/getting_started/quick_glance/app2.py deleted file mode 100644 index 49ccd3be1..000000000 --- a/docs/getting_started/quick_glance/app2.py +++ /dev/null @@ -1,18 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator -from pyramid.response import Response -from pyramid.view import view_config - - -@view_config(route_name='hello') -def hello_world(request): - return Response('

Hello %(name)s!

' % request.matchdict) - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/hello/{name}') - config.scan() - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 8081, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app3.jinja2 b/docs/getting_started/quick_glance/app3.jinja2 deleted file mode 100644 index 6d9f0cd5f..000000000 --- a/docs/getting_started/quick_glance/app3.jinja2 +++ /dev/null @@ -1,9 +0,0 @@ - - - - Quick Glance - - -

Hello {{ name }}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app3.py b/docs/getting_started/quick_glance/app3.py deleted file mode 100644 index 549cb5f54..000000000 --- a/docs/getting_started/quick_glance/app3.py +++ /dev/null @@ -1,19 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator -from pyramid.response import Response -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app3.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/hello/{name}') - config.include('pyramid_jinja2') - config.scan() - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 8081, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app4.jinja2 b/docs/getting_started/quick_glance/app4.jinja2 deleted file mode 100644 index 3d0f28c1f..000000000 --- a/docs/getting_started/quick_glance/app4.jinja2 +++ /dev/null @@ -1,10 +0,0 @@ - - - - Quick Glance - - - -

Hello {{ name }}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app4.py b/docs/getting_started/quick_glance/app4.py deleted file mode 100644 index 245ed0b68..000000000 --- a/docs/getting_started/quick_glance/app4.py +++ /dev/null @@ -1,19 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app4.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/hello/{name}') - config.add_static_view(name='static', path='static') - config.include('pyramid_jinja2') - config.scan() - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 8081, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app5.py b/docs/getting_started/quick_glance/app5.py deleted file mode 100644 index 245a0a5ae..000000000 --- a/docs/getting_started/quick_glance/app5.py +++ /dev/null @@ -1,26 +0,0 @@ -from wsgiref.simple_server import make_server - -from pyramid.config import Configurator -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app4.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - - -@view_config(route_name='hello_json', renderer='json') -def hello_json(request): - return [1, 2, 3] - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/hello/{name}') - config.add_route('hello_json', 'hello.json') - config.add_static_view(name='static', path='static') - config.include('pyramid_jinja2') - config.scan() - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 8081, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/app6.py b/docs/getting_started/quick_glance/app6.py deleted file mode 100644 index 155becc54..000000000 --- a/docs/getting_started/quick_glance/app6.py +++ /dev/null @@ -1,30 +0,0 @@ -from wsgiref.simple_server import make_server - -from pyramid.config import Configurator -from pyramid.view import view_config - - -class HelloWorldViews: - def __init__(self, request): - self.request = request - - @view_config(route_name='hello', renderer='app4.jinja2') - def hello_world(self): - return dict(name=self.request.matchdict['name']) - - - @view_config(route_name='hello_json', renderer='json') - def hello_json(self): - return [1, 2, 3] - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/hello/{name}') - config.add_route('hello_json', 'hello.json') - config.add_static_view(name='static', path='static') - config.include('pyramid_jinja2') - config.scan() - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 8081, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/hello_world/CHANGES.txt b/docs/getting_started/quick_glance/hello_world/CHANGES.txt deleted file mode 100644 index ffa255da8..000000000 --- a/docs/getting_started/quick_glance/hello_world/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/getting_started/quick_glance/hello_world/MANIFEST.in b/docs/getting_started/quick_glance/hello_world/MANIFEST.in deleted file mode 100644 index 18fbd855c..000000000 --- a/docs/getting_started/quick_glance/hello_world/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include *.txt *.ini *.cfg *.rst -recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/getting_started/quick_glance/hello_world/README.txt b/docs/getting_started/quick_glance/hello_world/README.txt deleted file mode 100644 index 63aaf6fbd..000000000 --- a/docs/getting_started/quick_glance/hello_world/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -hello_world README - - - diff --git a/docs/getting_started/quick_glance/hello_world/app.py b/docs/getting_started/quick_glance/hello_world/app.py new file mode 100644 index 000000000..df5a6cf18 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_world/app.py @@ -0,0 +1,16 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response + + +def hello_world(request): + return Response('

Hello World!

') + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/') + config.add_view(hello_world, route_name='hello') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/hello_world/development.ini b/docs/getting_started/quick_glance/hello_world/development.ini deleted file mode 100644 index 9aa5f40cf..000000000 --- a/docs/getting_started/quick_glance/hello_world/development.ini +++ /dev/null @@ -1,52 +0,0 @@ -[app:hello_world] -pyramid.includes = pyramid_debugtoolbar -use = egg:hello_world -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_routematch = false -debug_templates = true -default_locale_name = en -jinja2.directories = hello_world:templates - - - -[pipeline:main] -pipeline = - hello_world - -[server:main] -use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 - -# Begin logging configuration - -[loggers] -keys = root, hello_world - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[logger_hello_world] -level = DEBUG -handlers = -qualname = hello_world - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/__init__.py b/docs/getting_started/quick_glance/hello_world/hello_world/__init__.py deleted file mode 100644 index 9b5753c26..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -from pyramid.config import Configurator -from pyramid_jinja2 import renderer_factory -from hello_world.models import get_root - -def main(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - settings = dict(settings) - settings.setdefault('jinja2.i18n.domain', 'hello_world') - - config = Configurator(root_factory=get_root, settings=settings) - config.add_translation_dirs('locale/') - config.include('pyramid_jinja2') - - config.add_static_view('static', 'static') - config.add_view('hello_world.views.my_view', - context='hello_world.models.MyModel', - renderer="mytemplate.jinja2") - - return config.make_wsgi_app() diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.mo b/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.mo deleted file mode 100644 index 40bf0c271..000000000 Binary files a/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.mo and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.po b/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.po deleted file mode 100644 index 0df243dba..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/locale/de/LC_MESSAGES/hello_world.po +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "Hallo!" diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.mo b/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.mo deleted file mode 100644 index 4fc438bfe..000000000 Binary files a/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.mo and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.po b/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.po deleted file mode 100644 index dc0aae5d7..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/locale/fr/LC_MESSAGES/hello_world.po +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "Bonjour!" diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/locale/hello_world.pot b/docs/getting_started/quick_glance/hello_world/hello_world/locale/hello_world.pot deleted file mode 100644 index 9c9460cb2..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/locale/hello_world.pot +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "" diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/models.py b/docs/getting_started/quick_glance/hello_world/hello_world/models.py deleted file mode 100644 index edd361c9c..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/models.py +++ /dev/null @@ -1,8 +0,0 @@ -class MyModel(object): - pass - -root = MyModel() - - -def get_root(request): - return root diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/static/favicon.ico b/docs/getting_started/quick_glance/hello_world/hello_world/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/docs/getting_started/quick_glance/hello_world/hello_world/static/favicon.ico and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/static/logo.png b/docs/getting_started/quick_glance/hello_world/hello_world/static/logo.png deleted file mode 100644 index 88f5d9865..000000000 Binary files a/docs/getting_started/quick_glance/hello_world/hello_world/static/logo.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/static/pylons.css b/docs/getting_started/quick_glance/hello_world/hello_world/static/pylons.css deleted file mode 100644 index 42e2e320e..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/static/pylons.css +++ /dev/null @@ -1,73 +0,0 @@ -html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ -vertical-align:baseline;background:transparent;} -body{line-height:1;} -ol,ul{list-style:none;} -blockquote,q{quotes:none;} -blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ -:focus{outline:0;} -/* remember to highlight inserts somehow! */ -ins{text-decoration:none;} -del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ -table{border-collapse:collapse;border-spacing:0;} -/* restyling */ -sub{vertical-align:sub;font-size:smaller;line-height:normal;} -sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ -ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} -ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} -li{display:list-item;} -/* nested lists have no top/bottom margins */ -ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ -ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ -ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} -.hidden{display:none;} -p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} -h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} -html,body{width:100%;height:100%;} -body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} -a{color:#1b61d6;text-decoration:none;} -a:hover{color:#e88f00;text-decoration:underline;} -body h1, -body h2, -body h3, -body h4, -body h5, -body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} -#wrap {min-height: 100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} -#header{background-color:#e88f00;top:0;font-size:14px;} -#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} -.header,.footer{width:700px;margin-right:auto;margin-left:auto;} -.wrapper{width:100%} -#top,#bottom{width:100%;} -#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} -#bottom{color:#222;background-color:#ffffff;overflow:auto;padding-bottom:80px;} -.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} -.top{padding-top:100px;} -.app-welcome{margin-top:25px;} -.app-name{color:#000000;font-weight:bold;} -.bottom{padding-top:50px;} -#left{width:325px;float:left;padding-right:25px;} -#right{width:325px;float:right;padding-left:25px;} -.align-left{text-align:left;} -.align-right{text-align:right;} -.align-center{text-align:center;} -ul.links{margin:0;padding:0;} -ul.links li{list-style-type:none;font-size:14px;} -form{border-style:none;} -fieldset{border-style:none;} -input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text]{} -input[type=submit]{background-color:#ddd;font-weight:bold;} -/*Opera Fix*/ -body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 b/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 deleted file mode 100644 index 998edfe12..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/templates/mytemplate.jinja2 +++ /dev/null @@ -1,87 +0,0 @@ - - - - The Pyramid Web Framework - - - - - - - - - - -
- -
-
- Logo -

- Welcome to {{project}}, an application generated by
- the Pyramid Web Framework. -

-
-
-
-
-

{% trans %}Hello!{% endtrans %}

-

Request performed with {{ request.locale_name }} locale.

-
-
-
-

Search Pyramid documentation

-
- - -
-
- -
-
-
- - - diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/tests.py b/docs/getting_started/quick_glance/hello_world/hello_world/tests.py deleted file mode 100644 index a81c29eb0..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/tests.py +++ /dev/null @@ -1,21 +0,0 @@ -import unittest -from pyramid import testing -from pyramid.i18n import TranslationStringFactory - -_ = TranslationStringFactory('hello_world') - - -class ViewTests(unittest.TestCase): - - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_my_view(self): - from hello_world.views import my_view - request = testing.DummyRequest() - response = my_view(request) - self.assertEqual(response['project'], 'hello_world') - diff --git a/docs/getting_started/quick_glance/hello_world/hello_world/views.py b/docs/getting_started/quick_glance/hello_world/hello_world/views.py deleted file mode 100644 index c271d45dd..000000000 --- a/docs/getting_started/quick_glance/hello_world/hello_world/views.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.i18n import TranslationStringFactory - -_ = TranslationStringFactory('hello_world') - -def my_view(request): - return {'project':'hello_world'} diff --git a/docs/getting_started/quick_glance/hello_world/message-extraction.ini b/docs/getting_started/quick_glance/hello_world/message-extraction.ini deleted file mode 100644 index 0c3d54bc1..000000000 --- a/docs/getting_started/quick_glance/hello_world/message-extraction.ini +++ /dev/null @@ -1,3 +0,0 @@ -[python: **.py] -[jinja2: **.jinja2] -encoding = utf-8 diff --git a/docs/getting_started/quick_glance/hello_world/setup.cfg b/docs/getting_started/quick_glance/hello_world/setup.cfg deleted file mode 100644 index 186e796fc..000000000 --- a/docs/getting_started/quick_glance/hello_world/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = hello_world -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = hello_world/locale -domain = hello_world -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = hello_world/locale/hello_world.pot -width = 80 -mapping_file = message-extraction.ini - -[init_catalog] -domain = hello_world -input_file = hello_world/locale/hello_world.pot -output_dir = hello_world/locale - -[update_catalog] -domain = hello_world -input_file = hello_world/locale/hello_world.pot -output_dir = hello_world/locale -previous = true diff --git a/docs/getting_started/quick_glance/hello_world/setup.py b/docs/getting_started/quick_glance/hello_world/setup.py deleted file mode 100644 index 6269accf1..000000000 --- a/docs/getting_started/quick_glance/hello_world/setup.py +++ /dev/null @@ -1,39 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = ['pyramid>=1.0.2', 'pyramid_jinja2', 'pyramid_debugtoolbar'] - -setup(name='hello_world', - version='0.0', - description='hello_world', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pylons", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=requires, - tests_require=requires, - test_suite="hello_world", - entry_points="""\ - [paste.app_factory] - main = hello_world:main - """, - paster_plugins=['pyramid'], - extras_require={ - 'testing': ['nose', ], - } -) \ No newline at end of file diff --git a/docs/getting_started/quick_glance/jinja2/app.py b/docs/getting_started/quick_glance/jinja2/app.py new file mode 100644 index 000000000..bee50373b --- /dev/null +++ b/docs/getting_started/quick_glance/jinja2/app.py @@ -0,0 +1,19 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='app3.jinja2') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.include('pyramid_jinja2') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 new file mode 100644 index 000000000..6d9f0cd5f --- /dev/null +++ b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 @@ -0,0 +1,9 @@ + + + + Quick Glance + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/app.py b/docs/getting_started/quick_glance/json/app.py new file mode 100644 index 000000000..9b47fdeaf --- /dev/null +++ b/docs/getting_started/quick_glance/json/app.py @@ -0,0 +1,26 @@ +from wsgiref.simple_server import make_server + +from pyramid.config import Configurator +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='app4.jinja2') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +@view_config(route_name='hello_json', renderer='json') +def hello_json(request): + return [1, 2, 3] + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.add_route('hello_json', 'hello.json') + config.add_static_view(name='static', path='static') + config.include('pyramid_jinja2') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/package/CHANGES.txt b/docs/getting_started/quick_glance/package/CHANGES.txt new file mode 100644 index 000000000..ffa255da8 --- /dev/null +++ b/docs/getting_started/quick_glance/package/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version diff --git a/docs/getting_started/quick_glance/package/MANIFEST.in b/docs/getting_started/quick_glance/package/MANIFEST.in new file mode 100644 index 000000000..18fbd855c --- /dev/null +++ b/docs/getting_started/quick_glance/package/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/getting_started/quick_glance/package/README.txt b/docs/getting_started/quick_glance/package/README.txt new file mode 100644 index 000000000..63aaf6fbd --- /dev/null +++ b/docs/getting_started/quick_glance/package/README.txt @@ -0,0 +1,4 @@ +hello_world README + + + diff --git a/docs/getting_started/quick_glance/package/development.ini b/docs/getting_started/quick_glance/package/development.ini new file mode 100644 index 000000000..9aa5f40cf --- /dev/null +++ b/docs/getting_started/quick_glance/package/development.ini @@ -0,0 +1,52 @@ +[app:hello_world] +pyramid.includes = pyramid_debugtoolbar +use = egg:hello_world +reload_templates = true +debug_authorization = false +debug_notfound = false +debug_routematch = false +debug_templates = true +default_locale_name = en +jinja2.directories = hello_world:templates + + + +[pipeline:main] +pipeline = + hello_world + +[server:main] +use = egg:pyramid#wsgiref +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, hello_world + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_hello_world] +level = DEBUG +handlers = +qualname = hello_world + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/getting_started/quick_glance/package/hello_world/__init__.py b/docs/getting_started/quick_glance/package/hello_world/__init__.py new file mode 100644 index 000000000..9b5753c26 --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/__init__.py @@ -0,0 +1,23 @@ +from pyramid.config import Configurator +from pyramid_jinja2 import renderer_factory +from hello_world.models import get_root + +def main(global_config, **settings): + """ This function returns a WSGI application. + + It is usually called by the PasteDeploy framework during + ``paster serve``. + """ + settings = dict(settings) + settings.setdefault('jinja2.i18n.domain', 'hello_world') + + config = Configurator(root_factory=get_root, settings=settings) + config.add_translation_dirs('locale/') + config.include('pyramid_jinja2') + + config.add_static_view('static', 'static') + config.add_view('hello_world.views.my_view', + context='hello_world.models.MyModel', + renderer="mytemplate.jinja2") + + return config.make_wsgi_app() diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo b/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo new file mode 100644 index 000000000..40bf0c271 Binary files /dev/null and b/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo differ diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po b/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po new file mode 100644 index 000000000..0df243dba --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "Hallo!" diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo b/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo new file mode 100644 index 000000000..4fc438bfe Binary files /dev/null and b/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo differ diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po b/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po new file mode 100644 index 000000000..dc0aae5d7 --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "Bonjour!" diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot b/docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot new file mode 100644 index 000000000..9c9460cb2 --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "" diff --git a/docs/getting_started/quick_glance/package/hello_world/models.py b/docs/getting_started/quick_glance/package/hello_world/models.py new file mode 100644 index 000000000..edd361c9c --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/models.py @@ -0,0 +1,8 @@ +class MyModel(object): + pass + +root = MyModel() + + +def get_root(request): + return root diff --git a/docs/getting_started/quick_glance/package/hello_world/static/favicon.ico b/docs/getting_started/quick_glance/package/hello_world/static/favicon.ico new file mode 100644 index 000000000..71f837c9e Binary files /dev/null and b/docs/getting_started/quick_glance/package/hello_world/static/favicon.ico differ diff --git a/docs/getting_started/quick_glance/package/hello_world/static/logo.png b/docs/getting_started/quick_glance/package/hello_world/static/logo.png new file mode 100644 index 000000000..88f5d9865 Binary files /dev/null and b/docs/getting_started/quick_glance/package/hello_world/static/logo.png differ diff --git a/docs/getting_started/quick_glance/package/hello_world/static/pylons.css b/docs/getting_started/quick_glance/package/hello_world/static/pylons.css new file mode 100644 index 000000000..42e2e320e --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/static/pylons.css @@ -0,0 +1,73 @@ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ +vertical-align:baseline;background:transparent;} +body{line-height:1;} +ol,ul{list-style:none;} +blockquote,q{quotes:none;} +blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} +/* remember to define focus styles! */ +:focus{outline:0;} +/* remember to highlight inserts somehow! */ +ins{text-decoration:none;} +del{text-decoration:line-through;} +/* tables still need 'cellspacing="0"' in the markup */ +table{border-collapse:collapse;border-spacing:0;} +/* restyling */ +sub{vertical-align:sub;font-size:smaller;line-height:normal;} +sup{vertical-align:super;font-size:smaller;line-height:normal;} +/* lists */ +ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} +ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} +li{display:list-item;} +/* nested lists have no top/bottom margins */ +ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} +/* 2 deep unordered lists use a circle */ +ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} +/* 3 deep (or more) unordered lists use a square */ +ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} +.hidden{display:none;} +p{line-height:1.5em;} +h1{font-size:1.75em;/* 28px */ +line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;/* 24px */ +line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;/* 20px */ +line-height:1.7em;font-family:helvetica,verdana;} +h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} +html,body{width:100%;height:100%;} +body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} +a{color:#1b61d6;text-decoration:none;} +a:hover{color:#e88f00;text-decoration:underline;} +body h1, +body h2, +body h3, +body h4, +body h5, +body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} +#wrap {min-height: 100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} +#header{background-color:#e88f00;top:0;font-size:14px;} +#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} +.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +.wrapper{width:100%} +#top,#bottom{width:100%;} +#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} +#bottom{color:#222;background-color:#ffffff;overflow:auto;padding-bottom:80px;} +.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} +.top{padding-top:100px;} +.app-welcome{margin-top:25px;} +.app-name{color:#000000;font-weight:bold;} +.bottom{padding-top:50px;} +#left{width:325px;float:left;padding-right:25px;} +#right{width:325px;float:right;padding-left:25px;} +.align-left{text-align:left;} +.align-right{text-align:right;} +.align-center{text-align:center;} +ul.links{margin:0;padding:0;} +ul.links li{list-style-type:none;font-size:14px;} +form{border-style:none;} +fieldset{border-style:none;} +input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} +input[type=text]{} +input[type=submit]{background-color:#ddd;font-weight:bold;} +/*Opera Fix*/ +body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 b/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 new file mode 100644 index 000000000..998edfe12 --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 @@ -0,0 +1,87 @@ + + + + The Pyramid Web Framework + + + + + + + + + + +
+ +
+
+ Logo +

+ Welcome to {{project}}, an application generated by
+ the Pyramid Web Framework. +

+
+
+
+
+

{% trans %}Hello!{% endtrans %}

+

Request performed with {{ request.locale_name }} locale.

+
+
+
+

Search Pyramid documentation

+
+ + +
+
+ +
+
+
+ + + diff --git a/docs/getting_started/quick_glance/package/hello_world/tests.py b/docs/getting_started/quick_glance/package/hello_world/tests.py new file mode 100644 index 000000000..a81c29eb0 --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/tests.py @@ -0,0 +1,21 @@ +import unittest +from pyramid import testing +from pyramid.i18n import TranslationStringFactory + +_ = TranslationStringFactory('hello_world') + + +class ViewTests(unittest.TestCase): + + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from hello_world.views import my_view + request = testing.DummyRequest() + response = my_view(request) + self.assertEqual(response['project'], 'hello_world') + diff --git a/docs/getting_started/quick_glance/package/hello_world/views.py b/docs/getting_started/quick_glance/package/hello_world/views.py new file mode 100644 index 000000000..c271d45dd --- /dev/null +++ b/docs/getting_started/quick_glance/package/hello_world/views.py @@ -0,0 +1,6 @@ +from pyramid.i18n import TranslationStringFactory + +_ = TranslationStringFactory('hello_world') + +def my_view(request): + return {'project':'hello_world'} diff --git a/docs/getting_started/quick_glance/package/message-extraction.ini b/docs/getting_started/quick_glance/package/message-extraction.ini new file mode 100644 index 000000000..0c3d54bc1 --- /dev/null +++ b/docs/getting_started/quick_glance/package/message-extraction.ini @@ -0,0 +1,3 @@ +[python: **.py] +[jinja2: **.jinja2] +encoding = utf-8 diff --git a/docs/getting_started/quick_glance/package/setup.cfg b/docs/getting_started/quick_glance/package/setup.cfg new file mode 100644 index 000000000..186e796fc --- /dev/null +++ b/docs/getting_started/quick_glance/package/setup.cfg @@ -0,0 +1,28 @@ +[nosetests] +match = ^test +nocapture = 1 +cover-package = hello_world +with-coverage = 1 +cover-erase = 1 + +[compile_catalog] +directory = hello_world/locale +domain = hello_world +statistics = true + +[extract_messages] +add_comments = TRANSLATORS: +output_file = hello_world/locale/hello_world.pot +width = 80 +mapping_file = message-extraction.ini + +[init_catalog] +domain = hello_world +input_file = hello_world/locale/hello_world.pot +output_dir = hello_world/locale + +[update_catalog] +domain = hello_world +input_file = hello_world/locale/hello_world.pot +output_dir = hello_world/locale +previous = true diff --git a/docs/getting_started/quick_glance/package/setup.py b/docs/getting_started/quick_glance/package/setup.py new file mode 100644 index 000000000..6269accf1 --- /dev/null +++ b/docs/getting_started/quick_glance/package/setup.py @@ -0,0 +1,39 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +README = open(os.path.join(here, 'README.txt')).read() +CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + +requires = ['pyramid>=1.0.2', 'pyramid_jinja2', 'pyramid_debugtoolbar'] + +setup(name='hello_world', + version='0.0', + description='hello_world', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pylons", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + tests_require=requires, + test_suite="hello_world", + entry_points="""\ + [paste.app_factory] + main = hello_world:main + """, + paster_plugins=['pyramid'], + extras_require={ + 'testing': ['nose', ], + } +) \ No newline at end of file diff --git a/docs/getting_started/quick_glance/requests/app.py b/docs/getting_started/quick_glance/requests/app.py new file mode 100644 index 000000000..df5a6cf18 --- /dev/null +++ b/docs/getting_started/quick_glance/requests/app.py @@ -0,0 +1,16 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response + + +def hello_world(request): + return Response('

Hello World!

') + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/') + config.add_view(hello_world, route_name='hello') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/routing/app.py b/docs/getting_started/quick_glance/routing/app.py new file mode 100644 index 000000000..bbae35b07 --- /dev/null +++ b/docs/getting_started/quick_glance/routing/app.py @@ -0,0 +1,18 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response +from pyramid.view import view_config + + +@view_config(route_name='hello') +def hello_world(request): + return Response('

Hello %(name)s!

' % request.matchdict) + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/app.py b/docs/getting_started/quick_glance/view_classes/app.py new file mode 100644 index 000000000..90978344b --- /dev/null +++ b/docs/getting_started/quick_glance/view_classes/app.py @@ -0,0 +1,30 @@ +from wsgiref.simple_server import make_server + +from pyramid.config import Configurator +from pyramid.view import view_config + + +class HelloWorldViews: + def __init__(self, request): + self.request = request + + @view_config(route_name='hello', renderer='app4.jinja2') + def hello_world(self): + return dict(name=self.request.matchdict['name']) + + + @view_config(route_name='hello_json', renderer='json') + def hello_json(self): + return [1, 2, 3] + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.add_route('hello_json', 'hello.json') + config.add_static_view(name='static', path='static') + config.include('pyramid_jinja2') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/views/app.py b/docs/getting_started/quick_glance/views/app.py new file mode 100644 index 000000000..1e12b6581 --- /dev/null +++ b/docs/getting_started/quick_glance/views/app.py @@ -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() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/views/views.py b/docs/getting_started/quick_glance/views/views.py new file mode 100644 index 000000000..53a6a273a --- /dev/null +++ b/docs/getting_started/quick_glance/views/views.py @@ -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('

Hello %(name)s!

' % request.matchdict) diff --git a/docs/getting_started/scaffolds.rst b/docs/getting_started/scaffolds.rst index 437291089..af26ab6d6 100644 --- a/docs/getting_started/scaffolds.rst +++ b/docs/getting_started/scaffolds.rst @@ -1,3 +1,10 @@ ==================================== Starting New Projects With Scaffolds -==================================== \ No newline at end of file +==================================== + +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 diff --git a/docs/getting_started/static_assets/app.py b/docs/getting_started/static_assets/app.py new file mode 100644 index 000000000..a0c967c47 --- /dev/null +++ b/docs/getting_started/static_assets/app.py @@ -0,0 +1,19 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='app4.jinja2') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/hello/{name}') + config.add_static_view(name='static', path='static') + config.include('pyramid_jinja2') + config.scan() + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/static_assets/hello_world.jinja2 b/docs/getting_started/static_assets/hello_world.jinja2 new file mode 100644 index 000000000..3d0f28c1f --- /dev/null +++ b/docs/getting_started/static_assets/hello_world.jinja2 @@ -0,0 +1,10 @@ + + + + Quick Glance + + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 09bbb5a9a..e61fe64d4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -48,10 +48,30 @@ What's New 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 @@ management. It provides facilities for wikis, calendars, manuals, searching, tagging, commenting, and file uploads. See the `KARL site `_ for download and installation details. +.. _support-and-development: + Support and Development ======================= -- cgit v1.2.3 From d559afa1b3fabe2733e97c64df4370cc12f33ce0 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 6 Aug 2013 15:23:51 -0400 Subject: Up through JSON. --- docs/designdefense.rst | 3 + docs/getting_started/index.rst | 5 + docs/getting_started/quick_glance.rst | 291 +++++++++++++-------- docs/getting_started/quick_glance/jinja2/app.py | 12 +- .../quick_glance/jinja2/hello_world.jinja2 | 1 - docs/getting_started/quick_glance/jinja2/views.py | 8 + docs/getting_started/quick_glance/json/app.py | 15 +- .../quick_glance/json/hello_world.jinja2 | 10 + .../quick_glance/json/hello_world.pt | 17 ++ docs/getting_started/quick_glance/json/views.py | 13 + docs/getting_started/quick_glance/requests/app.py | 10 +- docs/getting_started/quick_glance/routing/app.py | 14 +- docs/getting_started/quick_glance/routing/views.py | 10 + docs/getting_started/quick_glance/static/app.css | 4 - .../quick_glance/static_assets/app.py | 14 + .../quick_glance/static_assets/hello_world.jinja2 | 10 + .../quick_glance/static_assets/hello_world.pt | 17 ++ .../quick_glance/static_assets/static/app.css | 4 + .../quick_glance/static_assets/views.py | 6 + .../getting_started/quick_glance/templating/app.py | 10 + .../quick_glance/templating/hello_world.pt | 8 + .../quick_glance/templating/views.py | 8 + .../quick_glance/view_classes/app.py | 2 +- docs/getting_started/quick_glance/views/app.py | 5 +- docs/getting_started/quick_glance/views/views.py | 26 +- docs/getting_started/static_assets/app.py | 19 -- .../static_assets/hello_world.jinja2 | 10 - docs/glossary.rst | 4 + 28 files changed, 369 insertions(+), 187 deletions(-) create mode 100644 docs/getting_started/quick_glance/jinja2/views.py create mode 100644 docs/getting_started/quick_glance/json/hello_world.jinja2 create mode 100644 docs/getting_started/quick_glance/json/hello_world.pt create mode 100644 docs/getting_started/quick_glance/json/views.py create mode 100644 docs/getting_started/quick_glance/routing/views.py delete mode 100644 docs/getting_started/quick_glance/static/app.css create mode 100644 docs/getting_started/quick_glance/static_assets/app.py create mode 100644 docs/getting_started/quick_glance/static_assets/hello_world.jinja2 create mode 100644 docs/getting_started/quick_glance/static_assets/hello_world.pt create mode 100644 docs/getting_started/quick_glance/static_assets/static/app.css create mode 100644 docs/getting_started/quick_glance/static_assets/views.py create mode 100644 docs/getting_started/quick_glance/templating/app.py create mode 100644 docs/getting_started/quick_glance/templating/hello_world.pt create mode 100644 docs/getting_started/quick_glance/templating/views.py delete mode 100644 docs/getting_started/static_assets/app.py delete mode 100644 docs/getting_started/static_assets/hello_world.jinja2 diff --git a/docs/designdefense.rst b/docs/designdefense.rst index ea46053a0..22570c23d 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -1295,6 +1295,9 @@ predictability. a registry in another module. This has the effect that double-registrations will never be performed. + +.. _routes_need_ordering: + Routes Need Relative Ordering +++++++++++++++++++++++++++++ diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst index 61964056e..06baf20ca 100644 --- a/docs/getting_started/index.rst +++ b/docs/getting_started/index.rst @@ -24,6 +24,11 @@ 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`. +Notes +===== + +- Cover static urls and asset specifications, resolving, replacing + Contents ======== diff --git a/docs/getting_started/quick_glance.rst b/docs/getting_started/quick_glance.rst index d58303e29..b04baeec8 100644 --- a/docs/getting_started/quick_glance.rst +++ b/docs/getting_started/quick_glance.rst @@ -67,7 +67,7 @@ browser and you will see the ``Hello World!`` message. New to Python web programming? If so, some lines in module merit explanation: -#. *Line 10*. ``if __name__ == '__main__':`` is Python's way of +#. *Line 10*. The ``if __name__ == '__main__':`` is Python's way of saying "Start here when running from the command line". #. *Lines 11-13*. Use Pyramid's :term:`configurator` to connect @@ -78,8 +78,13 @@ explanation: #. *Lines 14-16*. Publish a :term:`WSGI` app using an HTTP server. -Handling Web Requests With webob -================================ +As shown in this example, the :term:`configurator` plays a central role +in Pyramid development. Building an application from loosely-coupled +parts via :doc:`../narr/configuration` is a central idea in Pyramid, +one that we will revisit regurlarly in this *Getting Started* document. + +Handling Web Requests and Responses +=================================== Developing for the web means processing web requests. As this is a critical part of a web application, web developers need a robust, @@ -98,86 +103,144 @@ Let's see some features of requests and responses in action: .. literalinclude:: quick_glance/requests/app.py :pyobject: hello_world +In this Pyramid view, we get the URL being visited from ``request.url``. +Also, if you visited ``http://localhost:6543/?name=alice``, +the name is included in the body of the response:: + + URL http://localhost:6543/?name=alice with name: alice +Finally, we set the response's content type and return the Response. 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. +For the examples above, the ``hello_world`` function is a "view". In +Pyramid, views are the primary way to accept web requests and return +responses. + +So far our examples place everything in one file: + +- the view function -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``: +- its registration with the configurator + +- the route to map it to a URL + +- the WSGI application launcher + +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') +``views.py`` which is scanned via ``config.scan('views')``. -Our ``views.py`` is now more self-contained: +We now have a ``views.py`` module that is focused on handling requests +and responses: .. literalinclude:: quick_glance/views/views.py :linenos: +We have 4 views, each leading to the other. If you start at +``http://localhost:6543/``, you get a response with a link to the next +view. The ``hello_view`` (available at the URL ``/howdy``) has a link +to the ``redirect_view``, which shows issuing a redirect to the final +view. +.. note:: -- Raise exception, redirect -- Change header -- request object -- "callable" + We're focusing on one topic at a time, thus we are leaving out + handling errors, logging, restarting, etc. These will be covered in + sections of the *Getting Started* guide. -Routing With Decorators and Matchdicts -====================================== -Let's repeat the smallest step, but make it a little more functional -and elegant by adding: +Routing +======= -- Echo back a name sent in via the URL +Writing web applications usually means sophisticated URL design. We +just saw some Pyramid machinery for requests and views. Let's look at +features that help in routing. -- The URL is below the top of the site +Above we saw the basics of routing URLs to views in Pyramid: -- Use a decorator to register the view +- Your project's "setup" code registers a route name to be used when + matching part of the URL -Let's make update our ``app.py`` module: +- Elsewhere, a view is configured to be called for that route name + +.. note:: + + Why do this twice? Other systems don't make us repeat this! As + illustrated in :ref:`routes_need_ordering`, multiple routes might + match the same URL pattern. Rather than provide ways to help guess, + Pyramid lets you be explicit in ordering. Pyramid also gives + facilities to avoid the problem. + +What if we want part of the URL to be available as data in my view? This +route declaration: .. literalinclude:: quick_glance/routing/app.py - :linenos: + :start-after: Start Route 1 + :end-before: End Route 1 -When you run ``python ./app.py`` and visit a URL such as -``http://localhost:6543/hello/amy``, the response includes ``amy`` in -the HTML. +With this, URLs such as ``/howdy/amy/smith`` will assign ``amy`` to +``first`` and ``smith`` to ``last``. We can then use this data in our +view: -This module, while small, starts to show how many Pyramid applications -are composed: +.. literalinclude:: quick_glance/routing/views.py + :start-after: Start Route 1 + :end-before: End Route 1 -#. *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. +``request.matchdict`` contains values from the URL that match the +"replacement patterns" (the curly braces) in the route declaration. +This information can then be used in your view. -#. *Line 14*. When setting up the route, mark off a section of the URL - to be data available to the view's :term:`matchdict`. +As you might imagine, Pyramid provides +:doc:`many more features in routing <../narr/urldispatch>` +(route factories, custom predicates, security statements, +etc.) We will see more features later in *Geting Started*. -#. *Line 15*. Tell the configurator to go look for decorators. +Templating +========== +Ouch. We have been making our own ``Response`` and filling the response +body with HTML. You usually won't embed an HTML string directly in +Python, but instead, will use a templating language. -Templates -========= +Pyramid doesn't mandate a particular database system, form library, +etc. It encourages replaceability. This applies equally to templating, +which is fortunate: developers have strong views about template +languages. That said, Pyramid bundles Chameleon and Mako, +so in this step, let's use Chameleon as an example: + +.. literalinclude:: quick_glance/templating/views.py + :start-after: Start View 1 + :end-before: End View 1 + +Ahh, that looks better. We have a view that is focused on Python code. +Our ``@view_config`` decorator specifies a :term:`renderer` that points +our template file. Our view then simply returns data which is then +supplied to our template: -You usually won't embed an HTML string directly in Python, but instead, -will use a templating language. Pyramid comes bundled with Chameleon -and Mako, but Jinja2 is popular. Let's install it: +.. literalinclude:: quick_glance/templating/hello_world.pt + :language: html + +Since our view returned ``dict(name=request.matchdict['name'])``, +we can use ``name`` as a variable in our template via +``${name}``. + +Templating With ``jinja2`` +========================== + +We just said Pyramid doesn't prefer one templating language over +another. Time to prove it. Jinja2 is a popular templating system, +modelled after Django's templates. Let's add ``pyramid_jinja2``, +a Pyramid :term:`add-on` which enables Jinja2 as a :term:`renderer` in +our Pyramid applications: .. code-block:: bash @@ -190,28 +253,28 @@ our configuration: config.include('pyramid_jinja2') -Our view changes. We only return Python data and let the ``renderer`` -argument tell Pyramid to pass the response through Jinja2: +The only change in our view...point the renderer at the ``.jinja2`` file: -.. code-block:: python +.. literalinclude:: quick_glance/jinja2/views.py + :start-after: Start View 1 + :end-before: End View 1 - @view_config(route_name='hello', renderer="hello_world.jinja2") - def hello_world(request): - return dict(name=request.matchdict['name']) +Our Jinja2 template is very similar to our previous template: -Our template is HTML-oriented with a little logic in the ``

``: +.. literalinclude:: quick_glance/jinja2/hello_world.jinja2 + :language: html -.. code-block:: html +Pyramid's templating add-ons register a new kind of renderer into your +application. The renderer registration maps to different kinds of +filename extensions. In this case, changing the extension from ``.pt`` +to ``.jinja2`` passed the view response through the ``pyramid_jinja2`` +renderer. + +.. note:: + + At the time of this writing, Jinja2 had not released a version + compatible with Python 3.3. - - - - Quick Glance - - -

Hello {{ name }}!

- - Static Assets ============= @@ -219,11 +282,11 @@ Static Assets Of course the Web is more than just markup. You need static assets: CSS, JS, and images. Let's point our web app at a directory where Pyramid will serve some static assets. First, another call to the -``Configurator``: - -.. code-block:: python +:term:`configurator`: - config.add_static_view(name='static', path='static') +.. literalinclude:: quick_glance/static_assets/app.py + :start-after: Start Static 1 + :end-before: End Static 1 This tells our WSGI application to map requests under ``http://localhost:6543/static/`` to files and directories inside a @@ -231,45 +294,45 @@ This tells our WSGI application to map requests under Next, make a directory ``static`` and place ``app.css`` inside: -.. code-block:: css - - body { - margin: 2em; - font-family: sans-serif; - } +.. literalinclude:: quick_glance/static_assets/static/app.css + :language: css All we need to do now is point to it in the ```` of our Jinja2 template: -.. code-block:: html +.. literalinclude:: quick_glance/static_assets/hello_world.pt + :language: html + :start-after: Start Link 1 + :end-before: End Link 1 + +This link presumes that our CSS is at a URL starting with ``/static/``. +What if the site is later moved under ``/somesite/static/``? Or perhaps +web developer changes the arrangement on disk? Pyramid gives a helper +that provides flexibility on URL generation: - +.. literalinclude:: quick_glance/static_assets/hello_world.pt + :language: html + :start-after: Start Link 2 + :end-before: End Link 2 + +By using ``request.static_url`` to generate the full URL to the static +assets, you both ensure you stay in sync with the configuration and +gain refactoring flexibility later. Returning JSON ============== Modern web apps are more than rendered HTML. Dynamic pages now use -JavaScript update the UI in the browser by requesting server data as -JSON. +JavaScript to update the UI in the browser by requesting server data as +JSON. Pyramid supports this with a JSON renderer: -Pyramid supports this with a JSON renderer: - -.. code-block:: python - - @view_config(route_name='hello_json', renderer='json') - def hello_json(request): - return [1, 2, 3] +.. literalinclude:: quick_glance/json/views.py + :start-after: Start View 1 + :end-before: End View 2 This wires up a view that returns some data through the JSON -"renderer", which calls Python's JSON support to serialize the data -into JSON, set the appropriate HTTP headers, and more. - -The view needs a route added to the ``Configurator``: - -.. code-block:: python - - config.add_route('hello_json', 'hello.json') - +:term:`renderer`, which calls Python's JSON support to serialize the data +into JSON and set the appropriate HTTP headers. View Classes ============ @@ -301,6 +364,24 @@ Let's re-organize our two views into methods on a view class: Everything else remains the same. + +Configuration +============= + + +#. *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. + +#. *Line 15*. Tell the configurator to go look for decorators. + +- Move route declarations into views, with prefix thingy + +Packages +======== + Quick Project Startup with Scaffolds ==================================== @@ -768,23 +849,3 @@ Authorization ============= -Notes - -- See also, interlinking, teasers or "3 Extras" at the end of each - section, links to a downloadable version of the Python module - -- Read "pyramid for humans" and getting started as an attempt to kill - those - -- Do a better job at the "why" - -- Explain imperative vs. declarative configuration and link to "why - configuration" - -- For see also, point also to Getting Started sections - -- Debugging - -- Explain and link to WSGI, Python Packages - -- Richer routing diff --git a/docs/getting_started/quick_glance/jinja2/app.py b/docs/getting_started/quick_glance/jinja2/app.py index bee50373b..83af219db 100644 --- a/docs/getting_started/quick_glance/jinja2/app.py +++ b/docs/getting_started/quick_glance/jinja2/app.py @@ -1,19 +1,11 @@ from wsgiref.simple_server import make_server from pyramid.config import Configurator -from pyramid.response import Response -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app3.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') + config.add_route('hello', '/howdy/{name}') config.include('pyramid_jinja2') - config.scan() + config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 index 6d9f0cd5f..5fc1fc9bf 100644 --- a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 +++ b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 @@ -1,4 +1,3 @@ - Quick Glance diff --git a/docs/getting_started/quick_glance/jinja2/views.py b/docs/getting_started/quick_glance/jinja2/views.py new file mode 100644 index 000000000..916cdc720 --- /dev/null +++ b/docs/getting_started/quick_glance/jinja2/views.py @@ -0,0 +1,8 @@ +from pyramid.view import view_config + + +# Start View 1 +@view_config(route_name='hello', renderer='hello_world.jinja2') +# End View 1 +def hello_world(request): + return dict(name=request.matchdict['name']) diff --git a/docs/getting_started/quick_glance/json/app.py b/docs/getting_started/quick_glance/json/app.py index 9b47fdeaf..950cb478f 100644 --- a/docs/getting_started/quick_glance/json/app.py +++ b/docs/getting_started/quick_glance/json/app.py @@ -1,26 +1,15 @@ from wsgiref.simple_server import make_server from pyramid.config import Configurator -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app4.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - - -@view_config(route_name='hello_json', renderer='json') -def hello_json(request): - return [1, 2, 3] if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') + config.add_route('hello', '/howdy/{name}') config.add_route('hello_json', 'hello.json') config.add_static_view(name='static', path='static') config.include('pyramid_jinja2') - config.scan() + config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/hello_world.jinja2 b/docs/getting_started/quick_glance/json/hello_world.jinja2 new file mode 100644 index 000000000..3d0f28c1f --- /dev/null +++ b/docs/getting_started/quick_glance/json/hello_world.jinja2 @@ -0,0 +1,10 @@ + + + + Quick Glance + + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/hello_world.pt b/docs/getting_started/quick_glance/json/hello_world.pt new file mode 100644 index 000000000..0cf20d076 --- /dev/null +++ b/docs/getting_started/quick_glance/json/hello_world.pt @@ -0,0 +1,17 @@ + + + + Quick Glance + + + + + + + + +

Hello ${name}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/views.py b/docs/getting_started/quick_glance/json/views.py new file mode 100644 index 000000000..583e220c7 --- /dev/null +++ b/docs/getting_started/quick_glance/json/views.py @@ -0,0 +1,13 @@ +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +# Start View 1 +@view_config(route_name='hello_json', renderer='json') +def hello_json(request): + return [1, 2, 3] + # End View 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/requests/app.py b/docs/getting_started/quick_glance/requests/app.py index df5a6cf18..7ac81eb50 100644 --- a/docs/getting_started/quick_glance/requests/app.py +++ b/docs/getting_started/quick_glance/requests/app.py @@ -4,7 +4,15 @@ from pyramid.response import Response def hello_world(request): - return Response('

Hello World!

') + # Some parameters from a request such as /?name=lisa + url = request.url + name = request.params.get('name', 'No Name Provided') + + body = 'URL %s with name: %s' % (url, name) + return Response( + content_type="text/plain", + body=body + ) if __name__ == '__main__': diff --git a/docs/getting_started/quick_glance/routing/app.py b/docs/getting_started/quick_glance/routing/app.py index bbae35b07..04a8a6344 100644 --- a/docs/getting_started/quick_glance/routing/app.py +++ b/docs/getting_started/quick_glance/routing/app.py @@ -1,18 +1,12 @@ from wsgiref.simple_server import make_server from pyramid.config import Configurator -from pyramid.response import Response -from pyramid.view import view_config - - -@view_config(route_name='hello') -def hello_world(request): - return Response('

Hello %(name)s!

' % request.matchdict) - if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') - config.scan() + # Start Route 1 + config.add_route('hello', '/howdy/{first}/{last}') + # End Route 1 + config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/routing/views.py b/docs/getting_started/quick_glance/routing/views.py new file mode 100644 index 000000000..8cb8d3780 --- /dev/null +++ b/docs/getting_started/quick_glance/routing/views.py @@ -0,0 +1,10 @@ +from pyramid.response import Response +from pyramid.view import view_config + + +# Start Route 1 +@view_config(route_name='hello') +def hello_world(request): + body = '

Hi %(first)s %(last)s!

' % request.matchdict + return Response(body) + # End Route 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static/app.css b/docs/getting_started/quick_glance/static/app.css deleted file mode 100644 index f8acf3164..000000000 --- a/docs/getting_started/quick_glance/static/app.css +++ /dev/null @@ -1,4 +0,0 @@ -body { - margin: 2em; - font-family: sans-serif; -} \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/app.py b/docs/getting_started/quick_glance/static_assets/app.py new file mode 100644 index 000000000..9c808972f --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/app.py @@ -0,0 +1,14 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/howdy/{name}') + # Start Static 1 + config.add_static_view(name='static', path='static') + # End Static 1 + config.include('pyramid_jinja2') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 b/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 new file mode 100644 index 000000000..3d0f28c1f --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 @@ -0,0 +1,10 @@ + + + + Quick Glance + + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/hello_world.pt b/docs/getting_started/quick_glance/static_assets/hello_world.pt new file mode 100644 index 000000000..0cf20d076 --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/hello_world.pt @@ -0,0 +1,17 @@ + + + + Quick Glance + + + + + + + + +

Hello ${name}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/static/app.css b/docs/getting_started/quick_glance/static_assets/static/app.css new file mode 100644 index 000000000..f8acf3164 --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/static/app.css @@ -0,0 +1,4 @@ +body { + margin: 2em; + font-family: sans-serif; +} \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/views.py b/docs/getting_started/quick_glance/static_assets/views.py new file mode 100644 index 000000000..90730ae32 --- /dev/null +++ b/docs/getting_started/quick_glance/static_assets/views.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) diff --git a/docs/getting_started/quick_glance/templating/app.py b/docs/getting_started/quick_glance/templating/app.py new file mode 100644 index 000000000..6d1a29f4e --- /dev/null +++ b/docs/getting_started/quick_glance/templating/app.py @@ -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', '/howdy/{name}') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/templating/hello_world.pt b/docs/getting_started/quick_glance/templating/hello_world.pt new file mode 100644 index 000000000..8860df26a --- /dev/null +++ b/docs/getting_started/quick_glance/templating/hello_world.pt @@ -0,0 +1,8 @@ + + + Quick Glance + + +

Hello ${name}

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/templating/views.py b/docs/getting_started/quick_glance/templating/views.py new file mode 100644 index 000000000..6c7846efa --- /dev/null +++ b/docs/getting_started/quick_glance/templating/views.py @@ -0,0 +1,8 @@ +from pyramid.view import view_config + + +# Start View 1 +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) + # End View 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/app.py b/docs/getting_started/quick_glance/view_classes/app.py index 90978344b..c29311aa5 100644 --- a/docs/getting_started/quick_glance/view_classes/app.py +++ b/docs/getting_started/quick_glance/view_classes/app.py @@ -20,7 +20,7 @@ class HelloWorldViews: if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') + config.add_route('hello', '/howdy/{name}') config.add_route('hello_json', 'hello.json') config.add_static_view(name='static', path='static') config.include('pyramid_jinja2') diff --git a/docs/getting_started/quick_glance/views/app.py b/docs/getting_started/quick_glance/views/app.py index 1e12b6581..54dc9ed4b 100644 --- a/docs/getting_started/quick_glance/views/app.py +++ b/docs/getting_started/quick_glance/views/app.py @@ -3,7 +3,10 @@ from pyramid.config import Configurator if __name__ == '__main__': config = Configurator() - config.add_route('hello', '/hello/{name}') + config.add_route('home', '/') + config.add_route('hello', '/howdy') + config.add_route('redirect', '/goto') + config.add_route('exception', '/problem') config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) diff --git a/docs/getting_started/quick_glance/views/views.py b/docs/getting_started/quick_glance/views/views.py index 53a6a273a..9dc795f14 100644 --- a/docs/getting_started/quick_glance/views/views.py +++ b/docs/getting_started/quick_glance/views/views.py @@ -1,7 +1,29 @@ +from pyramid.httpexceptions import HTTPFound from pyramid.response import Response from pyramid.view import view_config +# First view, available at http://localhost:6543/ +@view_config(route_name='home') +def home_view(request): + return Response('

Visit hello

') + + +# /howdy?name=alice which links to the next view @view_config(route_name='hello') -def hello_world(request): - return Response('

Hello %(name)s!

' % request.matchdict) +def hello_view(request): + name = request.params.get('name', 'No Name') + body = '

Hi %s, this redirects

' + return Response(body % name) + + +# /goto which issues HTTP redirect to the last view +@view_config(route_name='redirect') +def redirect_view(request): + return HTTPFound(location="/problem") + + +# /problem which causes an site error +@view_config(route_name='exception') +def exception_view(request): + raise Exception() diff --git a/docs/getting_started/static_assets/app.py b/docs/getting_started/static_assets/app.py deleted file mode 100644 index a0c967c47..000000000 --- a/docs/getting_started/static_assets/app.py +++ /dev/null @@ -1,19 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='app4.jinja2') -def hello_world(request): - return dict(name=request.matchdict['name']) - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/hello/{name}') - config.add_static_view(name='static', path='static') - config.include('pyramid_jinja2') - config.scan() - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/static_assets/hello_world.jinja2 b/docs/getting_started/static_assets/hello_world.jinja2 deleted file mode 100644 index 3d0f28c1f..000000000 --- a/docs/getting_started/static_assets/hello_world.jinja2 +++ /dev/null @@ -1,10 +0,0 @@ - - - - Quick Glance - - - -

Hello {{ name }}!

- - \ No newline at end of file diff --git a/docs/glossary.rst b/docs/glossary.rst index abc37c7f8..8ade889a3 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -1018,3 +1018,7 @@ Glossary system. See :ref:`registering_thirdparty_predicates` for more information. + add-on + A Python :term:`distribution` that uses Pyramid's extensibility + to plug into a Pyramid application and provide extra, + configurable services. \ No newline at end of file -- cgit v1.2.3 From 30c51bd60756ab632553319a231e154c582b8cd1 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 6 Aug 2013 15:24:33 -0400 Subject: Forgot sqla demo --- .../quick_glance/hello_sqlalchemy/CHANGES.txt | 4 + .../quick_glance/hello_sqlalchemy/MANIFEST.in | 2 + .../quick_glance/hello_sqlalchemy/README.txt | 14 + .../quick_glance/hello_sqlalchemy/development.ini | 71 ++++ .../hello_sqlalchemy/hello_sqlalchemy.sqlite | Bin 0 -> 3072 bytes .../hello_sqlalchemy/hello_sqlalchemy/__init__.py | 20 ++ .../hello_sqlalchemy/hello_sqlalchemy/models.py | 28 ++ .../hello_sqlalchemy/scripts/__init__.py | 1 + .../hello_sqlalchemy/scripts/initializedb.py | 37 ++ .../hello_sqlalchemy/static/favicon.ico | Bin 0 -> 1406 bytes .../hello_sqlalchemy/static/footerbg.png | Bin 0 -> 333 bytes .../hello_sqlalchemy/static/headerbg.png | Bin 0 -> 203 bytes .../hello_sqlalchemy/static/ie6.css | 8 + .../hello_sqlalchemy/static/middlebg.png | Bin 0 -> 2797 bytes .../hello_sqlalchemy/static/pylons.css | 372 +++++++++++++++++++++ .../hello_sqlalchemy/static/pyramid-small.png | Bin 0 -> 7044 bytes .../hello_sqlalchemy/static/pyramid.png | Bin 0 -> 33055 bytes .../hello_sqlalchemy/static/transparent.gif | Bin 0 -> 49 bytes .../hello_sqlalchemy/templates/mytemplate.pt | 76 +++++ .../hello_sqlalchemy/hello_sqlalchemy/tests.py | 33 ++ .../hello_sqlalchemy/hello_sqlalchemy/views.py | 44 +++ .../quick_glance/hello_sqlalchemy/production.ini | 62 ++++ .../quick_glance/hello_sqlalchemy/setup.cfg | 27 ++ .../quick_glance/hello_sqlalchemy/setup.py | 44 +++ 24 files changed, 843 insertions(+) create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/CHANGES.txt create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/MANIFEST.in create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/README.txt create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/development.ini create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy.sqlite create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/__init__.py create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/models.py create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/__init__.py create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/initializedb.py create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/favicon.ico create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/footerbg.png create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/headerbg.png create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/ie6.css create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/middlebg.png create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pylons.css create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid-small.png create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid.png create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/transparent.gif create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/templates/mytemplate.pt create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/tests.py create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/views.py create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/production.ini create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/setup.cfg create mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/setup.py diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/CHANGES.txt b/docs/getting_started/quick_glance/hello_sqlalchemy/CHANGES.txt new file mode 100644 index 000000000..35a34f332 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/MANIFEST.in b/docs/getting_started/quick_glance/hello_sqlalchemy/MANIFEST.in new file mode 100644 index 000000000..2a06ba607 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include hello_sqlalchemy *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/README.txt b/docs/getting_started/quick_glance/hello_sqlalchemy/README.txt new file mode 100644 index 000000000..b7a6612a0 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/README.txt @@ -0,0 +1,14 @@ +hello_sqlalchemy README +================== + +Getting Started +--------------- + +- cd + +- $venv/bin/python setup.py develop + +- $venv/bin/initialize_hello_sqlalchemy_db development.ini + +- $venv/bin/pserve development.ini + diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/development.ini b/docs/getting_started/quick_glance/hello_sqlalchemy/development.ini new file mode 100644 index 000000000..59ae96568 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/development.ini @@ -0,0 +1,71 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_sqlalchemy + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm + +sqlalchemy.url = sqlite:///%(here)s/hello_sqlalchemy.sqlite + +# By default, the toolbar only appears for clients from IP addresses +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +host = 0.0.0.0 +port = 6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_sqlalchemy, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_hello_sqlalchemy] +level = DEBUG +handlers = +qualname = hello_sqlalchemy + +[logger_sqlalchemy] +level = INFO +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy.sqlite b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy.sqlite new file mode 100644 index 000000000..fa6adb104 Binary files /dev/null and b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy.sqlite differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/__init__.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/__init__.py new file mode 100644 index 000000000..aac7c5e69 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/__init__.py @@ -0,0 +1,20 @@ +from pyramid.config import Configurator +from sqlalchemy import engine_from_config + +from .models import ( + DBSession, + Base, + ) + + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.bind = engine + config = Configurator(settings=settings) + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + config.scan() + return config.make_wsgi_app() diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/models.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/models.py new file mode 100644 index 000000000..aeeb9df64 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/models.py @@ -0,0 +1,28 @@ +from sqlalchemy import ( + Column, + Integer, + Text, + ) + +from sqlalchemy.ext.declarative import declarative_base + +from sqlalchemy.orm import ( + scoped_session, + sessionmaker, + ) + +from zope.sqlalchemy import ZopeTransactionExtension + +DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) +Base = declarative_base() + + +class MyModel(Base): + __tablename__ = 'models' + id = Column(Integer, primary_key=True) + name = Column(Text, unique=True) + value = Column(Integer) + + def __init__(self, name, value): + self.name = name + self.value = value diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/__init__.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/__init__.py @@ -0,0 +1 @@ +# package diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/initializedb.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/initializedb.py new file mode 100644 index 000000000..66feb3008 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/initializedb.py @@ -0,0 +1,37 @@ +import os +import sys +import transaction + +from sqlalchemy import engine_from_config + +from pyramid.paster import ( + get_appsettings, + setup_logging, + ) + +from ..models import ( + DBSession, + MyModel, + Base, + ) + + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s \n' + '(example: "%s development.ini")' % (cmd, cmd)) + sys.exit(1) + + +def main(argv=sys.argv): + if len(argv) != 2: + usage(argv) + config_uri = argv[1] + setup_logging(config_uri) + settings = get_appsettings(config_uri) + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.create_all(engine) + with transaction.manager: + model = MyModel(name='one', value=1) + DBSession.add(model) diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/favicon.ico b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/favicon.ico new file mode 100644 index 000000000..71f837c9e Binary files /dev/null and b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/favicon.ico differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/footerbg.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/footerbg.png new file mode 100644 index 000000000..1fbc873da Binary files /dev/null and b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/footerbg.png differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/headerbg.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/headerbg.png new file mode 100644 index 000000000..0596f2020 Binary files /dev/null and b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/headerbg.png differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/ie6.css b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/middlebg.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/middlebg.png new file mode 100644 index 000000000..2369cfb7d Binary files /dev/null and b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/middlebg.png differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pylons.css b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pylons.css new file mode 100644 index 000000000..4b1c017cd --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pylons.css @@ -0,0 +1,372 @@ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td +{ + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; /* 16px */ + vertical-align: baseline; + background: transparent; +} + +body +{ + line-height: 1; +} + +ol, ul +{ + list-style: none; +} + +blockquote, q +{ + quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after +{ + content: ''; + content: none; +} + +:focus +{ + outline: 0; +} + +ins +{ + text-decoration: none; +} + +del +{ + text-decoration: line-through; +} + +table +{ + border-collapse: collapse; + border-spacing: 0; +} + +sub +{ + vertical-align: sub; + font-size: smaller; + line-height: normal; +} + +sup +{ + vertical-align: super; + font-size: smaller; + line-height: normal; +} + +ul, menu, dir +{ + display: block; + list-style-type: disc; + margin: 1em 0; + padding-left: 40px; +} + +ol +{ + display: block; + list-style-type: decimal-leading-zero; + margin: 1em 0; + padding-left: 40px; +} + +li +{ + display: list-item; +} + +ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl +{ + margin-top: 0; + margin-bottom: 0; +} + +ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir +{ + list-style-type: circle; +} + +ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir +{ + list-style-type: square; +} + +.hidden +{ + display: none; +} + +p +{ + line-height: 1.5em; +} + +h1 +{ + font-size: 1.75em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h2 +{ + font-size: 1.5em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h3 +{ + font-size: 1.25em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h4 +{ + font-size: 1em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +html, body +{ + width: 100%; + height: 100%; +} + +body +{ + margin: 0; + padding: 0; + background-color: #fff; + position: relative; + font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; +} + +a +{ + color: #1b61d6; + text-decoration: none; +} + +a:hover +{ + color: #e88f00; + text-decoration: underline; +} + +body h1, body h2, body h3, body h4, body h5, body h6 +{ + font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; + font-weight: 400; + color: #373839; + font-style: normal; +} + +#wrap +{ + min-height: 100%; +} + +#header, #footer +{ + width: 100%; + color: #fff; + height: 40px; + position: absolute; + text-align: center; + line-height: 40px; + overflow: hidden; + font-size: 12px; + vertical-align: middle; +} + +#header +{ + background: #000; + top: 0; + font-size: 14px; +} + +#footer +{ + bottom: 0; + background: #000 url(footerbg.png) repeat-x 0 top; + position: relative; + margin-top: -40px; + clear: both; +} + +.header, .footer +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.wrapper +{ + width: 100%; +} + +#top, #top-small, #bottom +{ + width: 100%; +} + +#top +{ + color: #000; + height: 230px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#top-small +{ + color: #000; + height: 60px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#bottom +{ + color: #222; + background-color: #fff; +} + +.top, .top-small, .middle, .bottom +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.top +{ + padding-top: 40px; +} + +.top-small +{ + padding-top: 10px; +} + +#middle +{ + width: 100%; + height: 100px; + background: url(middlebg.png) repeat-x; + border-top: 2px solid #fff; + border-bottom: 2px solid #b2b2b2; +} + +.app-welcome +{ + margin-top: 25px; +} + +.app-name +{ + color: #000; + font-weight: 700; +} + +.bottom +{ + padding-top: 50px; +} + +#left +{ + width: 350px; + float: left; + padding-right: 25px; +} + +#right +{ + width: 350px; + float: right; + padding-left: 25px; +} + +.align-left +{ + text-align: left; +} + +.align-right +{ + text-align: right; +} + +.align-center +{ + text-align: center; +} + +ul.links +{ + margin: 0; + padding: 0; +} + +ul.links li +{ + list-style-type: none; + font-size: 14px; +} + +form +{ + border-style: none; +} + +fieldset +{ + border-style: none; +} + +input +{ + color: #222; + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 12px; + line-height: 16px; +} + +input[type=text], input[type=password] +{ + width: 205px; +} + +input[type=submit] +{ + background-color: #ddd; + font-weight: 700; +} + +/*Opera Fix*/ +body:before +{ + content: ""; + height: 100%; + float: left; + width: 0; + margin-top: -32767px; +} diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid-small.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid-small.png new file mode 100644 index 000000000..a5bc0ade7 Binary files /dev/null and b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid-small.png differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid.png new file mode 100644 index 000000000..347e05549 Binary files /dev/null and b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid.png differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/transparent.gif b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/transparent.gif new file mode 100644 index 000000000..0341802e5 Binary files /dev/null and b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/transparent.gif differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/templates/mytemplate.pt b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/templates/mytemplate.pt new file mode 100644 index 000000000..2de66d4c9 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/templates/mytemplate.pt @@ -0,0 +1,76 @@ + + + + The Pyramid Web Framework + + + + + + + + + + +
+
+
+
pyramid
+
+
+
+
+

+ Welcome to ${project}, an application generated by
+ the Pyramid Web Framework. +

+
+
+
+
+
+

Search documentation

+
+ + +
+
+ +
+
+
+ + + diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/tests.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/tests.py new file mode 100644 index 000000000..e2789665b --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/tests.py @@ -0,0 +1,33 @@ +import unittest +import transaction + +from pyramid import testing + +from .models import DBSession + + +class TestMyView(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + from sqlalchemy import create_engine + engine = create_engine('sqlite://') + from .models import ( + Base, + MyModel, + ) + DBSession.configure(bind=engine) + Base.metadata.create_all(engine) + with transaction.manager: + model = MyModel(name='one', value=55) + DBSession.add(model) + + def tearDown(self): + DBSession.remove() + testing.tearDown() + + def test_it(self): + from .views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['one'].name, 'one') + self.assertEqual(info['project'], 'hello_sqlalchemy') diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/views.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/views.py new file mode 100644 index 000000000..796acf738 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/views.py @@ -0,0 +1,44 @@ +from pyramid.response import Response +from pyramid.view import view_config + +import colander +import deform + +from sqlalchemy.exc import DBAPIError + +from .models import ( + DBSession, + MyModel, + ) + +class MyForm(colander.MappingSchema): + title = colander.SchemaNode(colander.String()) + body = colander.SchemaNode( + colander.String(), + widget=deform.widget.RichTextWidget() + ) + +@view_config(route_name='home', renderer='templates/mytemplate.pt') +def my_view(request): + try: + one = DBSession.query(MyModel).filter(MyModel.name == 'one').first() + except DBAPIError: + return Response(conn_err_msg, content_type='text/plain', status_int=500) + return {'one': one, 'project': 'hello_sqlalchemy'} + +conn_err_msg = """\ +Pyramid is having a problem using your SQL database. The problem +might be caused by one of the following things: + +1. You may need to run the "initialize_hello_sqlalchemy_db" script + to initialize your database tables. Check your virtual + environment's "bin" directory for this script and try to run it. + +2. Your database server may not be running. Check that the + database server referred to by the "sqlalchemy.url" setting in + your "development.ini" file is running. + +After you fix the problem, please restart the Pyramid application to +try it again. +""" + diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/production.ini b/docs/getting_started/quick_glance/hello_sqlalchemy/production.ini new file mode 100644 index 000000000..3257d0067 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/production.ini @@ -0,0 +1,62 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:hello_sqlalchemy + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_tm + +sqlalchemy.url = sqlite:///%(here)s/hello_sqlalchemy.sqlite + +[server:main] +use = egg:waitress#main +host = 0.0.0.0 +port = 6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, hello_sqlalchemy, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_hello_sqlalchemy] +level = WARN +handlers = +qualname = hello_sqlalchemy + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/setup.cfg b/docs/getting_started/quick_glance/hello_sqlalchemy/setup.cfg new file mode 100644 index 000000000..d08bf9c9b --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/setup.cfg @@ -0,0 +1,27 @@ +[nosetests] +match=^test +nocapture=1 +cover-package=hello_sqlalchemy +with-coverage=1 +cover-erase=1 + +[compile_catalog] +directory = hello_sqlalchemy/locale +domain = hello_sqlalchemy +statistics = true + +[extract_messages] +add_comments = TRANSLATORS: +output_file = hello_sqlalchemy/locale/hello_sqlalchemy.pot +width = 80 + +[init_catalog] +domain = hello_sqlalchemy +input_file = hello_sqlalchemy/locale/hello_sqlalchemy.pot +output_dir = hello_sqlalchemy/locale + +[update_catalog] +domain = hello_sqlalchemy +input_file = hello_sqlalchemy/locale/hello_sqlalchemy.pot +output_dir = hello_sqlalchemy/locale +previous = true diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/setup.py b/docs/getting_started/quick_glance/hello_sqlalchemy/setup.py new file mode 100644 index 000000000..f4e1f48c0 --- /dev/null +++ b/docs/getting_started/quick_glance/hello_sqlalchemy/setup.py @@ -0,0 +1,44 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +README = open(os.path.join(here, 'README.txt')).read() +CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + +requires = [ + 'pyramid', + 'SQLAlchemy', + 'transaction', + 'pyramid_tm', + 'pyramid_debugtoolbar', + 'zope.sqlalchemy', + 'waitress', + ] + +setup(name='hello_sqlalchemy', + version='0.0', + description='hello_sqlalchemy', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web wsgi bfg pylons pyramid', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + test_suite='hello_sqlalchemy', + install_requires=requires, + entry_points="""\ + [paste.app_factory] + main = hello_sqlalchemy:main + [console_scripts] + initialize_hello_sqlalchemy_db = hello_sqlalchemy.scripts.initializedb:main + """, + ) -- cgit v1.2.3 From 65d1719fc5ce4ed4e87c45b1e4279c30930b274e Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Wed, 7 Aug 2013 15:34:58 -0400 Subject: Up through scaffolds. --- docs/getting_started/quick_glance.rst | 139 +++++++-------------- .../quick_glance/jinja2/hello_world.jinja2 | 2 +- .../quick_glance/json/hello_world.jinja2 | 4 +- .../quick_glance/json/hello_world.pt | 2 +- .../quick_glance/static_assets/hello_world.jinja2 | 4 +- .../quick_glance/static_assets/hello_world.pt | 5 +- .../quick_glance/templating/hello_world.pt | 1 + .../quick_glance/view_classes/app.py | 23 +--- .../quick_glance/view_classes/delete.jinja2 | 9 ++ .../quick_glance/view_classes/edit.jinja2 | 9 ++ .../quick_glance/view_classes/hello.jinja2 | 17 +++ .../quick_glance/view_classes/views.py | 32 +++++ docs/getting_started/scaffolds.rst | 100 +++++++++++++++ docs/getting_started/views.rst | 37 ++++++ 14 files changed, 259 insertions(+), 125 deletions(-) create mode 100644 docs/getting_started/quick_glance/view_classes/delete.jinja2 create mode 100644 docs/getting_started/quick_glance/view_classes/edit.jinja2 create mode 100644 docs/getting_started/quick_glance/view_classes/hello.jinja2 create mode 100644 docs/getting_started/quick_glance/view_classes/views.py diff --git a/docs/getting_started/quick_glance.rst b/docs/getting_started/quick_glance.rst index b04baeec8..7189a0d13 100644 --- a/docs/getting_started/quick_glance.rst +++ b/docs/getting_started/quick_glance.rst @@ -19,8 +19,8 @@ Python Setup 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: +environments, packaging tools, logging, etc.) so let's get our working +area in place. For Python 3.3: .. code-block:: bash @@ -151,6 +151,14 @@ view. The ``hello_view`` (available at the URL ``/howdy``) has a link to the ``redirect_view``, which shows issuing a redirect to the final view. +Earlier we saw ``config.add_view`` as one way to configure a view. This +section introduces ``@view_config``. 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. Both approaches result in the same final +configuration, thus usually, it is simply a matter of taste. + .. note:: We're focusing on one topic at a time, thus we are leaving out @@ -337,50 +345,43 @@ into JSON and set the appropriate HTTP headers. View Classes ============ -Free-standing functions are the regular way to do views. Many times, -though, you have several views that are closely related. For example, -a document might have many different ways to look at it. - -For some people, grouping these together makes logical sense. A view -class lets you group views, sharing some state assignments, and -using helper functions as class methods. - -Let's re-organize our two views into methods on a view class: - -.. code-block:: python - - class HelloWorldViews: - def __init__(self, request): - self.request = request +So far our views have been simple, free-standing functions. Many times +your views are related: different ways to look at or work on the same +data or a REST API that handles multiple operations. Grouping these +together as a +:ref:`view class ` makes sense: - @view_config(route_name='hello', renderer='app4.jinja2') - def hello_world(self): - return dict(name=self.request.matchdict['name']) +- Group views +- Centralize some repetitive defaults - @view_config(route_name='hello_json', renderer='json') - def hello_json(self): - return [1, 2, 3] +- Share some state and helpers -Everything else remains the same. +The following shows a "Hello World" example with three operations: view +a form, save a change, or press the delete button: +.. literalinclude:: quick_glance/view_classes/views.py + :start-after: Start View 1 + :end-before: End View 1 -Configuration -============= - +As you can see, the three views are logically grouped together. +Specifically: -#. *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. +- The first view is returned when you go to ``/howdy/amy``. This URL is + mapped to the ``hello`` route that we centrally set using the optional + ``@view_defaults``. -#. *Line 15*. Tell the configurator to go look for decorators. +- The second view is returned when the form data contains a field with + ``form.edit``, such as clicking on + ````. This rule + is specified in the ``@view_config`` for that view. -- Move route declarations into views, with prefix thingy +- The third view is returned when clicking on a button such + as ````. -Packages -======== +Only one route needed, stated in one place atop the view class. Also, +the assignment of the ``name`` is done in the ``__init__``. Our +templates can then use ``{{ view.name }}``. Quick Project Startup with Scaffolds ==================================== @@ -390,37 +391,8 @@ No Python packages, no structure. Most Pyramid projects, though, aren't developed this way. To ease the process of getting started, Pyramid provides *scaffolds* -that generate sample projects. Not just Pyramid itself: add-ons such as -``pyramid_jinja2`` (or your own projects) can register there own -scaffolds. - -We use Pyramid's ``pcreate`` command to generate our starting point -from a scaffold. What does this command look like? - -.. code-block:: bash - - $ pcreate --help - Usage: pcreate [options] output_directory - - Render Pyramid scaffolding to an output directory - - Options: - -h, --help show this help message and exit - -s SCAFFOLD_NAME, --scaffold=SCAFFOLD_NAME - Add a scaffold to the create process (multiple -s args - accepted) - -t SCAFFOLD_NAME, --template=SCAFFOLD_NAME - A backwards compatibility alias for -s/--scaffold. - Add a scaffold to the create process (multiple -t args - accepted) - -l, --list List all available scaffold names - --list-templates A backwards compatibility alias for -l/--list. List - all available scaffold names. - --simulate Simulate but do no work - --overwrite Always overwrite - --interactive When a file would be overwritten, interrogate - -Let's see what our Pyramid install supports as starting-point scaffolds: +that generate sample projects from templates in Pyramid and Pyramid +add-ons. Pyramid's ``pcreate`` command can list the available scaffolds: .. code-block:: bash @@ -431,38 +403,22 @@ Let's see what our Pyramid install supports as starting-point scaffolds: starter: Pyramid starter project zodb: Pyramid ZODB project using traversal -The ``pyramid_jinja2_starter`` looks interesting. From the parent -directory of where we want our Python package to be generated, +The ``pyramid_jinja2`` add-on gave us a scaffold that we can use. From +the parent directory of where we want our Python package to be generated, let's use that scaffold to make our project: .. code-block:: bash $ pcreate --scaffold pyramid_jinja2_starter hello_world -After printing a bunch of lines about the files being generated, -we now have a Python package. As described in the *official -instructions*, we need to install this as a development package: +We next use the normal Python development to setup our package for +development: .. code-block:: bash $ cd hello_world $ 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 -sample files for our application: - -.. code-block:: bash - - $ ls - CHANGES.txt development.ini hello_world.egg-info - MANIFEST.in message-extraction.ini setup.cfg - README.txt hello_world setup.py - - $ ls hello_world - __init__.py locale static tests.py - __pycache__ models.py templates views.py - We are moving in the direction of a full-featured Pyramid project, with a proper setup for Python standards (packaging) and Pyramid configuration. This includes a new way of running your application: @@ -471,15 +427,6 @@ configuration. This includes a new way of running your application: $ pserve development.ini -With ``pserve``, your application isn't responsible for finding a WSGI -server and launching your WSGI app. Also, much of the wiring of your -application can be moved to a declarative ``.ini`` configuration file. - -In your browser, visit -`http://localhost:6543/ `_ and you'll see that -things look very different. In the next few sections we'll cover some -decisions made by this scaffold. - Let's look at ``pserve`` and configuration in more depth. Application Running with ``pserve`` diff --git a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 index 5fc1fc9bf..e177744b5 100644 --- a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 +++ b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 @@ -1,6 +1,6 @@ - Quick Glance + Hello World

Hello {{ name }}!

diff --git a/docs/getting_started/quick_glance/json/hello_world.jinja2 b/docs/getting_started/quick_glance/json/hello_world.jinja2 index 3d0f28c1f..f6862e618 100644 --- a/docs/getting_started/quick_glance/json/hello_world.jinja2 +++ b/docs/getting_started/quick_glance/json/hello_world.jinja2 @@ -1,8 +1,8 @@ + - Quick Glance - +

Hello {{ name }}!

diff --git a/docs/getting_started/quick_glance/json/hello_world.pt b/docs/getting_started/quick_glance/json/hello_world.pt index 0cf20d076..711054aa9 100644 --- a/docs/getting_started/quick_glance/json/hello_world.pt +++ b/docs/getting_started/quick_glance/json/hello_world.pt @@ -1,5 +1,5 @@ + - Quick Glance diff --git a/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 b/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 index 3d0f28c1f..f6862e618 100644 --- a/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 +++ b/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 @@ -1,8 +1,8 @@ + - Quick Glance - +

Hello {{ name }}!

diff --git a/docs/getting_started/quick_glance/static_assets/hello_world.pt b/docs/getting_started/quick_glance/static_assets/hello_world.pt index 0cf20d076..1797146eb 100644 --- a/docs/getting_started/quick_glance/static_assets/hello_world.pt +++ b/docs/getting_started/quick_glance/static_assets/hello_world.pt @@ -1,6 +1,5 @@ - - - + + Quick Glance diff --git a/docs/getting_started/quick_glance/templating/hello_world.pt b/docs/getting_started/quick_glance/templating/hello_world.pt index 8860df26a..ae14f447d 100644 --- a/docs/getting_started/quick_glance/templating/hello_world.pt +++ b/docs/getting_started/quick_glance/templating/hello_world.pt @@ -1,3 +1,4 @@ + Quick Glance diff --git a/docs/getting_started/quick_glance/view_classes/app.py b/docs/getting_started/quick_glance/view_classes/app.py index c29311aa5..468c8c29e 100644 --- a/docs/getting_started/quick_glance/view_classes/app.py +++ b/docs/getting_started/quick_glance/view_classes/app.py @@ -1,30 +1,13 @@ from wsgiref.simple_server import make_server - from pyramid.config import Configurator -from pyramid.view import view_config - - -class HelloWorldViews: - def __init__(self, request): - self.request = request - - @view_config(route_name='hello', renderer='app4.jinja2') - def hello_world(self): - return dict(name=self.request.matchdict['name']) - - - @view_config(route_name='hello_json', renderer='json') - def hello_json(self): - return [1, 2, 3] - if __name__ == '__main__': config = Configurator() + # Start Routes 1 config.add_route('hello', '/howdy/{name}') - config.add_route('hello_json', 'hello.json') - config.add_static_view(name='static', path='static') + # End Routes 1 config.include('pyramid_jinja2') - config.scan() + config.scan('views') app = config.make_wsgi_app() server = make_server('0.0.0.0', 6543, app) server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/delete.jinja2 b/docs/getting_started/quick_glance/view_classes/delete.jinja2 new file mode 100644 index 000000000..ba45b7d16 --- /dev/null +++ b/docs/getting_started/quick_glance/view_classes/delete.jinja2 @@ -0,0 +1,9 @@ + + + + Delete World + + +

Delete {{ view.name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/edit.jinja2 b/docs/getting_started/quick_glance/view_classes/edit.jinja2 new file mode 100644 index 000000000..ce0eb5bd1 --- /dev/null +++ b/docs/getting_started/quick_glance/view_classes/edit.jinja2 @@ -0,0 +1,9 @@ + + + + Edit World + + +

Edit {{ view.name }}!

+ + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/hello.jinja2 b/docs/getting_started/quick_glance/view_classes/hello.jinja2 new file mode 100644 index 000000000..3446b96ce --- /dev/null +++ b/docs/getting_started/quick_glance/view_classes/hello.jinja2 @@ -0,0 +1,17 @@ + + + + Hello World + + +

Hello {{ view.name }}!

+ +
+ + + +
+ + + \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/views.py b/docs/getting_started/quick_glance/view_classes/views.py new file mode 100644 index 000000000..62556142e --- /dev/null +++ b/docs/getting_started/quick_glance/view_classes/views.py @@ -0,0 +1,32 @@ +from pyramid.view import ( + view_config, + view_defaults + ) + + +# Start View 1 +# One route, at /howdy/amy, so don't repeat on each @view_config +@view_defaults(route_name='hello') +class HelloWorldViews: + def __init__(self, request): + self.request = request + # Our templates can now say {{ view.name }} + self.name = request.matchdict['name'] + + # Retrieving /howdy/amy the first time + @view_config(renderer='hello.jinja2') + def hello_view(self): + return dict() + + # Posting to /howdy/amy via the "Edit" submit button + @view_config(request_param='form.edit', renderer='edit.jinja2') + def edit_view(self): + print('Edited') + return dict() + + # Posting to /howdy/amy via the "Delete" submit button + @view_config(request_param='form.delete', renderer='delete.jinja2') + def delete_view(self): + print('Deleted') + return dict() + # End View 1 \ No newline at end of file diff --git a/docs/getting_started/scaffolds.rst b/docs/getting_started/scaffolds.rst index af26ab6d6..52101495e 100644 --- a/docs/getting_started/scaffolds.rst +++ b/docs/getting_started/scaffolds.rst @@ -2,9 +2,109 @@ Starting New Projects With Scaffolds ==================================== +So far we have done all of our *Quick Glance* as a single Python file. +No Python packages, no structure. Most Pyramid projects, though, +aren't developed this way. + +To ease the process of getting started, Pyramid provides *scaffolds* +that generate sample projects. You run a command, perhaps answer some +questions, and a sample project is generated for you. Not just Pyramid +itself: add-ons such as ``pyramid_jinja2`` (or your own projects) can +register their own 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 + +Pyramid's ``pcreate`` command is used to generate a starting point +from a scaffold. What does this command look like? + +.. code-block:: bash + + $ pcreate --help + Usage: pcreate [options] output_directory + + Render Pyramid scaffolding to an output directory + + Options: + -h, --help show this help message and exit + -s SCAFFOLD_NAME, --scaffold=SCAFFOLD_NAME + Add a scaffold to the create process (multiple -s args + accepted) + -t SCAFFOLD_NAME, --template=SCAFFOLD_NAME + A backwards compatibility alias for -s/--scaffold. + Add a scaffold to the create process (multiple -t args + accepted) + -l, --list List all available scaffold names + --list-templates A backwards compatibility alias for -l/--list. List + all available scaffold names. + --simulate Simulate but do no work + --overwrite Always overwrite + --interactive When a file would be overwritten, interrogate + +Let's see what our Pyramid install supports as starting-point scaffolds: + +.. code-block:: bash + + $ pcreate --list + Available scaffolds: + alchemy: Pyramid SQLAlchemy project using url dispatch + pyramid_jinja2_starter: pyramid jinja2 starter project + starter: Pyramid starter project + zodb: Pyramid ZODB project using traversal + +The ``pyramid_jinja2_starter`` looks interesting. From the parent +directory of where we want our Python package to be generated, +let's use that scaffold to make our project: + +.. code-block:: bash + + $ pcreate --scaffold pyramid_jinja2_starter hello_world + +After printing a bunch of lines about the files being generated, +we now have a Python package. As described in the *official +instructions*, we need to install this as a development package: + +.. code-block:: bash + + $ cd hello_world + $ 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 +sample files for our application: + +.. code-block:: bash + + $ ls + CHANGES.txt development.ini hello_world.egg-info + MANIFEST.in message-extraction.ini setup.cfg + README.txt hello_world setup.py + + $ ls hello_world + __init__.py locale static tests.py + __pycache__ models.py templates views.py + +We are moving in the direction of a full-featured Pyramid project, +with a proper setup for Python standards (packaging) and Pyramid +configuration. This includes a new way of running your application: + +.. code-block:: bash + + $ pserve development.ini + +With ``pserve``, your application isn't responsible for finding a WSGI +server and launching your WSGI app. Also, much of the wiring of your +application can be moved to a declarative ``.ini`` configuration file. + +In your browser, visit +`http://localhost:6543/ `_ and you'll see that +things look very different. In the next few sections we'll cover some +decisions made by this scaffold. + +Let's look at ``pserve`` and configuration in more depth. \ No newline at end of file diff --git a/docs/getting_started/views.rst b/docs/getting_started/views.rst index 347d5aae7..827778a66 100644 --- a/docs/getting_started/views.rst +++ b/docs/getting_started/views.rst @@ -1,3 +1,40 @@ ================================ Handling Web Requests With Views ================================ + +Free-standing functions are the regular way to do views. Many times, +though, you have several views that are closely related. For example, +a document might have many different ways to look at it, +or a form might submit to different targets, or a REST handler might +cover different operations. + +Grouping these together makes logical sense. A view class lets you +group views, centralize some repetitive defaults, share some state +assignments, and use helper functions as class methods. + +As an example, imagine we have some views around saying hello to a +person, then editing that person or perhaps deleting that person. They +might logically belong together. We could do these as independent +functions, but let's do them together as a view class: + +.. literalinclude:: quick_glance/view_classes/views.py + :start-after: Start View 1 + :end-before: End View 1 + +...and some routes that wire up the views to URLs: + +.. literalinclude:: quick_glance/view_classes/app.py + :start-after: Start Routes 1 + :end-before: End Routes 1 + +...and a form in ``hello_world.jinja2`` that submits to the second view: + +.. literalinclude:: quick_glance/view_classes/hello_world.jinja2 + :language: html + :start-after: Start Form 1 + :end-before: End Form 1 + +Just to review: + +- The ``/howdy/amy`` URL matches the ``hello`` route, handled by the + ``hello_view`` class method. \ No newline at end of file -- cgit v1.2.3 From d4bd291fd5ca51bbbeec487f2011476706a5952f Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Fri, 9 Aug 2013 11:37:48 -0400 Subject: Lots of updates, move more code out of code-blocks into working package code. About to tackle cool Pyramid stuff. --- docs/getting_started/databases.rst | 17 + docs/getting_started/index.rst | 7 + docs/getting_started/pserve.rst | 18 + docs/getting_started/quick_glance.rst | 306 ++++++++--------- .../quick_glance/hello_sqlalchemy/CHANGES.txt | 4 - .../quick_glance/hello_sqlalchemy/MANIFEST.in | 2 - .../quick_glance/hello_sqlalchemy/README.txt | 14 - .../quick_glance/hello_sqlalchemy/development.ini | 71 ---- .../hello_sqlalchemy/hello_sqlalchemy.sqlite | Bin 3072 -> 0 bytes .../hello_sqlalchemy/hello_sqlalchemy/__init__.py | 20 -- .../hello_sqlalchemy/hello_sqlalchemy/models.py | 28 -- .../hello_sqlalchemy/scripts/__init__.py | 1 - .../hello_sqlalchemy/scripts/initializedb.py | 37 -- .../hello_sqlalchemy/static/favicon.ico | Bin 1406 -> 0 bytes .../hello_sqlalchemy/static/footerbg.png | Bin 333 -> 0 bytes .../hello_sqlalchemy/static/headerbg.png | Bin 203 -> 0 bytes .../hello_sqlalchemy/static/ie6.css | 8 - .../hello_sqlalchemy/static/middlebg.png | Bin 2797 -> 0 bytes .../hello_sqlalchemy/static/pylons.css | 372 --------------------- .../hello_sqlalchemy/static/pyramid-small.png | Bin 7044 -> 0 bytes .../hello_sqlalchemy/static/pyramid.png | Bin 33055 -> 0 bytes .../hello_sqlalchemy/static/transparent.gif | Bin 49 -> 0 bytes .../hello_sqlalchemy/templates/mytemplate.pt | 76 ----- .../hello_sqlalchemy/hello_sqlalchemy/tests.py | 33 -- .../hello_sqlalchemy/hello_sqlalchemy/views.py | 44 --- .../quick_glance/hello_sqlalchemy/production.ini | 62 ---- .../quick_glance/hello_sqlalchemy/setup.cfg | 27 -- .../quick_glance/hello_sqlalchemy/setup.py | 44 --- .../quick_glance/package/development.ini | 13 +- .../quick_glance/package/hello_world/__init__.py | 13 +- .../hello_world/templates/mytemplate.jinja2 | 5 +- .../quick_glance/package/hello_world/tests.py | 1 - .../quick_glance/package/hello_world/views.py | 18 +- docs/getting_started/quick_glance/package/setup.py | 2 + .../quick_glance/sqla_demo/CHANGES.txt | 4 + .../quick_glance/sqla_demo/MANIFEST.in | 2 + .../quick_glance/sqla_demo/README.txt | 14 + .../quick_glance/sqla_demo/development.ini | 71 ++++ .../quick_glance/sqla_demo/production.ini | 62 ++++ .../quick_glance/sqla_demo/setup.cfg | 27 ++ .../quick_glance/sqla_demo/setup.py | 44 +++ .../quick_glance/sqla_demo/sqla_demo.sqlite | Bin 0 -> 3072 bytes .../quick_glance/sqla_demo/sqla_demo/__init__.py | 20 ++ .../quick_glance/sqla_demo/sqla_demo/models.py | 29 ++ .../sqla_demo/sqla_demo/scripts/__init__.py | 1 + .../sqla_demo/sqla_demo/scripts/initializedb.py | 37 ++ .../sqla_demo/sqla_demo/static/favicon.ico | Bin 0 -> 1406 bytes .../sqla_demo/sqla_demo/static/footerbg.png | Bin 0 -> 333 bytes .../sqla_demo/sqla_demo/static/headerbg.png | Bin 0 -> 203 bytes .../sqla_demo/sqla_demo/static/ie6.css | 8 + .../sqla_demo/sqla_demo/static/middlebg.png | Bin 0 -> 2797 bytes .../sqla_demo/sqla_demo/static/pylons.css | 372 +++++++++++++++++++++ .../sqla_demo/sqla_demo/static/pyramid-small.png | Bin 0 -> 7044 bytes .../sqla_demo/sqla_demo/static/pyramid.png | Bin 0 -> 33055 bytes .../sqla_demo/sqla_demo/static/transparent.gif | Bin 0 -> 49 bytes .../sqla_demo/sqla_demo/templates/mytemplate.pt | 76 +++++ .../quick_glance/sqla_demo/sqla_demo/tests.py | 33 ++ .../quick_glance/sqla_demo/sqla_demo/views.py | 37 ++ docs/getting_started/top_ten.rst | 33 +- docs/getting_started/views.rst | 10 - 60 files changed, 1101 insertions(+), 1022 deletions(-) create mode 100644 docs/getting_started/pserve.rst delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/CHANGES.txt delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/MANIFEST.in delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/README.txt delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/development.ini delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy.sqlite delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/__init__.py delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/models.py delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/__init__.py delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/initializedb.py delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/favicon.ico delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/footerbg.png delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/headerbg.png delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/ie6.css delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/middlebg.png delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pylons.css delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid-small.png delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid.png delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/transparent.gif delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/templates/mytemplate.pt delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/tests.py delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/views.py delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/production.ini delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/setup.cfg delete mode 100644 docs/getting_started/quick_glance/hello_sqlalchemy/setup.py create mode 100644 docs/getting_started/quick_glance/sqla_demo/CHANGES.txt create mode 100644 docs/getting_started/quick_glance/sqla_demo/MANIFEST.in create mode 100644 docs/getting_started/quick_glance/sqla_demo/README.txt create mode 100644 docs/getting_started/quick_glance/sqla_demo/development.ini create mode 100644 docs/getting_started/quick_glance/sqla_demo/production.ini create mode 100644 docs/getting_started/quick_glance/sqla_demo/setup.cfg create mode 100644 docs/getting_started/quick_glance/sqla_demo/setup.py create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo.sqlite create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/__init__.py create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/models.py create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/__init__.py create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/initializedb.py create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/favicon.ico create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/footerbg.png create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/headerbg.png create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/ie6.css create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/middlebg.png create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pylons.css create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid-small.png create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid.png create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/transparent.gif create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/templates/mytemplate.pt create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/tests.py create mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/views.py diff --git a/docs/getting_started/databases.rst b/docs/getting_started/databases.rst index f982643af..c415ed2db 100644 --- a/docs/getting_started/databases.rst +++ b/docs/getting_started/databases.rst @@ -2,3 +2,20 @@ Databases With SQLAlchemy ========================= +We can now visit our sample at +`http://localhost:6543/ `_. Some choices that +the scaffold helped us with: + +- A ``setup.py`` with appropriate dependencies + +- Connection strings and integration in our ``development.ini`` file + +- A console script which we ran above to initialize the database + +- The SQLAlchemy engine integrated into the ``Configurator`` on + application startup + +- Python modules for the SQLAlchemy models and the Pyramid views that + go with them + +- Some unit tests...yummy! diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst index 06baf20ca..b7ab3c7bb 100644 --- a/docs/getting_started/index.rst +++ b/docs/getting_started/index.rst @@ -29,6 +29,12 @@ Notes - Cover static urls and asset specifications, resolving, replacing +.. toctree:: + :maxdepth: 1 + + gettingstarted + + Contents ======== @@ -42,6 +48,7 @@ Contents views templates static_assets + pserve testing forms databases diff --git a/docs/getting_started/pserve.rst b/docs/getting_started/pserve.rst new file mode 100644 index 000000000..a7f8ba62c --- /dev/null +++ b/docs/getting_started/pserve.rst @@ -0,0 +1,18 @@ +=================================== +Application Running With ``pserve`` +=================================== + + +Three Cool Things About ``pserve`` +---------------------------------- + +1. *Multiple .ini files*. You might have some settings in + development mode or some in production mode. Maybe you are writing an + add-on that needs to be wired-up by other people. + +2. *Choice of WSGI server*. ``pserve`` itself isn't a WSGI server. + Instead, it loads the server you want from the configuration file. + +3. *Friends of pserve*. With the ``pserve``/``.ini`` approach you + also get other commands that help during development: ``pshell``, + ``proutes``, ``pviews``, ``prequest``, etc. diff --git a/docs/getting_started/quick_glance.rst b/docs/getting_started/quick_glance.rst index 7189a0d13..f9a60c0eb 100644 --- a/docs/getting_started/quick_glance.rst +++ b/docs/getting_started/quick_glance.rst @@ -270,7 +270,7 @@ The only change in our view...point the renderer at the ``.jinja2`` file: Our Jinja2 template is very similar to our previous template: .. literalinclude:: quick_glance/jinja2/hello_world.jinja2 - :language: html + :language: jinja Pyramid's templating add-ons register a new kind of renderer into your application. The renderer registration maps to different kinds of @@ -432,9 +432,15 @@ Let's look at ``pserve`` and configuration in more depth. Application Running with ``pserve`` =================================== -When you install Pyramid, a small command program called ``pserve`` is -written to your ``bin`` directory. This program is an executable Python -module. It's very small, getting most of its brains via import. +Prior to scaffolds, our project mixed a number of operations details +into our code. Why should my main code care with HTTP server I want and +what port number to run on? + +``pserve`` is Pyramid's application runner, separating operational +details from your code. When you install Pyramid, a small command +program called ``pserve`` is written to your ``bin`` directory. This +program is an executable Python module. It's very small, getting most +of its brains via import. You can run ``pserve`` with ``--help`` to see some of its options. Doing so reveals that you can ask ``pserve`` to watch your development @@ -444,35 +450,22 @@ files and reload the server when they change: $ pserve development.ini --reload -By design, ``pserve`` itself isn't all that interesting. Instead, -its brains from your project's wiring, as expressed in the -configuration file you supply it. - -.. seealso:: See Also: :ref:`what_is_this_pserve_thing` - -Three Cool Things About ``pserve`` ----------------------------------- - -1. *Multiple .ini files*. You might have some settings in - development mode or some in production mode. Maybe you are writing an - add-on that needs to be wired-up by other people. - -2. *Choice of WSGI server*. ``pserve`` itself isn't a WSGI server. - Instead, it loads the server you want from the configuration file. - -3. *Friends of pserve*. With the ``pserve``/``.ini`` approach you - also get other commands that help during development: ``pshell``, - ``proutes``, ``pviews``, ``prequest``, etc. +The ``pserve`` command has a number of other options and operations. +Most of the work, though, comes from your project's wiring, as +expressed in the configuration file you supply to ``pserve``. Let's +take a look at this configuration file. Configuration with ``.ini`` Files ================================= Earlier in *Quick Glance* we first met Pyramid's configuration system. -At that point we did all configuration in Python code, -aka *imperatively*. For example, the port number chosen for our HTTP -server was right there in Python code. Our scaffold has moved this -decision, and more, into *declarative* configuration in the -``development.ini`` file. +At that point we did all configuration in Python code. For example, +the port number chosen for our HTTP server was right there in Python +code. Our scaffold has moved this decision, and more, into the +``development.ini`` file: + +.. literalinclude:: quick_glance/package/development.ini + :language: ini Let's take a quick high-level look. First, the ``.ini`` file is divided into sections: @@ -485,7 +478,7 @@ into sections: - Various sections afterwards configure our Python logging system -Let's look at a few decisions made in this configuration: +We have a few decisions made for us in this configuration: #. *Choice of web server*. The ``use = egg:pyramid#wsgiref`` tell ``pserve`` to the ``wsgiref`` server that is wrapped in the Pyramid @@ -520,9 +513,9 @@ illustrates several points about configuration. First, change your ``setup.py`` to say: -.. code-block:: python - - requires=['pyramid>=1.0.2', 'pyramid_jinja2'] +.. literalinclude:: quick_glance/package/setup.py + :start-after: Start Requires + :end-before: End Requires ...and re-run your setup: @@ -530,26 +523,31 @@ First, change your ``setup.py`` to say: $ 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: +The Python package was now installed into our environment. The package +is a Pyramid add-on, which means we need to include its configuration +into our web application. We could do this with imperative +configuration, as we did above for the ``pyramid_jinja2`` add-on: -.. code-block:: python - - config.include('pyramid_debugtoolbar') +.. literalinclude:: quick_glance/package/hello_world/__init__.py + :start-after: Start Include + :end-before: End Include -Instead, let's do it in configuration by modifying our +Now that we have a configuration file, we can use the +``pyramid.includes`` facility and place this in our ``development.ini`` instead: -.. code-block:: ini - - [app:hello_world] - pyramid.includes = pyramid_debugtoolbar +.. literalinclude:: quick_glance/package/development.ini + :language: ini + :start-after: Start Includes + :end-before: End Includes -That is, add ``pyramid.includes = pyramid_debugtoolbar`` anywhere in the -``[app:hello_world]`` section. You'll now see an attractive (and -collapsible) menu in the right of your browser giving you introspective +You'll now see an attractive (and +collapsible) menu in the right of your browser, providing introspective access to debugging information. Even better, if your web application -generates an error, you will see a nice traceback on the screen. +generates an error, you will see a nice traceback on the screen. When +you want to disable this toolbar, no need to change code: you can +remove it from ``pyramid.includes`` in the relevant ``.ini`` +configuration file. Unit Tests and ``nose`` ======================= @@ -577,7 +575,8 @@ We changed ``setup.py`` which means we need to re-run .. code-block:: bash - $ nosetests + $ cd hello_world + $ nosetests . . Name Stmts Miss Cover Missing --------------------------------------------------- @@ -594,25 +593,7 @@ We changed ``setup.py`` which means we need to re-run Our unit test passed. What did our test look like? -.. code-block:: python - - import unittest - from pyramid import testing - - - class ViewTests(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_my_view(self): - from hello_world.views import my_view - - request = testing.DummyRequest() - response = my_view(request) - self.assertEqual(response['project'], 'hello_world') +.. literalinclude:: quick_glance/package/hello_world/tests.py Pyramid supplies helpers for test writing, which we use in the test setup and teardown. Our one test imports the view, @@ -634,65 +615,75 @@ messages sent by Pyramid (for example, when a new request comes in.) Maybe you would like to log messages in your code? In your Python module, import and setup the logging: -.. code-block:: python - - import logging - log = logging.getLogger(__name__) +.. literalinclude:: quick_glance/package/hello_world/views.py + :start-after: Start Logging 1 + :end-before: End Logging 1 You can now, in your code, log messages: -.. code-block:: python - - log.debug('Some Message') +.. literalinclude:: quick_glance/package/hello_world/views.py + :start-after: Start Logging 2 + :end-before: End Logging 2 This will log ``Some Message`` at a ``debug`` log level, to the application-configured logger in your ``development.ini``. What controls that? These sections in the configuration file: -.. code-block:: ini - - [loggers] - keys = root, hello_world - - [logger_hello_world] - level = DEBUG - handlers = - qualname = hello_world +.. literalinclude:: quick_glance/package/development.ini + :language: ini + :start-after: Start Sphinx Include + :end-before: End Sphinx Include Our application, a package named ``hello_world``, is setup as a logger -and configured to log messages at a ``DEBUG`` or higher level. +and configured to log messages at a ``DEBUG`` or higher level. When you +visit ``http://localhost:6543`` your console will now show:: + + 2013-08-09 10:42:42,968 DEBUG [hello_world.views][MainThread] Some Message Sessions ======== When people use your web application, they frequently perform a task -that requires semi-permanent data to be saved. For example,a shopping -cart. These are frequently called *sessions*. +that requires semi-permanent data to be saved. For example, a shopping +cart. This is called a :term:`session`. Pyramid has basic built-in support for sessions, with add-ons such as *Beaker* (or your own custom sessioning engine) that provide richer -session support. For the built-in session support, you first import -the "factory" which provides the sessioning: +session support. Let's take a look at the +:doc:`built-in sessioning support <../narr/sessions>`. In our +``__init__.py`` we first import the kind of sessioning we want: -.. code-block:: python +.. literalinclude:: quick_glance/package/hello_world/__init__.py + :start-after: Start Sphinx Include 1 + :end-before: End Sphinx Include 1 - from pyramid.session import UnencryptedCookieSessionFactoryConfig - my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet') +.. warning:: -We tell the configuration system that this is the source of our -sessioning support when setting up the ``Configurator``: + As noted in the session docs, this example implementation is + not intended for use in settings with security implications. -.. code-block:: python +Now make a "factory" and pass it to the :term:`configurator`'s +``session_factory`` argument: - config = Configurator(session_factory = my_session_factory) +.. literalinclude:: quick_glance/package/hello_world/__init__.py + :start-after: Start Sphinx Include 2 + :end-before: End Sphinx Include 2 -This now lets us use the session in our application code: +Pyramid's :term:`request` object now has a ``session`` attribute +that we can use in our view code: -.. code-block:: python +.. literalinclude:: quick_glance/package/hello_world/views.py + :start-after: Start Sphinx Include 1 + :end-before: End Sphinx Include 1 + +With this, each reload will increase the counter displayed in our +Jinja2 template: + +.. literalinclude:: quick_glance/package/hello_world/templates/mytemplate.jinja2 + :language: jinja + :start-after: Start Sphinx Include 1 + :end-before: End Sphinx Include 1 - session = request.session - if 'abc' in session: - session['fred'] = 'yes' Databases ========= @@ -708,8 +699,8 @@ scaffold! .. code-block:: bash - $ pcreate --scaffold alchemy hello_sqlalchemy - $ cd hello_sqlalchemy + $ pcreate --scaffold alchemy sqla_demo + $ cd sqla_demo $ python setup.py develop We now have a working sample SQLAlchemy application with all @@ -719,80 +710,97 @@ the application: .. code-block:: bash - $ initialize_hello_sqlalchemy_db development.ini + $ initialize_sqla_demo_db development.ini $ pserve development.ini -We can now visit our sample at -`http://localhost:6543/ `_. Some choices that -the scaffold helped us with: - -- A ``setup.py`` with appropriate dependencies +The ORM eases the mapping of database structures into a programming +language. SQLAlchemy uses "models" for this mapping. The scaffold +generated a sample model: -- Connection strings and integration in our ``development.ini`` file +.. literalinclude:: quick_glance/sqla_demo/sqla_demo/models.py + :start-after: Start Sphinx Include + :end-before: End Sphinx Include -- A console script which we ran above to initialize the database +View code, which mediates the logic between web requests and the rest +of the system, can then easily get at the data thanks to SQLAlchemy: -- The SQLAlchemy engine integrated into the ``Configurator`` on - application startup +.. literalinclude:: quick_glance/sqla_demo/sqla_demo/views.py + :start-after: Start Sphinx Include + :end-before: End Sphinx Include -- Python modules for the SQLAlchemy models and the Pyramid views that - go with them +Forms +===== -- Some unit tests...yummy! +Developers have lots of opinions about web forms, and thus there are many +form libraries for Python. Pyramid doesn't directly bundle a form +library, but *Deform* is a popular choice for forms, +along with its related *Colander* schema system. -As mentioned above, an ORM is software that eases the mapping of -database structures into a programming language. SQLAlchemy uses models -for this, and its scaffold generated a sample model: +As an example, imagine we want a form that edits a wiki page. The form +should have two fields on it, one of them a required title and the +other a rich text editor for the body. With Deform we can express this +as a Colander schema: .. code-block:: python - class MyModel(Base): - __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Text, unique=True) - value = Column(Integer) + class WikiPage(colander.MappingSchema): + title = colander.SchemaNode(colander.String()) + body = colander.SchemaNode( + colander.String(), + widget=deform.widget.RichTextWidget() + ) - def __init__(self, name, value): - self.name = name - self.value = value - -The Python module also includes this: +With this in place, we can render the HTML for a form, +perhaps with form data from an existing page: .. code-block:: python - from zope.sqlalchemy import ZopeTransactionExtension - -The generated application includes the optional support for -``pyramid_tm``, a unique transaction monitor that integrates your -database transactions with your code for transparent rollback and commit. + form = self.wiki_form.render() -View code, which mediates the logic between web requests and the rest -of the system, can then easily get at the data: +We'd like to handle form submission, validation, and saving: .. code-block:: python - one = DBSession.query(MyModel).filter(MyModel.name == 'one').first() - - -Forms -===== + # Get the form data that was posted + controls = self.request.POST.items() + try: + # Validate and either raise a validation error + # or return deserialized data from widgets + appstruct = wiki_form.validate(controls) + except deform.ValidationFailure as e: + # Bail out and render form with errors + return dict(title=title, page=page, form=e.render()) -Developers have lots of opinions about forms, and thus there are many -form libraries for Python. Pyramid doesn't directly bundle a form -library, but *Deform* is a popular choice. Let's see it in action. -First we install it: + # Change the content and redirect to the view + page['title'] = appstruct['title'] + page['body'] = appstruct['body'] -.. code-block:: bash +Deform and Colander provide a very flexible combination for forms, +widgets, schemas, and validation. Recent versions of Deform also +include a +`retail mode `_ +for gaining Deform +features on custom forms. - $ pip-3.3 install deform +Also, the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform +widgets using attractive CSS from Bootstrap and more powerful widgets +from Chosen. +Awesome Pyramid Features +======================== +For the most part this *Quick Glance* has covered concepts that are +common in Python web frameworks. Pyramid has a unique niche, +though. It helps you start with a small project that grows into a +larger project. Let's look at some of the unique facilities that help. -Authentication -============== -Authorization -============= +Conclusion +========== +This *Quick Glance* was a little about a lot. We introduced a long list +of concepts in Pyramid, many of which are expanded on more fully later +in *Getting Started* and certainly in the Pyramid developer docs. \ No newline at end of file diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/CHANGES.txt b/docs/getting_started/quick_glance/hello_sqlalchemy/CHANGES.txt deleted file mode 100644 index 35a34f332..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/MANIFEST.in b/docs/getting_started/quick_glance/hello_sqlalchemy/MANIFEST.in deleted file mode 100644 index 2a06ba607..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include *.txt *.ini *.cfg *.rst -recursive-include hello_sqlalchemy *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/README.txt b/docs/getting_started/quick_glance/hello_sqlalchemy/README.txt deleted file mode 100644 index b7a6612a0..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/README.txt +++ /dev/null @@ -1,14 +0,0 @@ -hello_sqlalchemy README -================== - -Getting Started ---------------- - -- cd - -- $venv/bin/python setup.py develop - -- $venv/bin/initialize_hello_sqlalchemy_db development.ini - -- $venv/bin/pserve development.ini - diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/development.ini b/docs/getting_started/quick_glance/hello_sqlalchemy/development.ini deleted file mode 100644 index 59ae96568..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/development.ini +++ /dev/null @@ -1,71 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### - -[app:main] -use = egg:hello_sqlalchemy - -pyramid.reload_templates = true -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -pyramid.includes = - pyramid_debugtoolbar - pyramid_tm - -sqlalchemy.url = sqlite:///%(here)s/hello_sqlalchemy.sqlite - -# By default, the toolbar only appears for clients from IP addresses -# '127.0.0.1' and '::1'. -# debugtoolbar.hosts = 127.0.0.1 ::1 - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -host = 0.0.0.0 -port = 6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, hello_sqlalchemy, sqlalchemy - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[logger_hello_sqlalchemy] -level = DEBUG -handlers = -qualname = hello_sqlalchemy - -[logger_sqlalchemy] -level = INFO -handlers = -qualname = sqlalchemy.engine -# "level = INFO" logs SQL queries. -# "level = DEBUG" logs SQL queries and results. -# "level = WARN" logs neither. (Recommended for production systems.) - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy.sqlite b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy.sqlite deleted file mode 100644 index fa6adb104..000000000 Binary files a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy.sqlite and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/__init__.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/__init__.py deleted file mode 100644 index aac7c5e69..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -from pyramid.config import Configurator -from sqlalchemy import engine_from_config - -from .models import ( - DBSession, - Base, - ) - - -def main(global_config, **settings): - """ This function returns a Pyramid WSGI application. - """ - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) - Base.metadata.bind = engine - config = Configurator(settings=settings) - config.add_static_view('static', 'static', cache_max_age=3600) - config.add_route('home', '/') - config.scan() - return config.make_wsgi_app() diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/models.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/models.py deleted file mode 100644 index aeeb9df64..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/models.py +++ /dev/null @@ -1,28 +0,0 @@ -from sqlalchemy import ( - Column, - Integer, - Text, - ) - -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import ( - scoped_session, - sessionmaker, - ) - -from zope.sqlalchemy import ZopeTransactionExtension - -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) -Base = declarative_base() - - -class MyModel(Base): - __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Text, unique=True) - value = Column(Integer) - - def __init__(self, name, value): - self.name = name - self.value = value diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/__init__.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/initializedb.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/initializedb.py deleted file mode 100644 index 66feb3008..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/scripts/initializedb.py +++ /dev/null @@ -1,37 +0,0 @@ -import os -import sys -import transaction - -from sqlalchemy import engine_from_config - -from pyramid.paster import ( - get_appsettings, - setup_logging, - ) - -from ..models import ( - DBSession, - MyModel, - Base, - ) - - -def usage(argv): - cmd = os.path.basename(argv[0]) - print('usage: %s \n' - '(example: "%s development.ini")' % (cmd, cmd)) - sys.exit(1) - - -def main(argv=sys.argv): - if len(argv) != 2: - usage(argv) - config_uri = argv[1] - setup_logging(config_uri) - settings = get_appsettings(config_uri) - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) - Base.metadata.create_all(engine) - with transaction.manager: - model = MyModel(name='one', value=1) - DBSession.add(model) diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/favicon.ico b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/favicon.ico and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/footerbg.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/footerbg.png deleted file mode 100644 index 1fbc873da..000000000 Binary files a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/footerbg.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/headerbg.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/headerbg.png deleted file mode 100644 index 0596f2020..000000000 Binary files a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/headerbg.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/ie6.css b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* html img, -* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", -this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", -this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) -);} -#wrap{display:table;height:100%} diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/middlebg.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/middlebg.png deleted file mode 100644 index 2369cfb7d..000000000 Binary files a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/middlebg.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pylons.css b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -ul, menu, dir -{ - display: block; - list-style-type: disc; - margin: 1em 0; - padding-left: 40px; -} - -ol -{ - display: block; - list-style-type: decimal-leading-zero; - margin: 1em 0; - padding-left: 40px; -} - -li -{ - display: list-item; -} - -ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl -{ - margin-top: 0; - margin-bottom: 0; -} - -ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir -{ - list-style-type: circle; -} - -ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir -{ - list-style-type: square; -} - -.hidden -{ - display: none; -} - -p -{ - line-height: 1.5em; -} - -h1 -{ - font-size: 1.75em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h2 -{ - font-size: 1.5em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h3 -{ - font-size: 1.25em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h4 -{ - font-size: 1em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -html, body -{ - width: 100%; - height: 100%; -} - -body -{ - margin: 0; - padding: 0; - background-color: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 url(footerbg.png) repeat-x 0 top; - position: relative; - margin-top: -40px; - clear: both; -} - -.header, .footer -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.wrapper -{ - width: 100%; -} - -#top, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.top, .top-small, .middle, .bottom -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.top -{ - padding-top: 40px; -} - -.top-small -{ - padding-top: 10px; -} - -#middle -{ - width: 100%; - height: 100px; - background: url(middlebg.png) repeat-x; - border-top: 2px solid #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#left -{ - width: 350px; - float: left; - padding-right: 25px; -} - -#right -{ - width: 350px; - float: right; - padding-left: 25px; -} - -.align-left -{ - text-align: left; -} - -.align-right -{ - text-align: right; -} - -.align-center -{ - text-align: center; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -ul.links li -{ - list-style-type: none; - font-size: 14px; -} - -form -{ - border-style: none; -} - -fieldset -{ - border-style: none; -} - -input -{ - color: #222; - border: 1px solid #ccc; - font-family: sans-serif; - font-size: 12px; - line-height: 16px; -} - -input[type=text], input[type=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid-small.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid-small.png deleted file mode 100644 index a5bc0ade7..000000000 Binary files a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid-small.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid.png b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid.png deleted file mode 100644 index 347e05549..000000000 Binary files a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/pyramid.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/transparent.gif b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/transparent.gif deleted file mode 100644 index 0341802e5..000000000 Binary files a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/static/transparent.gif and /dev/null differ diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/templates/mytemplate.pt b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/templates/mytemplate.pt deleted file mode 100644 index 2de66d4c9..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/templates/mytemplate.pt +++ /dev/null @@ -1,76 +0,0 @@ - - - - The Pyramid Web Framework - - - - - - - - - - -
-
-
-
pyramid
-
-
-
-
-

- Welcome to ${project}, an application generated by
- the Pyramid Web Framework. -

-
-
-
-
-
-

Search documentation

-
- - -
-
- -
-
-
- - - diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/tests.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/tests.py deleted file mode 100644 index e2789665b..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/tests.py +++ /dev/null @@ -1,33 +0,0 @@ -import unittest -import transaction - -from pyramid import testing - -from .models import DBSession - - -class TestMyView(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - from sqlalchemy import create_engine - engine = create_engine('sqlite://') - from .models import ( - Base, - MyModel, - ) - DBSession.configure(bind=engine) - Base.metadata.create_all(engine) - with transaction.manager: - model = MyModel(name='one', value=55) - DBSession.add(model) - - def tearDown(self): - DBSession.remove() - testing.tearDown() - - def test_it(self): - from .views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'hello_sqlalchemy') diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/views.py b/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/views.py deleted file mode 100644 index 796acf738..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/hello_sqlalchemy/views.py +++ /dev/null @@ -1,44 +0,0 @@ -from pyramid.response import Response -from pyramid.view import view_config - -import colander -import deform - -from sqlalchemy.exc import DBAPIError - -from .models import ( - DBSession, - MyModel, - ) - -class MyForm(colander.MappingSchema): - title = colander.SchemaNode(colander.String()) - body = colander.SchemaNode( - colander.String(), - widget=deform.widget.RichTextWidget() - ) - -@view_config(route_name='home', renderer='templates/mytemplate.pt') -def my_view(request): - try: - one = DBSession.query(MyModel).filter(MyModel.name == 'one').first() - except DBAPIError: - return Response(conn_err_msg, content_type='text/plain', status_int=500) - return {'one': one, 'project': 'hello_sqlalchemy'} - -conn_err_msg = """\ -Pyramid is having a problem using your SQL database. The problem -might be caused by one of the following things: - -1. You may need to run the "initialize_hello_sqlalchemy_db" script - to initialize your database tables. Check your virtual - environment's "bin" directory for this script and try to run it. - -2. Your database server may not be running. Check that the - database server referred to by the "sqlalchemy.url" setting in - your "development.ini" file is running. - -After you fix the problem, please restart the Pyramid application to -try it again. -""" - diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/production.ini b/docs/getting_started/quick_glance/hello_sqlalchemy/production.ini deleted file mode 100644 index 3257d0067..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/production.ini +++ /dev/null @@ -1,62 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### - -[app:main] -use = egg:hello_sqlalchemy - -pyramid.reload_templates = false -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm - -sqlalchemy.url = sqlite:///%(here)s/hello_sqlalchemy.sqlite - -[server:main] -use = egg:waitress#main -host = 0.0.0.0 -port = 6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, hello_sqlalchemy, sqlalchemy - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console - -[logger_hello_sqlalchemy] -level = WARN -handlers = -qualname = hello_sqlalchemy - -[logger_sqlalchemy] -level = WARN -handlers = -qualname = sqlalchemy.engine -# "level = INFO" logs SQL queries. -# "level = DEBUG" logs SQL queries and results. -# "level = WARN" logs neither. (Recommended for production systems.) - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/setup.cfg b/docs/getting_started/quick_glance/hello_sqlalchemy/setup.cfg deleted file mode 100644 index d08bf9c9b..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=hello_sqlalchemy -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = hello_sqlalchemy/locale -domain = hello_sqlalchemy -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = hello_sqlalchemy/locale/hello_sqlalchemy.pot -width = 80 - -[init_catalog] -domain = hello_sqlalchemy -input_file = hello_sqlalchemy/locale/hello_sqlalchemy.pot -output_dir = hello_sqlalchemy/locale - -[update_catalog] -domain = hello_sqlalchemy -input_file = hello_sqlalchemy/locale/hello_sqlalchemy.pot -output_dir = hello_sqlalchemy/locale -previous = true diff --git a/docs/getting_started/quick_glance/hello_sqlalchemy/setup.py b/docs/getting_started/quick_glance/hello_sqlalchemy/setup.py deleted file mode 100644 index f4e1f48c0..000000000 --- a/docs/getting_started/quick_glance/hello_sqlalchemy/setup.py +++ /dev/null @@ -1,44 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'pyramid', - 'SQLAlchemy', - 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', - 'zope.sqlalchemy', - 'waitress', - ] - -setup(name='hello_sqlalchemy', - version='0.0', - description='hello_sqlalchemy', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - test_suite='hello_sqlalchemy', - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = hello_sqlalchemy:main - [console_scripts] - initialize_hello_sqlalchemy_db = hello_sqlalchemy.scripts.initializedb:main - """, - ) diff --git a/docs/getting_started/quick_glance/package/development.ini b/docs/getting_started/quick_glance/package/development.ini index 9aa5f40cf..a751ff903 100644 --- a/docs/getting_started/quick_glance/package/development.ini +++ b/docs/getting_started/quick_glance/package/development.ini @@ -1,5 +1,7 @@ +# Start Includes [app:hello_world] pyramid.includes = pyramid_debugtoolbar +# End Includes use = egg:hello_world reload_templates = true debug_authorization = false @@ -22,9 +24,16 @@ port = 6543 # Begin logging configuration +# Start Sphinx Include [loggers] keys = root, hello_world +[logger_hello_world] +level = DEBUG +handlers = +qualname = hello_world +# End Sphinx Include + [handlers] keys = console @@ -35,10 +44,6 @@ keys = generic level = INFO handlers = console -[logger_hello_world] -level = DEBUG -handlers = -qualname = hello_world [handler_console] class = StreamHandler diff --git a/docs/getting_started/quick_glance/package/hello_world/__init__.py b/docs/getting_started/quick_glance/package/hello_world/__init__.py index 9b5753c26..6e66bf40a 100644 --- a/docs/getting_started/quick_glance/package/hello_world/__init__.py +++ b/docs/getting_started/quick_glance/package/hello_world/__init__.py @@ -1,5 +1,9 @@ from pyramid.config import Configurator from pyramid_jinja2 import renderer_factory +# Start Sphinx Include 1 +from pyramid.session import UnencryptedCookieSessionFactoryConfig +# End Sphinx Include 1 + from hello_world.models import get_root def main(global_config, **settings): @@ -11,9 +15,16 @@ def main(global_config, **settings): settings = dict(settings) settings.setdefault('jinja2.i18n.domain', 'hello_world') - config = Configurator(root_factory=get_root, settings=settings) + # Start Sphinx Include 2 + my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet') + config = Configurator(root_factory=get_root, settings=settings, + session_factory=my_session_factory) + # End Sphinx Include 2 config.add_translation_dirs('locale/') + # Start Include config.include('pyramid_jinja2') + # End Include + config.add_static_view('static', 'static') config.add_view('hello_world.views.my_view', diff --git a/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 b/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 index 998edfe12..25a28ed7a 100644 --- a/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 +++ b/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 @@ -35,7 +35,10 @@

{% trans %}Hello!{% endtrans %}

-

Request performed with {{ request.locale_name }} locale.

+ +

Counter: {{ request.session.counter }}

+ +

Request performed with {{ request.locale_name }} locale.

diff --git a/docs/getting_started/quick_glance/package/hello_world/tests.py b/docs/getting_started/quick_glance/package/hello_world/tests.py index a81c29eb0..ccec14f70 100644 --- a/docs/getting_started/quick_glance/package/hello_world/tests.py +++ b/docs/getting_started/quick_glance/package/hello_world/tests.py @@ -18,4 +18,3 @@ class ViewTests(unittest.TestCase): request = testing.DummyRequest() response = my_view(request) self.assertEqual(response['project'], 'hello_world') - diff --git a/docs/getting_started/quick_glance/package/hello_world/views.py b/docs/getting_started/quick_glance/package/hello_world/views.py index c271d45dd..109c260ad 100644 --- a/docs/getting_started/quick_glance/package/hello_world/views.py +++ b/docs/getting_started/quick_glance/package/hello_world/views.py @@ -1,6 +1,22 @@ +# Start Logging 1 +import logging +log = logging.getLogger(__name__) +# End Logging 1 + from pyramid.i18n import TranslationStringFactory _ = TranslationStringFactory('hello_world') + def my_view(request): - return {'project':'hello_world'} + # Start Logging 2 + log.debug('Some Message') + # End Logging 2 + # Start Sphinx Include 1 + session = request.session + if 'counter' in session: + session['counter'] += 1 + else: + session['counter'] = 0 + # End Sphinx Include 1 + return {'project': 'hello_world'} diff --git a/docs/getting_started/quick_glance/package/setup.py b/docs/getting_started/quick_glance/package/setup.py index 6269accf1..f118ed5fb 100644 --- a/docs/getting_started/quick_glance/package/setup.py +++ b/docs/getting_started/quick_glance/package/setup.py @@ -6,7 +6,9 @@ here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, 'README.txt')).read() CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() +# Start Requires requires = ['pyramid>=1.0.2', 'pyramid_jinja2', 'pyramid_debugtoolbar'] +# End Requires setup(name='hello_world', version='0.0', diff --git a/docs/getting_started/quick_glance/sqla_demo/CHANGES.txt b/docs/getting_started/quick_glance/sqla_demo/CHANGES.txt new file mode 100644 index 000000000..35a34f332 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version diff --git a/docs/getting_started/quick_glance/sqla_demo/MANIFEST.in b/docs/getting_started/quick_glance/sqla_demo/MANIFEST.in new file mode 100644 index 000000000..a432577e9 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include sqla_demo *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/getting_started/quick_glance/sqla_demo/README.txt b/docs/getting_started/quick_glance/sqla_demo/README.txt new file mode 100644 index 000000000..f35d3aec5 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/README.txt @@ -0,0 +1,14 @@ +sqla_demo README +================== + +Getting Started +--------------- + +- cd + +- $venv/bin/python setup.py develop + +- $venv/bin/initialize_sqla_demo_db development.ini + +- $venv/bin/pserve development.ini + diff --git a/docs/getting_started/quick_glance/sqla_demo/development.ini b/docs/getting_started/quick_glance/sqla_demo/development.ini new file mode 100644 index 000000000..174468abf --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/development.ini @@ -0,0 +1,71 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:sqla_demo + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm + +sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite + +# By default, the toolbar only appears for clients from IP addresses +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +host = 0.0.0.0 +port = 6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, sqla_demo, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_sqla_demo] +level = DEBUG +handlers = +qualname = sqla_demo + +[logger_sqlalchemy] +level = INFO +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/getting_started/quick_glance/sqla_demo/production.ini b/docs/getting_started/quick_glance/sqla_demo/production.ini new file mode 100644 index 000000000..dc0ba304f --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/production.ini @@ -0,0 +1,62 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:sqla_demo + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_tm + +sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite + +[server:main] +use = egg:waitress#main +host = 0.0.0.0 +port = 6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, sqla_demo, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_sqla_demo] +level = WARN +handlers = +qualname = sqla_demo + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/getting_started/quick_glance/sqla_demo/setup.cfg b/docs/getting_started/quick_glance/sqla_demo/setup.cfg new file mode 100644 index 000000000..9f91cd122 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/setup.cfg @@ -0,0 +1,27 @@ +[nosetests] +match=^test +nocapture=1 +cover-package=sqla_demo +with-coverage=1 +cover-erase=1 + +[compile_catalog] +directory = sqla_demo/locale +domain = sqla_demo +statistics = true + +[extract_messages] +add_comments = TRANSLATORS: +output_file = sqla_demo/locale/sqla_demo.pot +width = 80 + +[init_catalog] +domain = sqla_demo +input_file = sqla_demo/locale/sqla_demo.pot +output_dir = sqla_demo/locale + +[update_catalog] +domain = sqla_demo +input_file = sqla_demo/locale/sqla_demo.pot +output_dir = sqla_demo/locale +previous = true diff --git a/docs/getting_started/quick_glance/sqla_demo/setup.py b/docs/getting_started/quick_glance/sqla_demo/setup.py new file mode 100644 index 000000000..ac2eed035 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/setup.py @@ -0,0 +1,44 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +README = open(os.path.join(here, 'README.txt')).read() +CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + +requires = [ + 'pyramid', + 'SQLAlchemy', + 'transaction', + 'pyramid_tm', + 'pyramid_debugtoolbar', + 'zope.sqlalchemy', + 'waitress', + ] + +setup(name='sqla_demo', + version='0.0', + description='sqla_demo', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web wsgi bfg pylons pyramid', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + test_suite='sqla_demo', + install_requires=requires, + entry_points="""\ + [paste.app_factory] + main = sqla_demo:main + [console_scripts] + initialize_sqla_demo_db = sqla_demo.scripts.initializedb:main + """, + ) diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo.sqlite b/docs/getting_started/quick_glance/sqla_demo/sqla_demo.sqlite new file mode 100644 index 000000000..fa6adb104 Binary files /dev/null and b/docs/getting_started/quick_glance/sqla_demo/sqla_demo.sqlite differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/__init__.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/__init__.py new file mode 100644 index 000000000..aac7c5e69 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/__init__.py @@ -0,0 +1,20 @@ +from pyramid.config import Configurator +from sqlalchemy import engine_from_config + +from .models import ( + DBSession, + Base, + ) + + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.bind = engine + config = Configurator(settings=settings) + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + config.scan() + return config.make_wsgi_app() diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/models.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/models.py new file mode 100644 index 000000000..3dfb40e58 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/models.py @@ -0,0 +1,29 @@ +from sqlalchemy import ( + Column, + Integer, + Text, + ) + +from sqlalchemy.ext.declarative import declarative_base + +from sqlalchemy.orm import ( + scoped_session, + sessionmaker, + ) + +from zope.sqlalchemy import ZopeTransactionExtension + +DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) +Base = declarative_base() + +# Start Sphinx Include +class MyModel(Base): + __tablename__ = 'models' + id = Column(Integer, primary_key=True) + name = Column(Text, unique=True) + value = Column(Integer) + + def __init__(self, name, value): + self.name = name + self.value = value + # End Sphinx Include diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/__init__.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/__init__.py @@ -0,0 +1 @@ +# package diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/initializedb.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/initializedb.py new file mode 100644 index 000000000..66feb3008 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/initializedb.py @@ -0,0 +1,37 @@ +import os +import sys +import transaction + +from sqlalchemy import engine_from_config + +from pyramid.paster import ( + get_appsettings, + setup_logging, + ) + +from ..models import ( + DBSession, + MyModel, + Base, + ) + + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s \n' + '(example: "%s development.ini")' % (cmd, cmd)) + sys.exit(1) + + +def main(argv=sys.argv): + if len(argv) != 2: + usage(argv) + config_uri = argv[1] + setup_logging(config_uri) + settings = get_appsettings(config_uri) + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.create_all(engine) + with transaction.manager: + model = MyModel(name='one', value=1) + DBSession.add(model) diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/favicon.ico b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/favicon.ico new file mode 100644 index 000000000..71f837c9e Binary files /dev/null and b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/favicon.ico differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/footerbg.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/footerbg.png new file mode 100644 index 000000000..1fbc873da Binary files /dev/null and b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/footerbg.png differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/headerbg.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/headerbg.png new file mode 100644 index 000000000..0596f2020 Binary files /dev/null and b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/headerbg.png differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/ie6.css b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/middlebg.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/middlebg.png new file mode 100644 index 000000000..2369cfb7d Binary files /dev/null and b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/middlebg.png differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pylons.css b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pylons.css new file mode 100644 index 000000000..4b1c017cd --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pylons.css @@ -0,0 +1,372 @@ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td +{ + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; /* 16px */ + vertical-align: baseline; + background: transparent; +} + +body +{ + line-height: 1; +} + +ol, ul +{ + list-style: none; +} + +blockquote, q +{ + quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after +{ + content: ''; + content: none; +} + +:focus +{ + outline: 0; +} + +ins +{ + text-decoration: none; +} + +del +{ + text-decoration: line-through; +} + +table +{ + border-collapse: collapse; + border-spacing: 0; +} + +sub +{ + vertical-align: sub; + font-size: smaller; + line-height: normal; +} + +sup +{ + vertical-align: super; + font-size: smaller; + line-height: normal; +} + +ul, menu, dir +{ + display: block; + list-style-type: disc; + margin: 1em 0; + padding-left: 40px; +} + +ol +{ + display: block; + list-style-type: decimal-leading-zero; + margin: 1em 0; + padding-left: 40px; +} + +li +{ + display: list-item; +} + +ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl +{ + margin-top: 0; + margin-bottom: 0; +} + +ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir +{ + list-style-type: circle; +} + +ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir +{ + list-style-type: square; +} + +.hidden +{ + display: none; +} + +p +{ + line-height: 1.5em; +} + +h1 +{ + font-size: 1.75em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h2 +{ + font-size: 1.5em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h3 +{ + font-size: 1.25em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h4 +{ + font-size: 1em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +html, body +{ + width: 100%; + height: 100%; +} + +body +{ + margin: 0; + padding: 0; + background-color: #fff; + position: relative; + font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; +} + +a +{ + color: #1b61d6; + text-decoration: none; +} + +a:hover +{ + color: #e88f00; + text-decoration: underline; +} + +body h1, body h2, body h3, body h4, body h5, body h6 +{ + font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; + font-weight: 400; + color: #373839; + font-style: normal; +} + +#wrap +{ + min-height: 100%; +} + +#header, #footer +{ + width: 100%; + color: #fff; + height: 40px; + position: absolute; + text-align: center; + line-height: 40px; + overflow: hidden; + font-size: 12px; + vertical-align: middle; +} + +#header +{ + background: #000; + top: 0; + font-size: 14px; +} + +#footer +{ + bottom: 0; + background: #000 url(footerbg.png) repeat-x 0 top; + position: relative; + margin-top: -40px; + clear: both; +} + +.header, .footer +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.wrapper +{ + width: 100%; +} + +#top, #top-small, #bottom +{ + width: 100%; +} + +#top +{ + color: #000; + height: 230px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#top-small +{ + color: #000; + height: 60px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#bottom +{ + color: #222; + background-color: #fff; +} + +.top, .top-small, .middle, .bottom +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.top +{ + padding-top: 40px; +} + +.top-small +{ + padding-top: 10px; +} + +#middle +{ + width: 100%; + height: 100px; + background: url(middlebg.png) repeat-x; + border-top: 2px solid #fff; + border-bottom: 2px solid #b2b2b2; +} + +.app-welcome +{ + margin-top: 25px; +} + +.app-name +{ + color: #000; + font-weight: 700; +} + +.bottom +{ + padding-top: 50px; +} + +#left +{ + width: 350px; + float: left; + padding-right: 25px; +} + +#right +{ + width: 350px; + float: right; + padding-left: 25px; +} + +.align-left +{ + text-align: left; +} + +.align-right +{ + text-align: right; +} + +.align-center +{ + text-align: center; +} + +ul.links +{ + margin: 0; + padding: 0; +} + +ul.links li +{ + list-style-type: none; + font-size: 14px; +} + +form +{ + border-style: none; +} + +fieldset +{ + border-style: none; +} + +input +{ + color: #222; + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 12px; + line-height: 16px; +} + +input[type=text], input[type=password] +{ + width: 205px; +} + +input[type=submit] +{ + background-color: #ddd; + font-weight: 700; +} + +/*Opera Fix*/ +body:before +{ + content: ""; + height: 100%; + float: left; + width: 0; + margin-top: -32767px; +} diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid-small.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid-small.png new file mode 100644 index 000000000..a5bc0ade7 Binary files /dev/null and b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid-small.png differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid.png new file mode 100644 index 000000000..347e05549 Binary files /dev/null and b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid.png differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/transparent.gif b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/transparent.gif new file mode 100644 index 000000000..0341802e5 Binary files /dev/null and b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/transparent.gif differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/templates/mytemplate.pt b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/templates/mytemplate.pt new file mode 100644 index 000000000..e0ac9d440 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/templates/mytemplate.pt @@ -0,0 +1,76 @@ + + + + The Pyramid Web Application Development Framework + + + + + + + + + + +
+
+
+
pyramid
+
+
+
+
+

+ Welcome to ${project}, an application generated by
+ the Pyramid web application development framework. +

+
+
+
+
+
+

Search documentation

+
+ + +
+
+ +
+
+
+ + + diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/tests.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/tests.py new file mode 100644 index 000000000..6fef6d695 --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/tests.py @@ -0,0 +1,33 @@ +import unittest +import transaction + +from pyramid import testing + +from .models import DBSession + + +class TestMyView(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + from sqlalchemy import create_engine + engine = create_engine('sqlite://') + from .models import ( + Base, + MyModel, + ) + DBSession.configure(bind=engine) + Base.metadata.create_all(engine) + with transaction.manager: + model = MyModel(name='one', value=55) + DBSession.add(model) + + def tearDown(self): + DBSession.remove() + testing.tearDown() + + def test_it(self): + from .views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['one'].name, 'one') + self.assertEqual(info['project'], 'sqla_demo') diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/views.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/views.py new file mode 100644 index 000000000..768a7e42e --- /dev/null +++ b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/views.py @@ -0,0 +1,37 @@ +from pyramid.response import Response +from pyramid.view import view_config + +from sqlalchemy.exc import DBAPIError + +from .models import ( + DBSession, + MyModel, + ) + + +@view_config(route_name='home', renderer='templates/mytemplate.pt') +def my_view(request): + try: + # Start Sphinx Include + one = DBSession.query(MyModel).filter(MyModel.name == 'one').first() + # End Sphinx Include + except DBAPIError: + return Response(conn_err_msg, content_type='text/plain', status_int=500) + return {'one': one, 'project': 'sqla_demo'} + +conn_err_msg = """\ +Pyramid is having a problem using your SQL database. The problem +might be caused by one of the following things: + +1. You may need to run the "initialize_sqla_demo_db" script + to initialize your database tables. Check your virtual + environment's "bin" directory for this script and try to run it. + +2. Your database server may not be running. Check that the + database server referred to by the "sqlalchemy.url" setting in + your "development.ini" file is running. + +After you fix the problem, please restart the Pyramid application to +try it again. +""" + diff --git a/docs/getting_started/top_ten.rst b/docs/getting_started/top_ten.rst index a11d2898c..e207f4ce1 100644 --- a/docs/getting_started/top_ten.rst +++ b/docs/getting_started/top_ten.rst @@ -2,31 +2,40 @@ Top Killer Features In Pyramid ============================== -"Making your own framework" - -- Transactions +As a regular developer - Configuration - - config.include +- Route factories and contexts -- Advanced views and view predicates +- Advanced view configuration -Custom views -============ +- Route prefixes -- Corneice does this +- Asset specifications - Events -- Ordered routes - - Custom renderers - Tweens -- Asset specifications +- Transactions - Traversal -- Transactions \ No newline at end of file +- Custom directives + +- config.include + +- Extensible applications + + - Overridable views, routes, and assets + + - config.include + + - Events + + - Distributing an add-on + + - "Making your own framework", Extensibility diff --git a/docs/getting_started/views.rst b/docs/getting_started/views.rst index 827778a66..f30caea8a 100644 --- a/docs/getting_started/views.rst +++ b/docs/getting_started/views.rst @@ -17,22 +17,12 @@ person, then editing that person or perhaps deleting that person. They might logically belong together. We could do these as independent functions, but let's do them together as a view class: -.. literalinclude:: quick_glance/view_classes/views.py - :start-after: Start View 1 - :end-before: End View 1 ...and some routes that wire up the views to URLs: -.. literalinclude:: quick_glance/view_classes/app.py - :start-after: Start Routes 1 - :end-before: End Routes 1 ...and a form in ``hello_world.jinja2`` that submits to the second view: -.. literalinclude:: quick_glance/view_classes/hello_world.jinja2 - :language: html - :start-after: Start Form 1 - :end-before: End Form 1 Just to review: -- cgit v1.2.3 From c65b8506954a094f08a3191c76066a459c084a93 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Sat, 10 Aug 2013 22:22:37 +0200 Subject: No cookies on other domain with parent_domain --- pyramid/authentication.py | 14 +++++++------- pyramid/tests/test_authentication.py | 25 ++++++++++--------------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/pyramid/authentication.py b/pyramid/authentication.py index c1aa970bd..565393a34 100644 --- a/pyramid/authentication.py +++ b/pyramid/authentication.py @@ -865,22 +865,22 @@ class AuthTktCookieHelper(object): if ':' in cur_domain: cur_domain = cur_domain.split(':', 1)[0] - cookies = [ - ('Set-Cookie', '%s="%s"; Path=%s%s%s' % ( - self.cookie_name, value, self.path, max_age, self.static_flags)) - ] domains = [] if self.parent_domain and cur_domain.count('.') > 1: domains.append('.' + cur_domain.split('.', 1)[1]) else: + domains.append(None) domains.append(cur_domain) if self.wild_domain: domains.append('.' + cur_domain) + + cookies = [] + base_cookie = '%s="%s"; Path=%s%s%s' % (self.cookie_name, value, + self.path, max_age, self.static_flags) for domain in domains: - cookies.append(('Set-Cookie', '%s="%s"; Path=%s; Domain=%s%s%s' % ( - self.cookie_name, value, self.path, domain, max_age, - self.static_flags))) + domain = '; Domain=%s' % domain if domain is not None else '' + cookies.append(('Set-Cookie', '%s%s' % (base_cookie, domain))) return cookies diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py index 960a87a6a..d787d09b7 100644 --- a/pyramid/tests/test_authentication.py +++ b/pyramid/tests/test_authentication.py @@ -908,11 +908,11 @@ class TestAuthTktCookieHelper(unittest.TestCase): self.assertTrue(result[0][1].startswith('auth_tkt=')) self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue(result[1][1].endswith('; HttpOnly')) + self.assertTrue('; HttpOnly' in result[1][1]) self.assertTrue(result[1][1].startswith('auth_tkt=')) self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue(result[2][1].endswith('; HttpOnly')) + self.assertTrue('; HttpOnly' in result[2][1]) self.assertTrue(result[2][1].startswith('auth_tkt=')) def test_remember_secure(self): @@ -952,24 +952,19 @@ class TestAuthTktCookieHelper(unittest.TestCase): request = self._makeRequest() request.environ['HTTP_HOST'] = 'www.example.com' result = helper.remember(request, 'other') - self.assertEqual(len(result), 2) + self.assertEqual(len(result), 1) self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith('; Path=/')) + self.assertTrue(result[0][1].endswith('; Path=/; Domain=.example.com')) self.assertTrue(result[0][1].startswith('auth_tkt=')) - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue(result[1][1].endswith('; Path=/; Domain=.example.com')) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - def test_remember_parent_domain_supercedes_wild_domain(self): helper = self._makeOne('secret', parent_domain=True, wild_domain=True) request = self._makeRequest() request.environ['HTTP_HOST'] = 'www.example.com' result = helper.remember(request, 'other') - self.assertEqual(len(result), 2) - self.assertTrue(result[0][1].endswith('; Path=/')) - self.assertTrue(result[1][1].endswith('; Path=/; Domain=.example.com')) + self.assertEqual(len(result), 1) + self.assertTrue(result[0][1].endswith('; Domain=.example.com')) def test_remember_domain_has_port(self): helper = self._makeOne('secret', wild_domain=False) @@ -1102,13 +1097,13 @@ class TestAuthTktCookieHelper(unittest.TestCase): name, value = headers[1] self.assertEqual(name, 'Set-Cookie') self.assertEqual(value, - 'auth_tkt=""; Path=/; Domain=localhost; Max-Age=0; ' - 'Expires=Wed, 31-Dec-97 23:59:59 GMT') + 'auth_tkt=""; Path=/; Max-Age=0; ' + 'Expires=Wed, 31-Dec-97 23:59:59 GMT; Domain=localhost') name, value = headers[2] self.assertEqual(name, 'Set-Cookie') self.assertEqual(value, - 'auth_tkt=""; Path=/; Domain=.localhost; Max-Age=0; ' - 'Expires=Wed, 31-Dec-97 23:59:59 GMT') + 'auth_tkt=""; Path=/; Max-Age=0; ' + 'Expires=Wed, 31-Dec-97 23:59:59 GMT; Domain=.localhost') class TestAuthTicket(unittest.TestCase): def _makeOne(self, *arg, **kw): -- cgit v1.2.3 From ae901436a61563968cc31cc636f1fbeb5e85b528 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Sun, 11 Aug 2013 09:53:00 -0400 Subject: Per discussion with Chris, just wrap up "getting started" as the Quick Tour. Still need to do more linking and perhaps add a section on root factories, authorization, authentication. --- docs/getting_started/configuration.rst | 4 - docs/getting_started/databases.rst | 21 - docs/getting_started/forms.rst | 3 - docs/getting_started/gettingstarted.rst | 84 --- docs/getting_started/index.rst | 60 -- docs/getting_started/internationalization.rst | 3 - docs/getting_started/json.rst | 4 - docs/getting_started/pserve.rst | 18 - docs/getting_started/quick_glance.rst | 806 --------------------- .../quick_glance/hello_world/app.py | 16 - docs/getting_started/quick_glance/jinja2/app.py | 11 - .../quick_glance/jinja2/hello_world.jinja2 | 8 - docs/getting_started/quick_glance/jinja2/views.py | 8 - docs/getting_started/quick_glance/json/app.py | 15 - .../quick_glance/json/hello_world.jinja2 | 10 - .../quick_glance/json/hello_world.pt | 17 - docs/getting_started/quick_glance/json/views.py | 13 - .../quick_glance/package/CHANGES.txt | 4 - .../quick_glance/package/MANIFEST.in | 2 - .../quick_glance/package/README.txt | 4 - .../quick_glance/package/development.ini | 57 -- .../quick_glance/package/hello_world/__init__.py | 34 - .../locale/de/LC_MESSAGES/hello_world.mo | Bin 460 -> 0 bytes .../locale/de/LC_MESSAGES/hello_world.po | 21 - .../locale/fr/LC_MESSAGES/hello_world.mo | Bin 461 -> 0 bytes .../locale/fr/LC_MESSAGES/hello_world.po | 21 - .../package/hello_world/locale/hello_world.pot | 21 - .../quick_glance/package/hello_world/models.py | 8 - .../package/hello_world/static/favicon.ico | Bin 1406 -> 0 bytes .../package/hello_world/static/logo.png | Bin 6641 -> 0 bytes .../package/hello_world/static/pylons.css | 73 -- .../hello_world/templates/mytemplate.jinja2 | 90 --- .../quick_glance/package/hello_world/tests.py | 20 - .../quick_glance/package/hello_world/views.py | 22 - .../quick_glance/package/message-extraction.ini | 3 - .../getting_started/quick_glance/package/setup.cfg | 28 - docs/getting_started/quick_glance/package/setup.py | 41 -- docs/getting_started/quick_glance/requests/app.py | 24 - docs/getting_started/quick_glance/routing/app.py | 12 - docs/getting_started/quick_glance/routing/views.py | 10 - .../quick_glance/sqla_demo/CHANGES.txt | 4 - .../quick_glance/sqla_demo/MANIFEST.in | 2 - .../quick_glance/sqla_demo/README.txt | 14 - .../quick_glance/sqla_demo/development.ini | 71 -- .../quick_glance/sqla_demo/production.ini | 62 -- .../quick_glance/sqla_demo/setup.cfg | 27 - .../quick_glance/sqla_demo/setup.py | 44 -- .../quick_glance/sqla_demo/sqla_demo.sqlite | Bin 3072 -> 0 bytes .../quick_glance/sqla_demo/sqla_demo/__init__.py | 20 - .../quick_glance/sqla_demo/sqla_demo/models.py | 29 - .../sqla_demo/sqla_demo/scripts/__init__.py | 1 - .../sqla_demo/sqla_demo/scripts/initializedb.py | 37 - .../sqla_demo/sqla_demo/static/favicon.ico | Bin 1406 -> 0 bytes .../sqla_demo/sqla_demo/static/footerbg.png | Bin 333 -> 0 bytes .../sqla_demo/sqla_demo/static/headerbg.png | Bin 203 -> 0 bytes .../sqla_demo/sqla_demo/static/ie6.css | 8 - .../sqla_demo/sqla_demo/static/middlebg.png | Bin 2797 -> 0 bytes .../sqla_demo/sqla_demo/static/pylons.css | 372 ---------- .../sqla_demo/sqla_demo/static/pyramid-small.png | Bin 7044 -> 0 bytes .../sqla_demo/sqla_demo/static/pyramid.png | Bin 33055 -> 0 bytes .../sqla_demo/sqla_demo/static/transparent.gif | Bin 49 -> 0 bytes .../sqla_demo/sqla_demo/templates/mytemplate.pt | 76 -- .../quick_glance/sqla_demo/sqla_demo/tests.py | 33 - .../quick_glance/sqla_demo/sqla_demo/views.py | 37 - .../quick_glance/static_assets/app.py | 14 - .../quick_glance/static_assets/hello_world.jinja2 | 10 - .../quick_glance/static_assets/hello_world.pt | 16 - .../quick_glance/static_assets/static/app.css | 4 - .../quick_glance/static_assets/views.py | 6 - .../getting_started/quick_glance/templating/app.py | 10 - .../quick_glance/templating/hello_world.pt | 9 - .../quick_glance/templating/views.py | 8 - .../quick_glance/view_classes/app.py | 13 - .../quick_glance/view_classes/delete.jinja2 | 9 - .../quick_glance/view_classes/edit.jinja2 | 9 - .../quick_glance/view_classes/hello.jinja2 | 17 - .../quick_glance/view_classes/views.py | 32 - docs/getting_started/quick_glance/views/app.py | 13 - docs/getting_started/quick_glance/views/views.py | 29 - docs/getting_started/routes.rst | 3 - docs/getting_started/scaffolds.rst | 110 --- docs/getting_started/security.rst | 3 - docs/getting_started/sessions.rst | 3 - docs/getting_started/special_views.rst | 3 - docs/getting_started/static_assets.rst | 4 - docs/getting_started/templates.rst | 4 - docs/getting_started/testing.rst | 4 - docs/getting_started/top_ten.rst | 41 -- docs/getting_started/views.rst | 30 - docs/index.rst | 42 +- docs/quick_tour.rst | 789 ++++++++++++++++++++ 91 files changed, 810 insertions(+), 2858 deletions(-) delete mode 100644 docs/getting_started/configuration.rst delete mode 100644 docs/getting_started/databases.rst delete mode 100644 docs/getting_started/forms.rst delete mode 100644 docs/getting_started/gettingstarted.rst delete mode 100644 docs/getting_started/index.rst delete mode 100644 docs/getting_started/internationalization.rst delete mode 100644 docs/getting_started/json.rst delete mode 100644 docs/getting_started/pserve.rst delete mode 100644 docs/getting_started/quick_glance.rst delete mode 100644 docs/getting_started/quick_glance/hello_world/app.py delete mode 100644 docs/getting_started/quick_glance/jinja2/app.py delete mode 100644 docs/getting_started/quick_glance/jinja2/hello_world.jinja2 delete mode 100644 docs/getting_started/quick_glance/jinja2/views.py delete mode 100644 docs/getting_started/quick_glance/json/app.py delete mode 100644 docs/getting_started/quick_glance/json/hello_world.jinja2 delete mode 100644 docs/getting_started/quick_glance/json/hello_world.pt delete mode 100644 docs/getting_started/quick_glance/json/views.py delete mode 100644 docs/getting_started/quick_glance/package/CHANGES.txt delete mode 100644 docs/getting_started/quick_glance/package/MANIFEST.in delete mode 100644 docs/getting_started/quick_glance/package/README.txt delete mode 100644 docs/getting_started/quick_glance/package/development.ini delete mode 100644 docs/getting_started/quick_glance/package/hello_world/__init__.py delete mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo delete mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po delete mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo delete mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po delete mode 100644 docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot delete mode 100644 docs/getting_started/quick_glance/package/hello_world/models.py delete mode 100644 docs/getting_started/quick_glance/package/hello_world/static/favicon.ico delete mode 100644 docs/getting_started/quick_glance/package/hello_world/static/logo.png delete mode 100644 docs/getting_started/quick_glance/package/hello_world/static/pylons.css delete mode 100644 docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 delete mode 100644 docs/getting_started/quick_glance/package/hello_world/tests.py delete mode 100644 docs/getting_started/quick_glance/package/hello_world/views.py delete mode 100644 docs/getting_started/quick_glance/package/message-extraction.ini delete mode 100644 docs/getting_started/quick_glance/package/setup.cfg delete mode 100644 docs/getting_started/quick_glance/package/setup.py delete mode 100644 docs/getting_started/quick_glance/requests/app.py delete mode 100644 docs/getting_started/quick_glance/routing/app.py delete mode 100644 docs/getting_started/quick_glance/routing/views.py delete mode 100644 docs/getting_started/quick_glance/sqla_demo/CHANGES.txt delete mode 100644 docs/getting_started/quick_glance/sqla_demo/MANIFEST.in delete mode 100644 docs/getting_started/quick_glance/sqla_demo/README.txt delete mode 100644 docs/getting_started/quick_glance/sqla_demo/development.ini delete mode 100644 docs/getting_started/quick_glance/sqla_demo/production.ini delete mode 100644 docs/getting_started/quick_glance/sqla_demo/setup.cfg delete mode 100644 docs/getting_started/quick_glance/sqla_demo/setup.py delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo.sqlite delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/__init__.py delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/models.py delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/__init__.py delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/initializedb.py delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/favicon.ico delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/footerbg.png delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/headerbg.png delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/ie6.css delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/middlebg.png delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pylons.css delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid-small.png delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid.png delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/transparent.gif delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/templates/mytemplate.pt delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/tests.py delete mode 100644 docs/getting_started/quick_glance/sqla_demo/sqla_demo/views.py delete mode 100644 docs/getting_started/quick_glance/static_assets/app.py delete mode 100644 docs/getting_started/quick_glance/static_assets/hello_world.jinja2 delete mode 100644 docs/getting_started/quick_glance/static_assets/hello_world.pt delete mode 100644 docs/getting_started/quick_glance/static_assets/static/app.css delete mode 100644 docs/getting_started/quick_glance/static_assets/views.py delete mode 100644 docs/getting_started/quick_glance/templating/app.py delete mode 100644 docs/getting_started/quick_glance/templating/hello_world.pt delete mode 100644 docs/getting_started/quick_glance/templating/views.py delete mode 100644 docs/getting_started/quick_glance/view_classes/app.py delete mode 100644 docs/getting_started/quick_glance/view_classes/delete.jinja2 delete mode 100644 docs/getting_started/quick_glance/view_classes/edit.jinja2 delete mode 100644 docs/getting_started/quick_glance/view_classes/hello.jinja2 delete mode 100644 docs/getting_started/quick_glance/view_classes/views.py delete mode 100644 docs/getting_started/quick_glance/views/app.py delete mode 100644 docs/getting_started/quick_glance/views/views.py delete mode 100644 docs/getting_started/routes.rst delete mode 100644 docs/getting_started/scaffolds.rst delete mode 100644 docs/getting_started/security.rst delete mode 100644 docs/getting_started/sessions.rst delete mode 100644 docs/getting_started/special_views.rst delete mode 100644 docs/getting_started/static_assets.rst delete mode 100644 docs/getting_started/templates.rst delete mode 100644 docs/getting_started/testing.rst delete mode 100644 docs/getting_started/top_ten.rst delete mode 100644 docs/getting_started/views.rst create mode 100644 docs/quick_tour.rst diff --git a/docs/getting_started/configuration.rst b/docs/getting_started/configuration.rst deleted file mode 100644 index 30280c7e1..000000000 --- a/docs/getting_started/configuration.rst +++ /dev/null @@ -1,4 +0,0 @@ -============================================ -Managing Project Settings With Configuration -============================================ - diff --git a/docs/getting_started/databases.rst b/docs/getting_started/databases.rst deleted file mode 100644 index c415ed2db..000000000 --- a/docs/getting_started/databases.rst +++ /dev/null @@ -1,21 +0,0 @@ -========================= -Databases With SQLAlchemy -========================= - -We can now visit our sample at -`http://localhost:6543/ `_. Some choices that -the scaffold helped us with: - -- A ``setup.py`` with appropriate dependencies - -- Connection strings and integration in our ``development.ini`` file - -- A console script which we ran above to initialize the database - -- The SQLAlchemy engine integrated into the ``Configurator`` on - application startup - -- Python modules for the SQLAlchemy models and the Pyramid views that - go with them - -- Some unit tests...yummy! diff --git a/docs/getting_started/forms.rst b/docs/getting_started/forms.rst deleted file mode 100644 index 039bfbce4..000000000 --- a/docs/getting_started/forms.rst +++ /dev/null @@ -1,3 +0,0 @@ -================================ -Forms and Validation With Deform -================================ diff --git a/docs/getting_started/gettingstarted.rst b/docs/getting_started/gettingstarted.rst deleted file mode 100644 index 191a6a090..000000000 --- a/docs/getting_started/gettingstarted.rst +++ /dev/null @@ -1,84 +0,0 @@ -=============== -Getting Started -=============== - -What is Pyramid? ----------------- - -Pyramid is a web application development framework. Pyramid is lean, fast, -stable, well-tested, and thoroughly documented. Pyramid is written in Python, -and is open source software released under a `BSD-like license -`_. - -Pyramid helps you "start small, finish big". You can create a simple web -application using Pyramid with only basic knowledge. As you become more -familiar with Pyramid, you'll find there is plenty of room to grow. Code you -started with early on can be re-used in mature, large, powerful applications. - -Pyramid has dozens of features — URL generation, authentication and -authorization, [one or two more?] — just like any other web application -framework. Several features are unique and make Pyramid stand out from the -crowd. - -* Traversal -* Python 3 compatibility -* Tweens -* Debug Toolbar - -Installation Guide ------------------- -The Installation Guide describes how to install everything needed to get -started with Pyramid. It also offers practical advice on working with -projects. Whether you're new to Pyramid, Python, programming, or web -application development, the Installation Guide will help you get your first -Pyramid application up and running and deployed into production. - -Developer Guide ---------------- -The Developer Guide describes Pyramid in depth. Formerly called "narrative -documentation", the Developer Guide uses technical terms more familiar to the -seasoned web application developer. Beginners may be challenged, to put it -mildly, but it's a challenge worth accepting. Developers who have already -installed Pyramid, worked through a few tutorials, and are ready to write their -own applications will find that this guide offers a comprehensive understanding -of Pyramid. - -API Guide ---------- -The API Guide is a comprehensive reference for every public application -programming interface (API) exposed by Pyramid. The API Guide lists each item, -its arguments, definition, narrative description, its inner workings, and the -values and objects it returns in great detail. - -Tutorials and Screencasts -------------------------- -There are several tutorials and screencasts that give beginners and new-comers -to Pyramid hands-on experience with writing Pyramid applications. - -http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/ - -Add-ons -------- -Pyramid is extensible through add-ons. - -http://docs.pylonsproject.org/en/latest/docs/pyramid.html#pyramid-add-on-documentation - -Support -------- -https://github.com/Pylons/pylonsrtd/blob/master/index.rst#support - -Pylons-discuss Google group/mail list - -'#pyramid' IRC channel on irc.freenode.net - -issue tracker on GitHub http://github.com/Pylons/pyramid/issues - -Contributing ------------- -Guidelines for contributing to Pyramid are available at the following URL. - -https://github.com/Pylons/pylonsrtd/tree/master/community - -Community ---------- -http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/ diff --git a/docs/getting_started/index.rst b/docs/getting_started/index.rst deleted file mode 100644 index b7ab3c7bb..000000000 --- a/docs/getting_started/index.rst +++ /dev/null @@ -1,60 +0,0 @@ -============================ -Getting Started With Pyramid -============================ - -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 wanting a quick look at the major -features, this guide provides a convenient entry point with independent -chapters for each topic. - -About This Guide -================ - -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. - -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`. - -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`. - -Notes -===== - -- Cover static urls and asset specifications, resolving, replacing - -.. toctree:: - :maxdepth: 1 - - gettingstarted - - -Contents -======== - -.. toctree:: - :maxdepth: 2 - - quick_glance - scaffolds - configuration - routes - views - templates - static_assets - pserve - testing - forms - databases - security - json - sessions - internationalization - special_views - top_ten \ No newline at end of file diff --git a/docs/getting_started/internationalization.rst b/docs/getting_started/internationalization.rst deleted file mode 100644 index cc93406b1..000000000 --- a/docs/getting_started/internationalization.rst +++ /dev/null @@ -1,3 +0,0 @@ -============================================= -Multiple Languages Using Internationalization -============================================= diff --git a/docs/getting_started/json.rst b/docs/getting_started/json.rst deleted file mode 100644 index 006b44fc3..000000000 --- a/docs/getting_started/json.rst +++ /dev/null @@ -1,4 +0,0 @@ -================================= -Modern Web Development Using JSON -================================= - diff --git a/docs/getting_started/pserve.rst b/docs/getting_started/pserve.rst deleted file mode 100644 index a7f8ba62c..000000000 --- a/docs/getting_started/pserve.rst +++ /dev/null @@ -1,18 +0,0 @@ -=================================== -Application Running With ``pserve`` -=================================== - - -Three Cool Things About ``pserve`` ----------------------------------- - -1. *Multiple .ini files*. You might have some settings in - development mode or some in production mode. Maybe you are writing an - add-on that needs to be wired-up by other people. - -2. *Choice of WSGI server*. ``pserve`` itself isn't a WSGI server. - Instead, it loads the server you want from the configuration file. - -3. *Friends of pserve*. With the ``pserve``/``.ini`` approach you - also get other commands that help during development: ``pshell``, - ``proutes``, ``pviews``, ``prequest``, etc. diff --git a/docs/getting_started/quick_glance.rst b/docs/getting_started/quick_glance.rst deleted file mode 100644 index f9a60c0eb..000000000 --- a/docs/getting_started/quick_glance.rst +++ /dev/null @@ -1,806 +0,0 @@ -============ -Quick Glance -============ - -Pyramid lets you start small and finish big. This :doc:`index` guide -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. 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. - -Python Setup -============ - -First things first: we need our Python environment in ship-shape. -Pyramid encourages standard Python development practices (virtual -environments, packaging tools, logging, 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 - $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python - $ easy_install-3.3 pip - -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. - -Pyramid Installation -==================== - -We now have a standard starting point for Python. Getting Pyramid -installed is easy: - -.. code-block:: bash - - $ pip install pyramid - -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/hello_world/app.py - :linenos: - -This simple example is easy to run. Save this as ``app.py`` and run it: - -.. code-block:: bash - - $ python ./app.py - -Next, open `http://localhost:6543/ `_ in a -browser and you will see the ``Hello World!`` message. - -New to Python web programming? If so, some lines in module merit -explanation: - -#. *Line 10*. The ``if __name__ == '__main__':`` is Python's way of - saying "Start here when running from the command line". - -#. *Lines 11-13*. Use Pyramid's :term:`configurator` to connect - :term:`view` code to particular URL :term:`route`. - -#. *Lines 6-7*. Implement the view code that generates the - :term:`response`. - -#. *Lines 14-16*. Publish a :term:`WSGI` app using an HTTP server. - -As shown in this example, the :term:`configurator` plays a central role -in Pyramid development. Building an application from loosely-coupled -parts via :doc:`../narr/configuration` is a central idea in Pyramid, -one that we will revisit regurlarly in this *Getting Started* document. - -Handling Web Requests and Responses -=================================== - -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. - -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 `. - -Let's see some features of requests and responses in action: - -.. literalinclude:: quick_glance/requests/app.py - :pyobject: hello_world - -In this Pyramid view, we get the URL being visited from ``request.url``. -Also, if you visited ``http://localhost:6543/?name=alice``, -the name is included in the body of the response:: - - URL http://localhost:6543/?name=alice with name: alice - -Finally, we set the response's content type and return the Response. - -Views -===== - -For the examples above, the ``hello_world`` function is a "view". In -Pyramid, views are the primary way to accept web requests and return -responses. - -So far our examples place everything in one file: - -- the view function - -- its registration with the configurator - -- the route to map it to a URL - -- the WSGI application launcher - -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 ``config.scan('views')``. - -We now have a ``views.py`` module that is focused on handling requests -and responses: - -.. literalinclude:: quick_glance/views/views.py - :linenos: - -We have 4 views, each leading to the other. If you start at -``http://localhost:6543/``, you get a response with a link to the next -view. The ``hello_view`` (available at the URL ``/howdy``) has a link -to the ``redirect_view``, which shows issuing a redirect to the final -view. - -Earlier we saw ``config.add_view`` as one way to configure a view. This -section introduces ``@view_config``. 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. Both approaches result in the same final -configuration, thus usually, it is simply a matter of taste. - -.. note:: - - We're focusing on one topic at a time, thus we are leaving out - handling errors, logging, restarting, etc. These will be covered in - sections of the *Getting Started* guide. - - -Routing -======= - -Writing web applications usually means sophisticated URL design. We -just saw some Pyramid machinery for requests and views. Let's look at -features that help in routing. - -Above we saw the basics of routing URLs to views in Pyramid: - -- Your project's "setup" code registers a route name to be used when - matching part of the URL - -- Elsewhere, a view is configured to be called for that route name - -.. note:: - - Why do this twice? Other systems don't make us repeat this! As - illustrated in :ref:`routes_need_ordering`, multiple routes might - match the same URL pattern. Rather than provide ways to help guess, - Pyramid lets you be explicit in ordering. Pyramid also gives - facilities to avoid the problem. - -What if we want part of the URL to be available as data in my view? This -route declaration: - -.. literalinclude:: quick_glance/routing/app.py - :start-after: Start Route 1 - :end-before: End Route 1 - -With this, URLs such as ``/howdy/amy/smith`` will assign ``amy`` to -``first`` and ``smith`` to ``last``. We can then use this data in our -view: - -.. literalinclude:: quick_glance/routing/views.py - :start-after: Start Route 1 - :end-before: End Route 1 - -``request.matchdict`` contains values from the URL that match the -"replacement patterns" (the curly braces) in the route declaration. -This information can then be used in your view. - -As you might imagine, Pyramid provides -:doc:`many more features in routing <../narr/urldispatch>` -(route factories, custom predicates, security statements, -etc.) We will see more features later in *Geting Started*. - -Templating -========== - -Ouch. We have been making our own ``Response`` and filling the response -body with HTML. You usually won't embed an HTML string directly in -Python, but instead, will use a templating language. - -Pyramid doesn't mandate a particular database system, form library, -etc. It encourages replaceability. This applies equally to templating, -which is fortunate: developers have strong views about template -languages. That said, Pyramid bundles Chameleon and Mako, -so in this step, let's use Chameleon as an example: - -.. literalinclude:: quick_glance/templating/views.py - :start-after: Start View 1 - :end-before: End View 1 - -Ahh, that looks better. We have a view that is focused on Python code. -Our ``@view_config`` decorator specifies a :term:`renderer` that points -our template file. Our view then simply returns data which is then -supplied to our template: - -.. literalinclude:: quick_glance/templating/hello_world.pt - :language: html - -Since our view returned ``dict(name=request.matchdict['name'])``, -we can use ``name`` as a variable in our template via -``${name}``. - -Templating With ``jinja2`` -========================== - -We just said Pyramid doesn't prefer one templating language over -another. Time to prove it. Jinja2 is a popular templating system, -modelled after Django's templates. Let's add ``pyramid_jinja2``, -a Pyramid :term:`add-on` which enables Jinja2 as a :term:`renderer` in -our Pyramid applications: - -.. code-block:: bash - - $ pip install pyramid_jinja2 - -With the package installed, we can include the template bindings into -our configuration: - -.. code-block:: python - - config.include('pyramid_jinja2') - -The only change in our view...point the renderer at the ``.jinja2`` file: - -.. literalinclude:: quick_glance/jinja2/views.py - :start-after: Start View 1 - :end-before: End View 1 - -Our Jinja2 template is very similar to our previous template: - -.. literalinclude:: quick_glance/jinja2/hello_world.jinja2 - :language: jinja - -Pyramid's templating add-ons register a new kind of renderer into your -application. The renderer registration maps to different kinds of -filename extensions. In this case, changing the extension from ``.pt`` -to ``.jinja2`` passed the view response through the ``pyramid_jinja2`` -renderer. - -.. note:: - - At the time of this writing, Jinja2 had not released a version - compatible with Python 3.3. - - -Static Assets -============= - -Of course the Web is more than just markup. You need static assets: -CSS, JS, and images. Let's point our web app at a directory where -Pyramid will serve some static assets. First, another call to the -:term:`configurator`: - -.. literalinclude:: quick_glance/static_assets/app.py - :start-after: Start Static 1 - :end-before: End Static 1 - -This tells our WSGI application to map requests under -``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: - -.. literalinclude:: quick_glance/static_assets/static/app.css - :language: css - -All we need to do now is point to it in the ```` of our Jinja2 -template: - -.. literalinclude:: quick_glance/static_assets/hello_world.pt - :language: html - :start-after: Start Link 1 - :end-before: End Link 1 - -This link presumes that our CSS is at a URL starting with ``/static/``. -What if the site is later moved under ``/somesite/static/``? Or perhaps -web developer changes the arrangement on disk? Pyramid gives a helper -that provides flexibility on URL generation: - -.. literalinclude:: quick_glance/static_assets/hello_world.pt - :language: html - :start-after: Start Link 2 - :end-before: End Link 2 - -By using ``request.static_url`` to generate the full URL to the static -assets, you both ensure you stay in sync with the configuration and -gain refactoring flexibility later. - -Returning JSON -============== - -Modern web apps are more than rendered HTML. Dynamic pages now use -JavaScript to update the UI in the browser by requesting server data as -JSON. Pyramid supports this with a JSON renderer: - -.. literalinclude:: quick_glance/json/views.py - :start-after: Start View 1 - :end-before: End View 2 - -This wires up a view that returns some data through the JSON -:term:`renderer`, which calls Python's JSON support to serialize the data -into JSON and set the appropriate HTTP headers. - -View Classes -============ - -So far our views have been simple, free-standing functions. Many times -your views are related: different ways to look at or work on the same -data or a REST API that handles multiple operations. Grouping these -together as a -:ref:`view class ` makes sense: - -- Group views - -- Centralize some repetitive defaults - -- Share some state and helpers - -The following shows a "Hello World" example with three operations: view -a form, save a change, or press the delete button: - -.. literalinclude:: quick_glance/view_classes/views.py - :start-after: Start View 1 - :end-before: End View 1 - -As you can see, the three views are logically grouped together. -Specifically: - -- The first view is returned when you go to ``/howdy/amy``. This URL is - mapped to the ``hello`` route that we centrally set using the optional - ``@view_defaults``. - -- The second view is returned when the form data contains a field with - ``form.edit``, such as clicking on - ````. This rule - is specified in the ``@view_config`` for that view. - -- The third view is returned when clicking on a button such - as ````. - -Only one route needed, stated in one place atop the view class. Also, -the assignment of the ``name`` is done in the ``__init__``. Our -templates can then use ``{{ view.name }}``. - -Quick Project Startup with Scaffolds -==================================== - -So far we have done all of our *Quick Glance* as a single Python file. -No Python packages, no structure. Most Pyramid projects, though, -aren't developed this way. - -To ease the process of getting started, Pyramid provides *scaffolds* -that generate sample projects from templates in Pyramid and Pyramid -add-ons. Pyramid's ``pcreate`` command can list the available scaffolds: - -.. code-block:: bash - - $ pcreate --list - Available scaffolds: - alchemy: Pyramid SQLAlchemy project using url dispatch - pyramid_jinja2_starter: pyramid jinja2 starter project - starter: Pyramid starter project - zodb: Pyramid ZODB project using traversal - -The ``pyramid_jinja2`` add-on gave us a scaffold that we can use. From -the parent directory of where we want our Python package to be generated, -let's use that scaffold to make our project: - -.. code-block:: bash - - $ pcreate --scaffold pyramid_jinja2_starter hello_world - -We next use the normal Python development to setup our package for -development: - -.. code-block:: bash - - $ cd hello_world - $ python ./setup.py develop - -We are moving in the direction of a full-featured Pyramid project, -with a proper setup for Python standards (packaging) and Pyramid -configuration. This includes a new way of running your application: - -.. code-block:: bash - - $ pserve development.ini - -Let's look at ``pserve`` and configuration in more depth. - -Application Running with ``pserve`` -=================================== - -Prior to scaffolds, our project mixed a number of operations details -into our code. Why should my main code care with HTTP server I want and -what port number to run on? - -``pserve`` is Pyramid's application runner, separating operational -details from your code. When you install Pyramid, a small command -program called ``pserve`` is written to your ``bin`` directory. This -program is an executable Python module. It's very small, getting most -of its brains via import. - -You can run ``pserve`` with ``--help`` to see some of its options. -Doing so reveals that you can ask ``pserve`` to watch your development -files and reload the server when they change: - -.. code-block:: bash - - $ pserve development.ini --reload - -The ``pserve`` command has a number of other options and operations. -Most of the work, though, comes from your project's wiring, as -expressed in the configuration file you supply to ``pserve``. Let's -take a look at this configuration file. - -Configuration with ``.ini`` Files -================================= - -Earlier in *Quick Glance* we first met Pyramid's configuration system. -At that point we did all configuration in Python code. For example, -the port number chosen for our HTTP server was right there in Python -code. Our scaffold has moved this decision, and more, into the -``development.ini`` file: - -.. literalinclude:: quick_glance/package/development.ini - :language: ini - -Let's take a quick high-level look. First, the ``.ini`` file is divided -into sections: - -- ``[app:hello_world]`` configures our WSGI app - -- ``[pipeline:main]`` sets up our WSGI "pipeline" - -- ``[server:main]`` holds our WSGI server settings - -- Various sections afterwards configure our Python logging system - -We have a few decisions made for us in this configuration: - -#. *Choice of web server*. The ``use = egg:pyramid#wsgiref`` tell - ``pserve`` to the ``wsgiref`` server that is wrapped in the Pyramid - package. - -#. *Port number*. ``port = 6543`` tells ``wsgiref`` to listen on port - 6543. - -#. *WSGI app*. What package has our WSGI application in it? - ``use = egg:hello_world`` in the app section tells the - configuration what application to load. - -#. *Easier development by automatic template reloading*. In development - mode, you shouldn't have to restart the server when editing a Jinja2 - template. ``reload_templates = true`` sets this policy, - which might be different in production. - -Additionally, the ``development.ini`` generated by this scaffold wired -up Python's standard logging. We'll now see in the console, for example, -a log on every request that comes in, as well traceback information. - -Easier Development with ``debugtoolbar`` -======================================== - -As we introduce the basics we also want to show how to be productive in -development and debugging. For example, we just discussed template -reloading and earlier we showed ``--reload`` for application reloading. - -``pyramid_debugtoolbar`` is a popular Pyramid add-on which makes -several tools available in your browser. Adding it to your project -illustrates several points about configuration. - -First, change your ``setup.py`` to say: - -.. literalinclude:: quick_glance/package/setup.py - :start-after: Start Requires - :end-before: End Requires - -...and re-run your setup: - -.. code-block:: bash - - $ python ./setup.py develop - -The Python package was now installed into our environment. The package -is a Pyramid add-on, which means we need to include its configuration -into our web application. We could do this with imperative -configuration, as we did above for the ``pyramid_jinja2`` add-on: - -.. literalinclude:: quick_glance/package/hello_world/__init__.py - :start-after: Start Include - :end-before: End Include - -Now that we have a configuration file, we can use the -``pyramid.includes`` facility and place this in our -``development.ini`` instead: - -.. literalinclude:: quick_glance/package/development.ini - :language: ini - :start-after: Start Includes - :end-before: End Includes - -You'll now see an attractive (and -collapsible) menu in the right of your browser, providing introspective -access to debugging information. Even better, if your web application -generates an error, you will see a nice traceback on the screen. When -you want to disable this toolbar, no need to change code: you can -remove it from ``pyramid.includes`` in the relevant ``.ini`` -configuration file. - -Unit Tests and ``nose`` -======================= - -Yikes! We got this far and we haven't yet discussed tests. Particularly -egregious, as Pyramid has had a deep commitment to full test coverage -since before it was released. - -Our ``pyramid_jinja2_starter`` scaffold generated a ``tests.py`` module -with one unit test in it. To run it, let's install the handy ``nose`` -test runner by editing ``setup.py``. While we're at it, we'll throw in -the ``coverage`` tool which yells at us for code that isn't tested: - -.. code-block:: python - - setup(name='hello_world', - # Some lines removed... - extras_require={ - 'testing': ['nose', 'coverage'], - } - ) - -We changed ``setup.py`` which means we need to re-run -``python ./setup.py develop``. We can now run all our tests: - -.. code-block:: bash - - $ cd hello_world - $ nosetests . - . - Name Stmts Miss Cover Missing - --------------------------------------------------- - hello_world 12 8 33% 11-23 - hello_world.models 5 1 80% 8 - hello_world.tests 14 0 100% - hello_world.views 4 0 100% - --------------------------------------------------- - TOTAL 35 9 74% - ---------------------------------------------------------------------- - Ran 1 test in 0.931s - - OK - -Our unit test passed. What did our test look like? - -.. literalinclude:: quick_glance/package/hello_world/tests.py - -Pyramid supplies helpers for test writing, which we use in the -test setup and teardown. Our one test imports the view, -makes a dummy request, and sees if the view returns what we expected. - -Logging -======= - -It's important to know what is going on inside our web application. -In development we might need to collect some output. In production, -we might need to detect situations when other people use the site. We -need *logging*. - -Fortunately Pyramid uses the normal Python approach to logging. The -scaffold generated, in your ``development.ini``, a number of lines that -configure the logging for you to some reasonable defaults. You then see -messages sent by Pyramid (for example, when a new request comes in.) - -Maybe you would like to log messages in your code? In your Python -module, import and setup the logging: - -.. literalinclude:: quick_glance/package/hello_world/views.py - :start-after: Start Logging 1 - :end-before: End Logging 1 - -You can now, in your code, log messages: - -.. literalinclude:: quick_glance/package/hello_world/views.py - :start-after: Start Logging 2 - :end-before: End Logging 2 - -This will log ``Some Message`` at a ``debug`` log level, -to the application-configured logger in your ``development.ini``. What -controls that? These sections in the configuration file: - -.. literalinclude:: quick_glance/package/development.ini - :language: ini - :start-after: Start Sphinx Include - :end-before: End Sphinx Include - -Our application, a package named ``hello_world``, is setup as a logger -and configured to log messages at a ``DEBUG`` or higher level. When you -visit ``http://localhost:6543`` your console will now show:: - - 2013-08-09 10:42:42,968 DEBUG [hello_world.views][MainThread] Some Message - -Sessions -======== - -When people use your web application, they frequently perform a task -that requires semi-permanent data to be saved. For example, a shopping -cart. This is called a :term:`session`. - -Pyramid has basic built-in support for sessions, with add-ons such as -*Beaker* (or your own custom sessioning engine) that provide richer -session support. Let's take a look at the -:doc:`built-in sessioning support <../narr/sessions>`. In our -``__init__.py`` we first import the kind of sessioning we want: - -.. literalinclude:: quick_glance/package/hello_world/__init__.py - :start-after: Start Sphinx Include 1 - :end-before: End Sphinx Include 1 - -.. warning:: - - As noted in the session docs, this example implementation is - not intended for use in settings with security implications. - -Now make a "factory" and pass it to the :term:`configurator`'s -``session_factory`` argument: - -.. literalinclude:: quick_glance/package/hello_world/__init__.py - :start-after: Start Sphinx Include 2 - :end-before: End Sphinx Include 2 - -Pyramid's :term:`request` object now has a ``session`` attribute -that we can use in our view code: - -.. literalinclude:: quick_glance/package/hello_world/views.py - :start-after: Start Sphinx Include 1 - :end-before: End Sphinx Include 1 - -With this, each reload will increase the counter displayed in our -Jinja2 template: - -.. literalinclude:: quick_glance/package/hello_world/templates/mytemplate.jinja2 - :language: jinja - :start-after: Start Sphinx Include 1 - :end-before: End Sphinx Include 1 - - -Databases -========= - -Web applications mean data. Data means databases. Frequently SQL -databases. SQL Databases frequently mean an "ORM" -(object-relational mapper.) In Python, ORM usually leads to the -mega-quality *SQLAlchemy*, a Python package that greatly eases working -with databases. - -Pyramid and SQLAlchemy are great friends. That friendship includes a -scaffold! - -.. code-block:: bash - - $ pcreate --scaffold alchemy sqla_demo - $ cd sqla_demo - $ python setup.py develop - -We now have a working sample SQLAlchemy application with all -dependencies installed. The sample project provides a console script to -initialize a SQLite database with tables. Let's run it and then start -the application: - -.. code-block:: bash - - $ initialize_sqla_demo_db development.ini - $ pserve development.ini - -The ORM eases the mapping of database structures into a programming -language. SQLAlchemy uses "models" for this mapping. The scaffold -generated a sample model: - -.. literalinclude:: quick_glance/sqla_demo/sqla_demo/models.py - :start-after: Start Sphinx Include - :end-before: End Sphinx Include - -View code, which mediates the logic between web requests and the rest -of the system, can then easily get at the data thanks to SQLAlchemy: - -.. literalinclude:: quick_glance/sqla_demo/sqla_demo/views.py - :start-after: Start Sphinx Include - :end-before: End Sphinx Include - -Forms -===== - -Developers have lots of opinions about web forms, and thus there are many -form libraries for Python. Pyramid doesn't directly bundle a form -library, but *Deform* is a popular choice for forms, -along with its related *Colander* schema system. - -As an example, imagine we want a form that edits a wiki page. The form -should have two fields on it, one of them a required title and the -other a rich text editor for the body. With Deform we can express this -as a Colander schema: - -.. code-block:: python - - class WikiPage(colander.MappingSchema): - title = colander.SchemaNode(colander.String()) - body = colander.SchemaNode( - colander.String(), - widget=deform.widget.RichTextWidget() - ) - -With this in place, we can render the HTML for a form, -perhaps with form data from an existing page: - -.. code-block:: python - - form = self.wiki_form.render() - -We'd like to handle form submission, validation, and saving: - -.. code-block:: python - - # Get the form data that was posted - controls = self.request.POST.items() - try: - # Validate and either raise a validation error - # or return deserialized data from widgets - appstruct = wiki_form.validate(controls) - except deform.ValidationFailure as e: - # Bail out and render form with errors - return dict(title=title, page=page, form=e.render()) - - # Change the content and redirect to the view - page['title'] = appstruct['title'] - page['body'] = appstruct['body'] - -Deform and Colander provide a very flexible combination for forms, -widgets, schemas, and validation. Recent versions of Deform also -include a -`retail mode `_ -for gaining Deform -features on custom forms. - -Also, the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform -widgets using attractive CSS from Bootstrap and more powerful widgets -from Chosen. - -Awesome Pyramid Features -======================== - -For the most part this *Quick Glance* has covered concepts that are -common in Python web frameworks. Pyramid has a unique niche, -though. It helps you start with a small project that grows into a -larger project. Let's look at some of the unique facilities that help. - - - - -Conclusion -========== - -This *Quick Glance* was a little about a lot. We introduced a long list -of concepts in Pyramid, many of which are expanded on more fully later -in *Getting Started* and certainly in the Pyramid developer docs. \ No newline at end of file diff --git a/docs/getting_started/quick_glance/hello_world/app.py b/docs/getting_started/quick_glance/hello_world/app.py deleted file mode 100644 index df5a6cf18..000000000 --- a/docs/getting_started/quick_glance/hello_world/app.py +++ /dev/null @@ -1,16 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator -from pyramid.response import Response - - -def hello_world(request): - return Response('

Hello World!

') - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/') - config.add_view(hello_world, route_name='hello') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/jinja2/app.py b/docs/getting_started/quick_glance/jinja2/app.py deleted file mode 100644 index 83af219db..000000000 --- a/docs/getting_started/quick_glance/jinja2/app.py +++ /dev/null @@ -1,11 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/howdy/{name}') - config.include('pyramid_jinja2') - config.scan('views') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 b/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 deleted file mode 100644 index e177744b5..000000000 --- a/docs/getting_started/quick_glance/jinja2/hello_world.jinja2 +++ /dev/null @@ -1,8 +0,0 @@ - - - Hello World - - -

Hello {{ name }}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/jinja2/views.py b/docs/getting_started/quick_glance/jinja2/views.py deleted file mode 100644 index 916cdc720..000000000 --- a/docs/getting_started/quick_glance/jinja2/views.py +++ /dev/null @@ -1,8 +0,0 @@ -from pyramid.view import view_config - - -# Start View 1 -@view_config(route_name='hello', renderer='hello_world.jinja2') -# End View 1 -def hello_world(request): - return dict(name=request.matchdict['name']) diff --git a/docs/getting_started/quick_glance/json/app.py b/docs/getting_started/quick_glance/json/app.py deleted file mode 100644 index 950cb478f..000000000 --- a/docs/getting_started/quick_glance/json/app.py +++ /dev/null @@ -1,15 +0,0 @@ -from wsgiref.simple_server import make_server - -from pyramid.config import Configurator - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/howdy/{name}') - config.add_route('hello_json', 'hello.json') - config.add_static_view(name='static', path='static') - config.include('pyramid_jinja2') - config.scan('views') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/hello_world.jinja2 b/docs/getting_started/quick_glance/json/hello_world.jinja2 deleted file mode 100644 index f6862e618..000000000 --- a/docs/getting_started/quick_glance/json/hello_world.jinja2 +++ /dev/null @@ -1,10 +0,0 @@ - - - - Quick Glance - - - -

Hello {{ name }}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/hello_world.pt b/docs/getting_started/quick_glance/json/hello_world.pt deleted file mode 100644 index 711054aa9..000000000 --- a/docs/getting_started/quick_glance/json/hello_world.pt +++ /dev/null @@ -1,17 +0,0 @@ - - - - Quick Glance - - - - - - - - -

Hello ${name}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/json/views.py b/docs/getting_started/quick_glance/json/views.py deleted file mode 100644 index 583e220c7..000000000 --- a/docs/getting_started/quick_glance/json/views.py +++ /dev/null @@ -1,13 +0,0 @@ -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='hello_world.pt') -def hello_world(request): - return dict(name=request.matchdict['name']) - - -# Start View 1 -@view_config(route_name='hello_json', renderer='json') -def hello_json(request): - return [1, 2, 3] - # End View 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/package/CHANGES.txt b/docs/getting_started/quick_glance/package/CHANGES.txt deleted file mode 100644 index ffa255da8..000000000 --- a/docs/getting_started/quick_glance/package/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/getting_started/quick_glance/package/MANIFEST.in b/docs/getting_started/quick_glance/package/MANIFEST.in deleted file mode 100644 index 18fbd855c..000000000 --- a/docs/getting_started/quick_glance/package/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include *.txt *.ini *.cfg *.rst -recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/getting_started/quick_glance/package/README.txt b/docs/getting_started/quick_glance/package/README.txt deleted file mode 100644 index 63aaf6fbd..000000000 --- a/docs/getting_started/quick_glance/package/README.txt +++ /dev/null @@ -1,4 +0,0 @@ -hello_world README - - - diff --git a/docs/getting_started/quick_glance/package/development.ini b/docs/getting_started/quick_glance/package/development.ini deleted file mode 100644 index a751ff903..000000000 --- a/docs/getting_started/quick_glance/package/development.ini +++ /dev/null @@ -1,57 +0,0 @@ -# Start Includes -[app:hello_world] -pyramid.includes = pyramid_debugtoolbar -# End Includes -use = egg:hello_world -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_routematch = false -debug_templates = true -default_locale_name = en -jinja2.directories = hello_world:templates - - - -[pipeline:main] -pipeline = - hello_world - -[server:main] -use = egg:pyramid#wsgiref -host = 0.0.0.0 -port = 6543 - -# Begin logging configuration - -# Start Sphinx Include -[loggers] -keys = root, hello_world - -[logger_hello_world] -level = DEBUG -handlers = -qualname = hello_world -# End Sphinx Include - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration diff --git a/docs/getting_started/quick_glance/package/hello_world/__init__.py b/docs/getting_started/quick_glance/package/hello_world/__init__.py deleted file mode 100644 index 6e66bf40a..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -from pyramid.config import Configurator -from pyramid_jinja2 import renderer_factory -# Start Sphinx Include 1 -from pyramid.session import UnencryptedCookieSessionFactoryConfig -# End Sphinx Include 1 - -from hello_world.models import get_root - -def main(global_config, **settings): - """ This function returns a WSGI application. - - It is usually called by the PasteDeploy framework during - ``paster serve``. - """ - settings = dict(settings) - settings.setdefault('jinja2.i18n.domain', 'hello_world') - - # Start Sphinx Include 2 - my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet') - config = Configurator(root_factory=get_root, settings=settings, - session_factory=my_session_factory) - # End Sphinx Include 2 - config.add_translation_dirs('locale/') - # Start Include - config.include('pyramid_jinja2') - # End Include - - - config.add_static_view('static', 'static') - config.add_view('hello_world.views.my_view', - context='hello_world.models.MyModel', - renderer="mytemplate.jinja2") - - return config.make_wsgi_app() diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo b/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo deleted file mode 100644 index 40bf0c271..000000000 Binary files a/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo and /dev/null differ diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po b/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po deleted file mode 100644 index 0df243dba..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/locale/de/LC_MESSAGES/hello_world.po +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "Hallo!" diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo b/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo deleted file mode 100644 index 4fc438bfe..000000000 Binary files a/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo and /dev/null differ diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po b/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po deleted file mode 100644 index dc0aae5d7..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "Bonjour!" diff --git a/docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot b/docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot deleted file mode 100644 index 9c9460cb2..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/locale/hello_world.pot +++ /dev/null @@ -1,21 +0,0 @@ -# Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION -# This file is distributed under the same license as the PROJECT project. -# FIRST AUTHOR , 2011. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PROJECT VERSION\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-05-12 09:14-0330\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.6\n" - -msgid "Hello!" -msgstr "" diff --git a/docs/getting_started/quick_glance/package/hello_world/models.py b/docs/getting_started/quick_glance/package/hello_world/models.py deleted file mode 100644 index edd361c9c..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/models.py +++ /dev/null @@ -1,8 +0,0 @@ -class MyModel(object): - pass - -root = MyModel() - - -def get_root(request): - return root diff --git a/docs/getting_started/quick_glance/package/hello_world/static/favicon.ico b/docs/getting_started/quick_glance/package/hello_world/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/docs/getting_started/quick_glance/package/hello_world/static/favicon.ico and /dev/null differ diff --git a/docs/getting_started/quick_glance/package/hello_world/static/logo.png b/docs/getting_started/quick_glance/package/hello_world/static/logo.png deleted file mode 100644 index 88f5d9865..000000000 Binary files a/docs/getting_started/quick_glance/package/hello_world/static/logo.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/package/hello_world/static/pylons.css b/docs/getting_started/quick_glance/package/hello_world/static/pylons.css deleted file mode 100644 index 42e2e320e..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/static/pylons.css +++ /dev/null @@ -1,73 +0,0 @@ -html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ -vertical-align:baseline;background:transparent;} -body{line-height:1;} -ol,ul{list-style:none;} -blockquote,q{quotes:none;} -blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -/* remember to define focus styles! */ -:focus{outline:0;} -/* remember to highlight inserts somehow! */ -ins{text-decoration:none;} -del{text-decoration:line-through;} -/* tables still need 'cellspacing="0"' in the markup */ -table{border-collapse:collapse;border-spacing:0;} -/* restyling */ -sub{vertical-align:sub;font-size:smaller;line-height:normal;} -sup{vertical-align:super;font-size:smaller;line-height:normal;} -/* lists */ -ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} -ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} -li{display:list-item;} -/* nested lists have no top/bottom margins */ -ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -/* 2 deep unordered lists use a circle */ -ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -/* 3 deep (or more) unordered lists use a square */ -ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} -.hidden{display:none;} -p{line-height:1.5em;} -h1{font-size:1.75em;/* 28px */ -line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;/* 24px */ -line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;/* 20px */ -line-height:1.7em;font-family:helvetica,verdana;} -h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} -html,body{width:100%;height:100%;} -body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} -a{color:#1b61d6;text-decoration:none;} -a:hover{color:#e88f00;text-decoration:underline;} -body h1, -body h2, -body h3, -body h4, -body h5, -body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} -#wrap {min-height: 100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} -#header{background-color:#e88f00;top:0;font-size:14px;} -#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} -.header,.footer{width:700px;margin-right:auto;margin-left:auto;} -.wrapper{width:100%} -#top,#bottom{width:100%;} -#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} -#bottom{color:#222;background-color:#ffffff;overflow:auto;padding-bottom:80px;} -.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} -.top{padding-top:100px;} -.app-welcome{margin-top:25px;} -.app-name{color:#000000;font-weight:bold;} -.bottom{padding-top:50px;} -#left{width:325px;float:left;padding-right:25px;} -#right{width:325px;float:right;padding-left:25px;} -.align-left{text-align:left;} -.align-right{text-align:right;} -.align-center{text-align:center;} -ul.links{margin:0;padding:0;} -ul.links li{list-style-type:none;font-size:14px;} -form{border-style:none;} -fieldset{border-style:none;} -input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text]{} -input[type=submit]{background-color:#ddd;font-weight:bold;} -/*Opera Fix*/ -body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 b/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 deleted file mode 100644 index 25a28ed7a..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/templates/mytemplate.jinja2 +++ /dev/null @@ -1,90 +0,0 @@ - - - - The Pyramid Web Framework - - - - - - - - - - -
- -
-
- Logo -

- Welcome to {{project}}, an application generated by
- the Pyramid Web Framework. -

-
-
-
-
-

{% trans %}Hello!{% endtrans %}

- -

Counter: {{ request.session.counter }}

- -

Request performed with {{ request.locale_name }} locale.

-
-
-
-

Search Pyramid documentation

-
- - -
-
- -
-
-
- - - diff --git a/docs/getting_started/quick_glance/package/hello_world/tests.py b/docs/getting_started/quick_glance/package/hello_world/tests.py deleted file mode 100644 index ccec14f70..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/tests.py +++ /dev/null @@ -1,20 +0,0 @@ -import unittest -from pyramid import testing -from pyramid.i18n import TranslationStringFactory - -_ = TranslationStringFactory('hello_world') - - -class ViewTests(unittest.TestCase): - - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_my_view(self): - from hello_world.views import my_view - request = testing.DummyRequest() - response = my_view(request) - self.assertEqual(response['project'], 'hello_world') diff --git a/docs/getting_started/quick_glance/package/hello_world/views.py b/docs/getting_started/quick_glance/package/hello_world/views.py deleted file mode 100644 index 109c260ad..000000000 --- a/docs/getting_started/quick_glance/package/hello_world/views.py +++ /dev/null @@ -1,22 +0,0 @@ -# Start Logging 1 -import logging -log = logging.getLogger(__name__) -# End Logging 1 - -from pyramid.i18n import TranslationStringFactory - -_ = TranslationStringFactory('hello_world') - - -def my_view(request): - # Start Logging 2 - log.debug('Some Message') - # End Logging 2 - # Start Sphinx Include 1 - session = request.session - if 'counter' in session: - session['counter'] += 1 - else: - session['counter'] = 0 - # End Sphinx Include 1 - return {'project': 'hello_world'} diff --git a/docs/getting_started/quick_glance/package/message-extraction.ini b/docs/getting_started/quick_glance/package/message-extraction.ini deleted file mode 100644 index 0c3d54bc1..000000000 --- a/docs/getting_started/quick_glance/package/message-extraction.ini +++ /dev/null @@ -1,3 +0,0 @@ -[python: **.py] -[jinja2: **.jinja2] -encoding = utf-8 diff --git a/docs/getting_started/quick_glance/package/setup.cfg b/docs/getting_started/quick_glance/package/setup.cfg deleted file mode 100644 index 186e796fc..000000000 --- a/docs/getting_started/quick_glance/package/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[nosetests] -match = ^test -nocapture = 1 -cover-package = hello_world -with-coverage = 1 -cover-erase = 1 - -[compile_catalog] -directory = hello_world/locale -domain = hello_world -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = hello_world/locale/hello_world.pot -width = 80 -mapping_file = message-extraction.ini - -[init_catalog] -domain = hello_world -input_file = hello_world/locale/hello_world.pot -output_dir = hello_world/locale - -[update_catalog] -domain = hello_world -input_file = hello_world/locale/hello_world.pot -output_dir = hello_world/locale -previous = true diff --git a/docs/getting_started/quick_glance/package/setup.py b/docs/getting_started/quick_glance/package/setup.py deleted file mode 100644 index f118ed5fb..000000000 --- a/docs/getting_started/quick_glance/package/setup.py +++ /dev/null @@ -1,41 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -# Start Requires -requires = ['pyramid>=1.0.2', 'pyramid_jinja2', 'pyramid_debugtoolbar'] -# End Requires - -setup(name='hello_world', - version='0.0', - description='hello_world', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pylons", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=requires, - tests_require=requires, - test_suite="hello_world", - entry_points="""\ - [paste.app_factory] - main = hello_world:main - """, - paster_plugins=['pyramid'], - extras_require={ - 'testing': ['nose', ], - } -) \ No newline at end of file diff --git a/docs/getting_started/quick_glance/requests/app.py b/docs/getting_started/quick_glance/requests/app.py deleted file mode 100644 index 7ac81eb50..000000000 --- a/docs/getting_started/quick_glance/requests/app.py +++ /dev/null @@ -1,24 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator -from pyramid.response import Response - - -def hello_world(request): - # Some parameters from a request such as /?name=lisa - url = request.url - name = request.params.get('name', 'No Name Provided') - - body = 'URL %s with name: %s' % (url, name) - return Response( - content_type="text/plain", - body=body - ) - - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/') - config.add_view(hello_world, route_name='hello') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/routing/app.py b/docs/getting_started/quick_glance/routing/app.py deleted file mode 100644 index 04a8a6344..000000000 --- a/docs/getting_started/quick_glance/routing/app.py +++ /dev/null @@ -1,12 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator - -if __name__ == '__main__': - config = Configurator() - # Start Route 1 - config.add_route('hello', '/howdy/{first}/{last}') - # End Route 1 - config.scan('views') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/routing/views.py b/docs/getting_started/quick_glance/routing/views.py deleted file mode 100644 index 8cb8d3780..000000000 --- a/docs/getting_started/quick_glance/routing/views.py +++ /dev/null @@ -1,10 +0,0 @@ -from pyramid.response import Response -from pyramid.view import view_config - - -# Start Route 1 -@view_config(route_name='hello') -def hello_world(request): - body = '

Hi %(first)s %(last)s!

' % request.matchdict - return Response(body) - # End Route 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/sqla_demo/CHANGES.txt b/docs/getting_started/quick_glance/sqla_demo/CHANGES.txt deleted file mode 100644 index 35a34f332..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/CHANGES.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/docs/getting_started/quick_glance/sqla_demo/MANIFEST.in b/docs/getting_started/quick_glance/sqla_demo/MANIFEST.in deleted file mode 100644 index a432577e9..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include *.txt *.ini *.cfg *.rst -recursive-include sqla_demo *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/getting_started/quick_glance/sqla_demo/README.txt b/docs/getting_started/quick_glance/sqla_demo/README.txt deleted file mode 100644 index f35d3aec5..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/README.txt +++ /dev/null @@ -1,14 +0,0 @@ -sqla_demo README -================== - -Getting Started ---------------- - -- cd - -- $venv/bin/python setup.py develop - -- $venv/bin/initialize_sqla_demo_db development.ini - -- $venv/bin/pserve development.ini - diff --git a/docs/getting_started/quick_glance/sqla_demo/development.ini b/docs/getting_started/quick_glance/sqla_demo/development.ini deleted file mode 100644 index 174468abf..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/development.ini +++ /dev/null @@ -1,71 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### - -[app:main] -use = egg:sqla_demo - -pyramid.reload_templates = true -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -pyramid.includes = - pyramid_debugtoolbar - pyramid_tm - -sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite - -# By default, the toolbar only appears for clients from IP addresses -# '127.0.0.1' and '::1'. -# debugtoolbar.hosts = 127.0.0.1 ::1 - -### -# wsgi server configuration -### - -[server:main] -use = egg:waitress#main -host = 0.0.0.0 -port = 6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, sqla_demo, sqlalchemy - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[logger_sqla_demo] -level = DEBUG -handlers = -qualname = sqla_demo - -[logger_sqlalchemy] -level = INFO -handlers = -qualname = sqlalchemy.engine -# "level = INFO" logs SQL queries. -# "level = DEBUG" logs SQL queries and results. -# "level = WARN" logs neither. (Recommended for production systems.) - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/getting_started/quick_glance/sqla_demo/production.ini b/docs/getting_started/quick_glance/sqla_demo/production.ini deleted file mode 100644 index dc0ba304f..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/production.ini +++ /dev/null @@ -1,62 +0,0 @@ -### -# app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html -### - -[app:main] -use = egg:sqla_demo - -pyramid.reload_templates = false -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm - -sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite - -[server:main] -use = egg:waitress#main -host = 0.0.0.0 -port = 6543 - -### -# logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html -### - -[loggers] -keys = root, sqla_demo, sqlalchemy - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console - -[logger_sqla_demo] -level = WARN -handlers = -qualname = sqla_demo - -[logger_sqlalchemy] -level = WARN -handlers = -qualname = sqlalchemy.engine -# "level = INFO" logs SQL queries. -# "level = DEBUG" logs SQL queries and results. -# "level = WARN" logs neither. (Recommended for production systems.) - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/getting_started/quick_glance/sqla_demo/setup.cfg b/docs/getting_started/quick_glance/sqla_demo/setup.cfg deleted file mode 100644 index 9f91cd122..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/setup.cfg +++ /dev/null @@ -1,27 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=sqla_demo -with-coverage=1 -cover-erase=1 - -[compile_catalog] -directory = sqla_demo/locale -domain = sqla_demo -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = sqla_demo/locale/sqla_demo.pot -width = 80 - -[init_catalog] -domain = sqla_demo -input_file = sqla_demo/locale/sqla_demo.pot -output_dir = sqla_demo/locale - -[update_catalog] -domain = sqla_demo -input_file = sqla_demo/locale/sqla_demo.pot -output_dir = sqla_demo/locale -previous = true diff --git a/docs/getting_started/quick_glance/sqla_demo/setup.py b/docs/getting_started/quick_glance/sqla_demo/setup.py deleted file mode 100644 index ac2eed035..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/setup.py +++ /dev/null @@ -1,44 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() - -requires = [ - 'pyramid', - 'SQLAlchemy', - 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', - 'zope.sqlalchemy', - 'waitress', - ] - -setup(name='sqla_demo', - version='0.0', - description='sqla_demo', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web wsgi bfg pylons pyramid', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - test_suite='sqla_demo', - install_requires=requires, - entry_points="""\ - [paste.app_factory] - main = sqla_demo:main - [console_scripts] - initialize_sqla_demo_db = sqla_demo.scripts.initializedb:main - """, - ) diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo.sqlite b/docs/getting_started/quick_glance/sqla_demo/sqla_demo.sqlite deleted file mode 100644 index fa6adb104..000000000 Binary files a/docs/getting_started/quick_glance/sqla_demo/sqla_demo.sqlite and /dev/null differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/__init__.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/__init__.py deleted file mode 100644 index aac7c5e69..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -from pyramid.config import Configurator -from sqlalchemy import engine_from_config - -from .models import ( - DBSession, - Base, - ) - - -def main(global_config, **settings): - """ This function returns a Pyramid WSGI application. - """ - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) - Base.metadata.bind = engine - config = Configurator(settings=settings) - config.add_static_view('static', 'static', cache_max_age=3600) - config.add_route('home', '/') - config.scan() - return config.make_wsgi_app() diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/models.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/models.py deleted file mode 100644 index 3dfb40e58..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/models.py +++ /dev/null @@ -1,29 +0,0 @@ -from sqlalchemy import ( - Column, - Integer, - Text, - ) - -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import ( - scoped_session, - sessionmaker, - ) - -from zope.sqlalchemy import ZopeTransactionExtension - -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) -Base = declarative_base() - -# Start Sphinx Include -class MyModel(Base): - __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Text, unique=True) - value = Column(Integer) - - def __init__(self, name, value): - self.name = name - self.value = value - # End Sphinx Include diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/__init__.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/initializedb.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/initializedb.py deleted file mode 100644 index 66feb3008..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/scripts/initializedb.py +++ /dev/null @@ -1,37 +0,0 @@ -import os -import sys -import transaction - -from sqlalchemy import engine_from_config - -from pyramid.paster import ( - get_appsettings, - setup_logging, - ) - -from ..models import ( - DBSession, - MyModel, - Base, - ) - - -def usage(argv): - cmd = os.path.basename(argv[0]) - print('usage: %s \n' - '(example: "%s development.ini")' % (cmd, cmd)) - sys.exit(1) - - -def main(argv=sys.argv): - if len(argv) != 2: - usage(argv) - config_uri = argv[1] - setup_logging(config_uri) - settings = get_appsettings(config_uri) - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) - Base.metadata.create_all(engine) - with transaction.manager: - model = MyModel(name='one', value=1) - DBSession.add(model) diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/favicon.ico b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/favicon.ico and /dev/null differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/footerbg.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/footerbg.png deleted file mode 100644 index 1fbc873da..000000000 Binary files a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/footerbg.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/headerbg.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/headerbg.png deleted file mode 100644 index 0596f2020..000000000 Binary files a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/headerbg.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/ie6.css b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* html img, -* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", -this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", -this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) -);} -#wrap{display:table;height:100%} diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/middlebg.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/middlebg.png deleted file mode 100644 index 2369cfb7d..000000000 Binary files a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/middlebg.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pylons.css b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -ul, menu, dir -{ - display: block; - list-style-type: disc; - margin: 1em 0; - padding-left: 40px; -} - -ol -{ - display: block; - list-style-type: decimal-leading-zero; - margin: 1em 0; - padding-left: 40px; -} - -li -{ - display: list-item; -} - -ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl -{ - margin-top: 0; - margin-bottom: 0; -} - -ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir -{ - list-style-type: circle; -} - -ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir -{ - list-style-type: square; -} - -.hidden -{ - display: none; -} - -p -{ - line-height: 1.5em; -} - -h1 -{ - font-size: 1.75em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h2 -{ - font-size: 1.5em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h3 -{ - font-size: 1.25em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h4 -{ - font-size: 1em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -html, body -{ - width: 100%; - height: 100%; -} - -body -{ - margin: 0; - padding: 0; - background-color: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 url(footerbg.png) repeat-x 0 top; - position: relative; - margin-top: -40px; - clear: both; -} - -.header, .footer -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.wrapper -{ - width: 100%; -} - -#top, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.top, .top-small, .middle, .bottom -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.top -{ - padding-top: 40px; -} - -.top-small -{ - padding-top: 10px; -} - -#middle -{ - width: 100%; - height: 100px; - background: url(middlebg.png) repeat-x; - border-top: 2px solid #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#left -{ - width: 350px; - float: left; - padding-right: 25px; -} - -#right -{ - width: 350px; - float: right; - padding-left: 25px; -} - -.align-left -{ - text-align: left; -} - -.align-right -{ - text-align: right; -} - -.align-center -{ - text-align: center; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -ul.links li -{ - list-style-type: none; - font-size: 14px; -} - -form -{ - border-style: none; -} - -fieldset -{ - border-style: none; -} - -input -{ - color: #222; - border: 1px solid #ccc; - font-family: sans-serif; - font-size: 12px; - line-height: 16px; -} - -input[type=text], input[type=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid-small.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid-small.png deleted file mode 100644 index a5bc0ade7..000000000 Binary files a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid-small.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid.png b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid.png deleted file mode 100644 index 347e05549..000000000 Binary files a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/pyramid.png and /dev/null differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/transparent.gif b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/transparent.gif deleted file mode 100644 index 0341802e5..000000000 Binary files a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/static/transparent.gif and /dev/null differ diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/templates/mytemplate.pt b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/templates/mytemplate.pt deleted file mode 100644 index e0ac9d440..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/templates/mytemplate.pt +++ /dev/null @@ -1,76 +0,0 @@ - - - - The Pyramid Web Application Development Framework - - - - - - - - - - -
-
-
-
pyramid
-
-
-
-
-

- Welcome to ${project}, an application generated by
- the Pyramid web application development framework. -

-
-
-
-
-
-

Search documentation

-
- - -
-
- -
-
-
- - - diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/tests.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/tests.py deleted file mode 100644 index 6fef6d695..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/tests.py +++ /dev/null @@ -1,33 +0,0 @@ -import unittest -import transaction - -from pyramid import testing - -from .models import DBSession - - -class TestMyView(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - from sqlalchemy import create_engine - engine = create_engine('sqlite://') - from .models import ( - Base, - MyModel, - ) - DBSession.configure(bind=engine) - Base.metadata.create_all(engine) - with transaction.manager: - model = MyModel(name='one', value=55) - DBSession.add(model) - - def tearDown(self): - DBSession.remove() - testing.tearDown() - - def test_it(self): - from .views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['one'].name, 'one') - self.assertEqual(info['project'], 'sqla_demo') diff --git a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/views.py b/docs/getting_started/quick_glance/sqla_demo/sqla_demo/views.py deleted file mode 100644 index 768a7e42e..000000000 --- a/docs/getting_started/quick_glance/sqla_demo/sqla_demo/views.py +++ /dev/null @@ -1,37 +0,0 @@ -from pyramid.response import Response -from pyramid.view import view_config - -from sqlalchemy.exc import DBAPIError - -from .models import ( - DBSession, - MyModel, - ) - - -@view_config(route_name='home', renderer='templates/mytemplate.pt') -def my_view(request): - try: - # Start Sphinx Include - one = DBSession.query(MyModel).filter(MyModel.name == 'one').first() - # End Sphinx Include - except DBAPIError: - return Response(conn_err_msg, content_type='text/plain', status_int=500) - return {'one': one, 'project': 'sqla_demo'} - -conn_err_msg = """\ -Pyramid is having a problem using your SQL database. The problem -might be caused by one of the following things: - -1. You may need to run the "initialize_sqla_demo_db" script - to initialize your database tables. Check your virtual - environment's "bin" directory for this script and try to run it. - -2. Your database server may not be running. Check that the - database server referred to by the "sqlalchemy.url" setting in - your "development.ini" file is running. - -After you fix the problem, please restart the Pyramid application to -try it again. -""" - diff --git a/docs/getting_started/quick_glance/static_assets/app.py b/docs/getting_started/quick_glance/static_assets/app.py deleted file mode 100644 index 9c808972f..000000000 --- a/docs/getting_started/quick_glance/static_assets/app.py +++ /dev/null @@ -1,14 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/howdy/{name}') - # Start Static 1 - config.add_static_view(name='static', path='static') - # End Static 1 - config.include('pyramid_jinja2') - config.scan('views') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 b/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 deleted file mode 100644 index f6862e618..000000000 --- a/docs/getting_started/quick_glance/static_assets/hello_world.jinja2 +++ /dev/null @@ -1,10 +0,0 @@ - - - - Quick Glance - - - -

Hello {{ name }}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/hello_world.pt b/docs/getting_started/quick_glance/static_assets/hello_world.pt deleted file mode 100644 index 1797146eb..000000000 --- a/docs/getting_started/quick_glance/static_assets/hello_world.pt +++ /dev/null @@ -1,16 +0,0 @@ - - - Quick Glance - - - - - - - - -

Hello ${name}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/static/app.css b/docs/getting_started/quick_glance/static_assets/static/app.css deleted file mode 100644 index f8acf3164..000000000 --- a/docs/getting_started/quick_glance/static_assets/static/app.css +++ /dev/null @@ -1,4 +0,0 @@ -body { - margin: 2em; - font-family: sans-serif; -} \ No newline at end of file diff --git a/docs/getting_started/quick_glance/static_assets/views.py b/docs/getting_started/quick_glance/static_assets/views.py deleted file mode 100644 index 90730ae32..000000000 --- a/docs/getting_started/quick_glance/static_assets/views.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config - - -@view_config(route_name='hello', renderer='hello_world.pt') -def hello_world(request): - return dict(name=request.matchdict['name']) diff --git a/docs/getting_started/quick_glance/templating/app.py b/docs/getting_started/quick_glance/templating/app.py deleted file mode 100644 index 6d1a29f4e..000000000 --- a/docs/getting_started/quick_glance/templating/app.py +++ /dev/null @@ -1,10 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator - -if __name__ == '__main__': - config = Configurator() - config.add_route('hello', '/howdy/{name}') - config.scan('views') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/templating/hello_world.pt b/docs/getting_started/quick_glance/templating/hello_world.pt deleted file mode 100644 index ae14f447d..000000000 --- a/docs/getting_started/quick_glance/templating/hello_world.pt +++ /dev/null @@ -1,9 +0,0 @@ - - - - Quick Glance - - -

Hello ${name}

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/templating/views.py b/docs/getting_started/quick_glance/templating/views.py deleted file mode 100644 index 6c7846efa..000000000 --- a/docs/getting_started/quick_glance/templating/views.py +++ /dev/null @@ -1,8 +0,0 @@ -from pyramid.view import view_config - - -# Start View 1 -@view_config(route_name='hello', renderer='hello_world.pt') -def hello_world(request): - return dict(name=request.matchdict['name']) - # End View 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/app.py b/docs/getting_started/quick_glance/view_classes/app.py deleted file mode 100644 index 468c8c29e..000000000 --- a/docs/getting_started/quick_glance/view_classes/app.py +++ /dev/null @@ -1,13 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator - -if __name__ == '__main__': - config = Configurator() - # Start Routes 1 - config.add_route('hello', '/howdy/{name}') - # End Routes 1 - config.include('pyramid_jinja2') - config.scan('views') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/delete.jinja2 b/docs/getting_started/quick_glance/view_classes/delete.jinja2 deleted file mode 100644 index ba45b7d16..000000000 --- a/docs/getting_started/quick_glance/view_classes/delete.jinja2 +++ /dev/null @@ -1,9 +0,0 @@ - - - - Delete World - - -

Delete {{ view.name }}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/edit.jinja2 b/docs/getting_started/quick_glance/view_classes/edit.jinja2 deleted file mode 100644 index ce0eb5bd1..000000000 --- a/docs/getting_started/quick_glance/view_classes/edit.jinja2 +++ /dev/null @@ -1,9 +0,0 @@ - - - - Edit World - - -

Edit {{ view.name }}!

- - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/hello.jinja2 b/docs/getting_started/quick_glance/view_classes/hello.jinja2 deleted file mode 100644 index 3446b96ce..000000000 --- a/docs/getting_started/quick_glance/view_classes/hello.jinja2 +++ /dev/null @@ -1,17 +0,0 @@ - - - - Hello World - - -

Hello {{ view.name }}!

- -
- - - -
- - - \ No newline at end of file diff --git a/docs/getting_started/quick_glance/view_classes/views.py b/docs/getting_started/quick_glance/view_classes/views.py deleted file mode 100644 index 62556142e..000000000 --- a/docs/getting_started/quick_glance/view_classes/views.py +++ /dev/null @@ -1,32 +0,0 @@ -from pyramid.view import ( - view_config, - view_defaults - ) - - -# Start View 1 -# One route, at /howdy/amy, so don't repeat on each @view_config -@view_defaults(route_name='hello') -class HelloWorldViews: - def __init__(self, request): - self.request = request - # Our templates can now say {{ view.name }} - self.name = request.matchdict['name'] - - # Retrieving /howdy/amy the first time - @view_config(renderer='hello.jinja2') - def hello_view(self): - return dict() - - # Posting to /howdy/amy via the "Edit" submit button - @view_config(request_param='form.edit', renderer='edit.jinja2') - def edit_view(self): - print('Edited') - return dict() - - # Posting to /howdy/amy via the "Delete" submit button - @view_config(request_param='form.delete', renderer='delete.jinja2') - def delete_view(self): - print('Deleted') - return dict() - # End View 1 \ No newline at end of file diff --git a/docs/getting_started/quick_glance/views/app.py b/docs/getting_started/quick_glance/views/app.py deleted file mode 100644 index 54dc9ed4b..000000000 --- a/docs/getting_started/quick_glance/views/app.py +++ /dev/null @@ -1,13 +0,0 @@ -from wsgiref.simple_server import make_server -from pyramid.config import Configurator - -if __name__ == '__main__': - config = Configurator() - config.add_route('home', '/') - config.add_route('hello', '/howdy') - config.add_route('redirect', '/goto') - config.add_route('exception', '/problem') - config.scan('views') - app = config.make_wsgi_app() - server = make_server('0.0.0.0', 6543, app) - server.serve_forever() \ No newline at end of file diff --git a/docs/getting_started/quick_glance/views/views.py b/docs/getting_started/quick_glance/views/views.py deleted file mode 100644 index 9dc795f14..000000000 --- a/docs/getting_started/quick_glance/views/views.py +++ /dev/null @@ -1,29 +0,0 @@ -from pyramid.httpexceptions import HTTPFound -from pyramid.response import Response -from pyramid.view import view_config - - -# First view, available at http://localhost:6543/ -@view_config(route_name='home') -def home_view(request): - return Response('

Visit hello

') - - -# /howdy?name=alice which links to the next view -@view_config(route_name='hello') -def hello_view(request): - name = request.params.get('name', 'No Name') - body = '

Hi %s, this redirects

' - return Response(body % name) - - -# /goto which issues HTTP redirect to the last view -@view_config(route_name='redirect') -def redirect_view(request): - return HTTPFound(location="/problem") - - -# /problem which causes an site error -@view_config(route_name='exception') -def exception_view(request): - raise Exception() diff --git a/docs/getting_started/routes.rst b/docs/getting_started/routes.rst deleted file mode 100644 index ec4fc988c..000000000 --- a/docs/getting_started/routes.rst +++ /dev/null @@ -1,3 +0,0 @@ -=========================== -Designing URLs Using Routes -=========================== diff --git a/docs/getting_started/scaffolds.rst b/docs/getting_started/scaffolds.rst deleted file mode 100644 index 52101495e..000000000 --- a/docs/getting_started/scaffolds.rst +++ /dev/null @@ -1,110 +0,0 @@ -==================================== -Starting New Projects With Scaffolds -==================================== - -So far we have done all of our *Quick Glance* as a single Python file. -No Python packages, no structure. Most Pyramid projects, though, -aren't developed this way. - -To ease the process of getting started, Pyramid provides *scaffolds* -that generate sample projects. You run a command, perhaps answer some -questions, and a sample project is generated for you. Not just Pyramid -itself: add-ons such as ``pyramid_jinja2`` (or your own projects) can -register their own 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 - -Pyramid's ``pcreate`` command is used to generate a starting point -from a scaffold. What does this command look like? - -.. code-block:: bash - - $ pcreate --help - Usage: pcreate [options] output_directory - - Render Pyramid scaffolding to an output directory - - Options: - -h, --help show this help message and exit - -s SCAFFOLD_NAME, --scaffold=SCAFFOLD_NAME - Add a scaffold to the create process (multiple -s args - accepted) - -t SCAFFOLD_NAME, --template=SCAFFOLD_NAME - A backwards compatibility alias for -s/--scaffold. - Add a scaffold to the create process (multiple -t args - accepted) - -l, --list List all available scaffold names - --list-templates A backwards compatibility alias for -l/--list. List - all available scaffold names. - --simulate Simulate but do no work - --overwrite Always overwrite - --interactive When a file would be overwritten, interrogate - -Let's see what our Pyramid install supports as starting-point scaffolds: - -.. code-block:: bash - - $ pcreate --list - Available scaffolds: - alchemy: Pyramid SQLAlchemy project using url dispatch - pyramid_jinja2_starter: pyramid jinja2 starter project - starter: Pyramid starter project - zodb: Pyramid ZODB project using traversal - -The ``pyramid_jinja2_starter`` looks interesting. From the parent -directory of where we want our Python package to be generated, -let's use that scaffold to make our project: - -.. code-block:: bash - - $ pcreate --scaffold pyramid_jinja2_starter hello_world - -After printing a bunch of lines about the files being generated, -we now have a Python package. As described in the *official -instructions*, we need to install this as a development package: - -.. code-block:: bash - - $ cd hello_world - $ 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 -sample files for our application: - -.. code-block:: bash - - $ ls - CHANGES.txt development.ini hello_world.egg-info - MANIFEST.in message-extraction.ini setup.cfg - README.txt hello_world setup.py - - $ ls hello_world - __init__.py locale static tests.py - __pycache__ models.py templates views.py - -We are moving in the direction of a full-featured Pyramid project, -with a proper setup for Python standards (packaging) and Pyramid -configuration. This includes a new way of running your application: - -.. code-block:: bash - - $ pserve development.ini - -With ``pserve``, your application isn't responsible for finding a WSGI -server and launching your WSGI app. Also, much of the wiring of your -application can be moved to a declarative ``.ini`` configuration file. - -In your browser, visit -`http://localhost:6543/ `_ and you'll see that -things look very different. In the next few sections we'll cover some -decisions made by this scaffold. - -Let's look at ``pserve`` and configuration in more depth. \ No newline at end of file diff --git a/docs/getting_started/security.rst b/docs/getting_started/security.rst deleted file mode 100644 index 5ba1fb103..000000000 --- a/docs/getting_started/security.rst +++ /dev/null @@ -1,3 +0,0 @@ -============================================== -Security With Authentication and Authorization -============================================== diff --git a/docs/getting_started/sessions.rst b/docs/getting_started/sessions.rst deleted file mode 100644 index 02e51f9e3..000000000 --- a/docs/getting_started/sessions.rst +++ /dev/null @@ -1,3 +0,0 @@ -=============================== -Site Visitor Data With Sessions -=============================== diff --git a/docs/getting_started/special_views.rst b/docs/getting_started/special_views.rst deleted file mode 100644 index c2b384bdb..000000000 --- a/docs/getting_started/special_views.rst +++ /dev/null @@ -1,3 +0,0 @@ -========================================= -NotFound, Errors, and Other Special Views -========================================= diff --git a/docs/getting_started/static_assets.rst b/docs/getting_started/static_assets.rst deleted file mode 100644 index b605260a7..000000000 --- a/docs/getting_started/static_assets.rst +++ /dev/null @@ -1,4 +0,0 @@ -====================================================== -Serving CSS, JavaScript, and Images With Static Assets -====================================================== - diff --git a/docs/getting_started/templates.rst b/docs/getting_started/templates.rst deleted file mode 100644 index 32cfea848..000000000 --- a/docs/getting_started/templates.rst +++ /dev/null @@ -1,4 +0,0 @@ -============================= -Rendering HTML With Templates -============================= - diff --git a/docs/getting_started/testing.rst b/docs/getting_started/testing.rst deleted file mode 100644 index af2b335b7..000000000 --- a/docs/getting_started/testing.rst +++ /dev/null @@ -1,4 +0,0 @@ -================================================= -Coding For Quality With Unit and Functional Tests -================================================= - diff --git a/docs/getting_started/top_ten.rst b/docs/getting_started/top_ten.rst deleted file mode 100644 index e207f4ce1..000000000 --- a/docs/getting_started/top_ten.rst +++ /dev/null @@ -1,41 +0,0 @@ -============================== -Top Killer Features In Pyramid -============================== - -As a regular developer - -- Configuration - -- Route factories and contexts - -- Advanced view configuration - -- Route prefixes - -- Asset specifications - -- Events - -- Custom renderers - -- Tweens - -- Transactions - -- Traversal - -- Custom directives - -- config.include - -- Extensible applications - - - Overridable views, routes, and assets - - - config.include - - - Events - - - Distributing an add-on - - - "Making your own framework", Extensibility diff --git a/docs/getting_started/views.rst b/docs/getting_started/views.rst deleted file mode 100644 index f30caea8a..000000000 --- a/docs/getting_started/views.rst +++ /dev/null @@ -1,30 +0,0 @@ -================================ -Handling Web Requests With Views -================================ - -Free-standing functions are the regular way to do views. Many times, -though, you have several views that are closely related. For example, -a document might have many different ways to look at it, -or a form might submit to different targets, or a REST handler might -cover different operations. - -Grouping these together makes logical sense. A view class lets you -group views, centralize some repetitive defaults, share some state -assignments, and use helper functions as class methods. - -As an example, imagine we have some views around saying hello to a -person, then editing that person or perhaps deleting that person. They -might logically belong together. We could do these as independent -functions, but let's do them together as a view class: - - -...and some routes that wire up the views to URLs: - - -...and a form in ``hello_world.jinja2`` that submits to the second view: - - -Just to review: - -- The ``/howdy/amy`` URL matches the ``hello`` route, handled by the - ``hello_view`` class method. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index e61fe64d4..c4b81ad7d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -48,30 +48,30 @@ What's New Getting Started =============== -Quick tour of major facilities in Pyramid, including a -:doc:`getting_started/quick_glance` high-level -overview. +If you are new to Pyramid, we have a few resources that can help you get +up to speed right away. Our *Quick Tour* shows a little about a lot: .. toctree:: - :maxdepth: 1 + :maxdepth: 2 + + quick_tour + +Also: + +* To see a minimal Pyramid web application, check out `creating your first + Pyramid application <../narr/firstapp>`_. + +* For help getting Pyramid set up, try the `install guide + <../narr/install>`_. + +* To get the feel of how a Pyramid web application is created, go to the + `single file tasks tutorial `_ page. + +* Like learning by example? Check out to the `wiki tutorial + <../tutorials/wiki2/index.html>`_. + +* Need help? See `Support `_. - 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: diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst new file mode 100644 index 000000000..cc4afe67d --- /dev/null +++ b/docs/quick_tour.rst @@ -0,0 +1,789 @@ +===================== +Quick Tour of Pyramid +===================== + +Pyramid lets you start small and finish big. This *Quick Tour* guide +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:: + + We use Python 3 in 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. + +Python Setup +============ + +First things first: we need our Python environment in ship-shape. +Pyramid encourages standard Python development practices (virtual +environments, packaging tools, logging, 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 + $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python + $ easy_install-3.3 pip + +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. + +Pyramid Installation +==================== + +We now have a standard starting point for Python. Getting Pyramid +installed is easy: + +.. code-block:: bash + + $ pip install pyramid + +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_tour/hello_world/app.py + :linenos: + +This simple example is easy to run. Save this as ``app.py`` and run it: + +.. code-block:: bash + + $ python ./app.py + +Next, open `http://localhost:6543/ `_ in a +browser and you will see the ``Hello World!`` message. + +New to Python web programming? If so, some lines in module merit +explanation: + +#. *Line 10*. The ``if __name__ == '__main__':`` is Python's way of + saying "Start here when running from the command line". + +#. *Lines 11-13*. Use Pyramid's :term:`configurator` to connect + :term:`view` code to particular URL :term:`route`. + +#. *Lines 6-7*. Implement the view code that generates the + :term:`response`. + +#. *Lines 14-16*. Publish a :term:`WSGI` app using an HTTP server. + +As shown in this example, the :term:`configurator` plays a central role +in Pyramid development. Building an application from loosely-coupled +parts via :doc:`../narr/configuration` is a central idea in Pyramid, +one that we will revisit regurlarly in this *Quick Tour*. + +Handling Web Requests and Responses +=================================== + +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. + +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 `. + +Let's see some features of requests and responses in action: + +.. literalinclude:: quick_tour/requests/app.py + :pyobject: hello_world + +In this Pyramid view, we get the URL being visited from ``request.url``. +Also, if you visited ``http://localhost:6543/?name=alice``, +the name is included in the body of the response:: + + URL http://localhost:6543/?name=alice with name: alice + +Finally, we set the response's content type and return the Response. + +Views +===== + +For the examples above, the ``hello_world`` function is a "view". In +Pyramid, views are the primary way to accept web requests and return +responses. + +So far our examples place everything in one file: + +- the view function + +- its registration with the configurator + +- the route to map it to a URL + +- the WSGI application launcher + +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_tour/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 ``config.scan('views')``. + +We now have a ``views.py`` module that is focused on handling requests +and responses: + +.. literalinclude:: quick_tour/views/views.py + :linenos: + +We have 4 views, each leading to the other. If you start at +``http://localhost:6543/``, you get a response with a link to the next +view. The ``hello_view`` (available at the URL ``/howdy``) has a link +to the ``redirect_view``, which shows issuing a redirect to the final +view. + +Earlier we saw ``config.add_view`` as one way to configure a view. This +section introduces ``@view_config``. 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. Both approaches result in the same final +configuration, thus usually, it is simply a matter of taste. + + +Routing +======= + +Writing web applications usually means sophisticated URL design. We +just saw some Pyramid machinery for requests and views. Let's look at +features that help in routing. + +Above we saw the basics of routing URLs to views in Pyramid: + +- Your project's "setup" code registers a route name to be used when + matching part of the URL + +- Elsewhere, a view is configured to be called for that route name + +.. note:: + + Why do this twice? Other systems don't make us repeat this! As + illustrated in :ref:`routes_need_ordering`, multiple routes might + match the same URL pattern. Rather than provide ways to help guess, + Pyramid lets you be explicit in ordering. Pyramid also gives + facilities to avoid the problem. + +What if we want part of the URL to be available as data in my view? This +route declaration: + +.. literalinclude:: quick_tour/routing/app.py + :start-after: Start Route 1 + :end-before: End Route 1 + +With this, URLs such as ``/howdy/amy/smith`` will assign ``amy`` to +``first`` and ``smith`` to ``last``. We can then use this data in our +view: + +.. literalinclude:: quick_tour/routing/views.py + :start-after: Start Route 1 + :end-before: End Route 1 + +``request.matchdict`` contains values from the URL that match the +"replacement patterns" (the curly braces) in the route declaration. +This information can then be used in your view. + +As you might imagine, Pyramid provides +:doc:`many more features in routing <../narr/urldispatch>` +(route factories, custom predicates, security statements, +etc.) We will see more features later in *Geting Started*. + +Templating +========== + +Ouch. We have been making our own ``Response`` and filling the response +body with HTML. You usually won't embed an HTML string directly in +Python, but instead, will use a templating language. + +Pyramid doesn't mandate a particular database system, form library, +etc. It encourages replaceability. This applies equally to templating, +which is fortunate: developers have strong views about template +languages. That said, Pyramid bundles Chameleon and Mako, +so in this step, let's use Chameleon as an example: + +.. literalinclude:: quick_tour/templating/views.py + :start-after: Start View 1 + :end-before: End View 1 + +Ahh, that looks better. We have a view that is focused on Python code. +Our ``@view_config`` decorator specifies a :term:`renderer` that points +our template file. Our view then simply returns data which is then +supplied to our template: + +.. literalinclude:: quick_tour/templating/hello_world.pt + :language: html + +Since our view returned ``dict(name=request.matchdict['name'])``, +we can use ``name`` as a variable in our template via +``${name}``. + +Templating With ``jinja2`` +========================== + +We just said Pyramid doesn't prefer one templating language over +another. Time to prove it. Jinja2 is a popular templating system, +modelled after Django's templates. Let's add ``pyramid_jinja2``, +a Pyramid :term:`add-on` which enables Jinja2 as a :term:`renderer` in +our Pyramid applications: + +.. code-block:: bash + + $ pip install pyramid_jinja2 + +With the package installed, we can include the template bindings into +our configuration: + +.. code-block:: python + + config.include('pyramid_jinja2') + +The only change in our view...point the renderer at the ``.jinja2`` file: + +.. literalinclude:: quick_tour/jinja2/views.py + :start-after: Start View 1 + :end-before: End View 1 + +Our Jinja2 template is very similar to our previous template: + +.. literalinclude:: quick_tour/jinja2/hello_world.jinja2 + :language: jinja + +Pyramid's templating add-ons register a new kind of renderer into your +application. The renderer registration maps to different kinds of +filename extensions. In this case, changing the extension from ``.pt`` +to ``.jinja2`` passed the view response through the ``pyramid_jinja2`` +renderer. + +.. note:: + + At the time of this writing, Jinja2 had not released a version + compatible with Python 3.3. + + +Static Assets +============= + +Of course the Web is more than just markup. You need static assets: +CSS, JS, and images. Let's point our web app at a directory where +Pyramid will serve some static assets. First, another call to the +:term:`configurator`: + +.. literalinclude:: quick_tour/static_assets/app.py + :start-after: Start Static 1 + :end-before: End Static 1 + +This tells our WSGI application to map requests under +``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: + +.. literalinclude:: quick_tour/static_assets/static/app.css + :language: css + +All we need to do now is point to it in the ```` of our Jinja2 +template: + +.. literalinclude:: quick_tour/static_assets/hello_world.pt + :language: html + :start-after: Start Link 1 + :end-before: End Link 1 + +This link presumes that our CSS is at a URL starting with ``/static/``. +What if the site is later moved under ``/somesite/static/``? Or perhaps +web developer changes the arrangement on disk? Pyramid gives a helper +that provides flexibility on URL generation: + +.. literalinclude:: quick_tour/static_assets/hello_world.pt + :language: html + :start-after: Start Link 2 + :end-before: End Link 2 + +By using ``request.static_url`` to generate the full URL to the static +assets, you both ensure you stay in sync with the configuration and +gain refactoring flexibility later. + +Returning JSON +============== + +Modern web apps are more than rendered HTML. Dynamic pages now use +JavaScript to update the UI in the browser by requesting server data as +JSON. Pyramid supports this with a JSON renderer: + +.. literalinclude:: quick_tour/json/views.py + :start-after: Start View 1 + :end-before: End View 2 + +This wires up a view that returns some data through the JSON +:term:`renderer`, which calls Python's JSON support to serialize the data +into JSON and set the appropriate HTTP headers. + +View Classes +============ + +So far our views have been simple, free-standing functions. Many times +your views are related: different ways to look at or work on the same +data or a REST API that handles multiple operations. Grouping these +together as a +:ref:`view class ` makes sense: + +- Group views + +- Centralize some repetitive defaults + +- Share some state and helpers + +The following shows a "Hello World" example with three operations: view +a form, save a change, or press the delete button: + +.. literalinclude:: quick_tour/view_classes/views.py + :start-after: Start View 1 + :end-before: End View 1 + +As you can see, the three views are logically grouped together. +Specifically: + +- The first view is returned when you go to ``/howdy/amy``. This URL is + mapped to the ``hello`` route that we centrally set using the optional + ``@view_defaults``. + +- The second view is returned when the form data contains a field with + ``form.edit``, such as clicking on + ````. This rule + is specified in the ``@view_config`` for that view. + +- The third view is returned when clicking on a button such + as ````. + +Only one route needed, stated in one place atop the view class. Also, +the assignment of the ``name`` is done in the ``__init__``. Our +templates can then use ``{{ view.name }}``. + +Quick Project Startup with Scaffolds +==================================== + +So far we have done all of our *Quick Glance* as a single Python file. +No Python packages, no structure. Most Pyramid projects, though, +aren't developed this way. + +To ease the process of getting started, Pyramid provides *scaffolds* +that generate sample projects from templates in Pyramid and Pyramid +add-ons. Pyramid's ``pcreate`` command can list the available scaffolds: + +.. code-block:: bash + + $ pcreate --list + Available scaffolds: + alchemy: Pyramid SQLAlchemy project using url dispatch + pyramid_jinja2_starter: pyramid jinja2 starter project + starter: Pyramid starter project + zodb: Pyramid ZODB project using traversal + +The ``pyramid_jinja2`` add-on gave us a scaffold that we can use. From +the parent directory of where we want our Python package to be generated, +let's use that scaffold to make our project: + +.. code-block:: bash + + $ pcreate --scaffold pyramid_jinja2_starter hello_world + +We next use the normal Python development to setup our package for +development: + +.. code-block:: bash + + $ cd hello_world + $ python ./setup.py develop + +We are moving in the direction of a full-featured Pyramid project, +with a proper setup for Python standards (packaging) and Pyramid +configuration. This includes a new way of running your application: + +.. code-block:: bash + + $ pserve development.ini + +Let's look at ``pserve`` and configuration in more depth. + +Application Running with ``pserve`` +=================================== + +Prior to scaffolds, our project mixed a number of operations details +into our code. Why should my main code care with HTTP server I want and +what port number to run on? + +``pserve`` is Pyramid's application runner, separating operational +details from your code. When you install Pyramid, a small command +program called ``pserve`` is written to your ``bin`` directory. This +program is an executable Python module. It's very small, getting most +of its brains via import. + +You can run ``pserve`` with ``--help`` to see some of its options. +Doing so reveals that you can ask ``pserve`` to watch your development +files and reload the server when they change: + +.. code-block:: bash + + $ pserve development.ini --reload + +The ``pserve`` command has a number of other options and operations. +Most of the work, though, comes from your project's wiring, as +expressed in the configuration file you supply to ``pserve``. Let's +take a look at this configuration file. + +Configuration with ``.ini`` Files +================================= + +Earlier in *Quick Glance* we first met Pyramid's configuration system. +At that point we did all configuration in Python code. For example, +the port number chosen for our HTTP server was right there in Python +code. Our scaffold has moved this decision, and more, into the +``development.ini`` file: + +.. literalinclude:: quick_tour/package/development.ini + :language: ini + +Let's take a quick high-level look. First, the ``.ini`` file is divided +into sections: + +- ``[app:hello_world]`` configures our WSGI app + +- ``[pipeline:main]`` sets up our WSGI "pipeline" + +- ``[server:main]`` holds our WSGI server settings + +- Various sections afterwards configure our Python logging system + +We have a few decisions made for us in this configuration: + +#. *Choice of web server*. The ``use = egg:pyramid#wsgiref`` tell + ``pserve`` to the ``wsgiref`` server that is wrapped in the Pyramid + package. + +#. *Port number*. ``port = 6543`` tells ``wsgiref`` to listen on port + 6543. + +#. *WSGI app*. What package has our WSGI application in it? + ``use = egg:hello_world`` in the app section tells the + configuration what application to load. + +#. *Easier development by automatic template reloading*. In development + mode, you shouldn't have to restart the server when editing a Jinja2 + template. ``reload_templates = true`` sets this policy, + which might be different in production. + +Additionally, the ``development.ini`` generated by this scaffold wired +up Python's standard logging. We'll now see in the console, for example, +a log on every request that comes in, as well traceback information. + +Easier Development with ``debugtoolbar`` +======================================== + +As we introduce the basics we also want to show how to be productive in +development and debugging. For example, we just discussed template +reloading and earlier we showed ``--reload`` for application reloading. + +``pyramid_debugtoolbar`` is a popular Pyramid add-on which makes +several tools available in your browser. Adding it to your project +illustrates several points about configuration. + +First, change your ``setup.py`` to say: + +.. literalinclude:: quick_tour/package/setup.py + :start-after: Start Requires + :end-before: End Requires + +...and re-run your setup: + +.. code-block:: bash + + $ python ./setup.py develop + +The Python package was now installed into our environment. The package +is a Pyramid add-on, which means we need to include its configuration +into our web application. We could do this with imperative +configuration, as we did above for the ``pyramid_jinja2`` add-on: + +.. literalinclude:: quick_tour/package/hello_world/__init__.py + :start-after: Start Include + :end-before: End Include + +Now that we have a configuration file, we can use the +``pyramid.includes`` facility and place this in our +``development.ini`` instead: + +.. literalinclude:: quick_tour/package/development.ini + :language: ini + :start-after: Start Includes + :end-before: End Includes + +You'll now see an attractive (and +collapsible) menu in the right of your browser, providing introspective +access to debugging information. Even better, if your web application +generates an error, you will see a nice traceback on the screen. When +you want to disable this toolbar, no need to change code: you can +remove it from ``pyramid.includes`` in the relevant ``.ini`` +configuration file. + +Unit Tests and ``nose`` +======================= + +Yikes! We got this far and we haven't yet discussed tests. Particularly +egregious, as Pyramid has had a deep commitment to full test coverage +since before it was released. + +Our ``pyramid_jinja2_starter`` scaffold generated a ``tests.py`` module +with one unit test in it. To run it, let's install the handy ``nose`` +test runner by editing ``setup.py``. While we're at it, we'll throw in +the ``coverage`` tool which yells at us for code that isn't tested: + +.. code-block:: python + + setup(name='hello_world', + # Some lines removed... + extras_require={ + 'testing': ['nose', 'coverage'], + } + ) + +We changed ``setup.py`` which means we need to re-run +``python ./setup.py develop``. We can now run all our tests: + +.. code-block:: bash + + $ cd hello_world + $ nosetests . + . + Name Stmts Miss Cover Missing + --------------------------------------------------- + hello_world 12 8 33% 11-23 + hello_world.models 5 1 80% 8 + hello_world.tests 14 0 100% + hello_world.views 4 0 100% + --------------------------------------------------- + TOTAL 35 9 74% + ---------------------------------------------------------------------- + Ran 1 test in 0.931s + + OK + +Our unit test passed. What did our test look like? + +.. literalinclude:: quick_tour/package/hello_world/tests.py + +Pyramid supplies helpers for test writing, which we use in the +test setup and teardown. Our one test imports the view, +makes a dummy request, and sees if the view returns what we expected. + +Logging +======= + +It's important to know what is going on inside our web application. +In development we might need to collect some output. In production, +we might need to detect situations when other people use the site. We +need *logging*. + +Fortunately Pyramid uses the normal Python approach to logging. The +scaffold generated, in your ``development.ini``, a number of lines that +configure the logging for you to some reasonable defaults. You then see +messages sent by Pyramid (for example, when a new request comes in.) + +Maybe you would like to log messages in your code? In your Python +module, import and setup the logging: + +.. literalinclude:: quick_tour/package/hello_world/views.py + :start-after: Start Logging 1 + :end-before: End Logging 1 + +You can now, in your code, log messages: + +.. literalinclude:: quick_tour/package/hello_world/views.py + :start-after: Start Logging 2 + :end-before: End Logging 2 + +This will log ``Some Message`` at a ``debug`` log level, +to the application-configured logger in your ``development.ini``. What +controls that? These sections in the configuration file: + +.. literalinclude:: quick_tour/package/development.ini + :language: ini + :start-after: Start Sphinx Include + :end-before: End Sphinx Include + +Our application, a package named ``hello_world``, is setup as a logger +and configured to log messages at a ``DEBUG`` or higher level. When you +visit ``http://localhost:6543`` your console will now show:: + + 2013-08-09 10:42:42,968 DEBUG [hello_world.views][MainThread] Some Message + +Sessions +======== + +When people use your web application, they frequently perform a task +that requires semi-permanent data to be saved. For example, a shopping +cart. This is called a :term:`session`. + +Pyramid has basic built-in support for sessions, with add-ons such as +*Beaker* (or your own custom sessioning engine) that provide richer +session support. Let's take a look at the +:doc:`built-in sessioning support <../narr/sessions>`. In our +``__init__.py`` we first import the kind of sessioning we want: + +.. literalinclude:: quick_tour/package/hello_world/__init__.py + :start-after: Start Sphinx Include 1 + :end-before: End Sphinx Include 1 + +.. warning:: + + As noted in the session docs, this example implementation is + not intended for use in settings with security implications. + +Now make a "factory" and pass it to the :term:`configurator`'s +``session_factory`` argument: + +.. literalinclude:: quick_tour/package/hello_world/__init__.py + :start-after: Start Sphinx Include 2 + :end-before: End Sphinx Include 2 + +Pyramid's :term:`request` object now has a ``session`` attribute +that we can use in our view code: + +.. literalinclude:: quick_tour/package/hello_world/views.py + :start-after: Start Sphinx Include 1 + :end-before: End Sphinx Include 1 + +With this, each reload will increase the counter displayed in our +Jinja2 template: + +.. literalinclude:: quick_tour/package/hello_world/templates/mytemplate.jinja2 + :language: jinja + :start-after: Start Sphinx Include 1 + :end-before: End Sphinx Include 1 + + +Databases +========= + +Web applications mean data. Data means databases. Frequently SQL +databases. SQL Databases frequently mean an "ORM" +(object-relational mapper.) In Python, ORM usually leads to the +mega-quality *SQLAlchemy*, a Python package that greatly eases working +with databases. + +Pyramid and SQLAlchemy are great friends. That friendship includes a +scaffold! + +.. code-block:: bash + + $ pcreate --scaffold alchemy sqla_demo + $ cd sqla_demo + $ python setup.py develop + +We now have a working sample SQLAlchemy application with all +dependencies installed. The sample project provides a console script to +initialize a SQLite database with tables. Let's run it and then start +the application: + +.. code-block:: bash + + $ initialize_sqla_demo_db development.ini + $ pserve development.ini + +The ORM eases the mapping of database structures into a programming +language. SQLAlchemy uses "models" for this mapping. The scaffold +generated a sample model: + +.. literalinclude:: quick_tour/sqla_demo/sqla_demo/models.py + :start-after: Start Sphinx Include + :end-before: End Sphinx Include + +View code, which mediates the logic between web requests and the rest +of the system, can then easily get at the data thanks to SQLAlchemy: + +.. literalinclude:: quick_tour/sqla_demo/sqla_demo/views.py + :start-after: Start Sphinx Include + :end-before: End Sphinx Include + +Forms +===== + +Developers have lots of opinions about web forms, and thus there are many +form libraries for Python. Pyramid doesn't directly bundle a form +library, but *Deform* is a popular choice for forms, +along with its related *Colander* schema system. + +As an example, imagine we want a form that edits a wiki page. The form +should have two fields on it, one of them a required title and the +other a rich text editor for the body. With Deform we can express this +as a Colander schema: + +.. code-block:: python + + class WikiPage(colander.MappingSchema): + title = colander.SchemaNode(colander.String()) + body = colander.SchemaNode( + colander.String(), + widget=deform.widget.RichTextWidget() + ) + +With this in place, we can render the HTML for a form, +perhaps with form data from an existing page: + +.. code-block:: python + + form = self.wiki_form.render() + +We'd like to handle form submission, validation, and saving: + +.. code-block:: python + + # Get the form data that was posted + controls = self.request.POST.items() + try: + # Validate and either raise a validation error + # or return deserialized data from widgets + appstruct = wiki_form.validate(controls) + except deform.ValidationFailure as e: + # Bail out and render form with errors + return dict(title=title, page=page, form=e.render()) + + # Change the content and redirect to the view + page['title'] = appstruct['title'] + page['body'] = appstruct['body'] + +Deform and Colander provide a very flexible combination for forms, +widgets, schemas, and validation. Recent versions of Deform also +include a +`retail mode `_ +for gaining Deform +features on custom forms. + +Also, the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform +widgets using attractive CSS from Bootstrap and more powerful widgets +from Chosen. + + +Conclusion +========== + +This *Quick Tour* covered a little about a lot. We introduced a long list +of concepts in Pyramid, many of which are expanded on more fully in the +Pyramid developer docs. \ No newline at end of file -- cgit v1.2.3 From b853e5c9c0b19e6c6349d65dca52d6c3fe249358 Mon Sep 17 00:00:00 2001 From: kusut Date: Mon, 12 Aug 2013 21:09:36 +0700 Subject: use easy_install instead of pip in quick_tour guide. - consistent with another docs (pyramid/substanced uses easy_install). - prevent pip/easy_install namespace package fiasco since the docs uses setup.py develop instead of pip install -e --- docs/quick_tour.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index cc4afe67d..fcf799c6d 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -26,11 +26,9 @@ area in place. For Python 3.3: $ pyvenv-3.3 env33 $ source env33/bin/activate $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python - $ easy_install-3.3 pip 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. +packaging tools installed. Pyramid Installation ==================== @@ -40,7 +38,7 @@ installed is easy: .. code-block:: bash - $ pip install pyramid + $ easy_install pyramid Our virtual environment now has the Pyramid software available to its Python. @@ -245,7 +243,7 @@ our Pyramid applications: .. code-block:: bash - $ pip install pyramid_jinja2 + $ easy_install pyramid_jinja2 With the package installed, we can include the template bindings into our configuration: -- cgit v1.2.3 From 5b47ba8ce8c8bdb149b92a2b35a5e7607ca6fc00 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Mon, 12 Aug 2013 14:20:04 -0400 Subject: About to give Intersphinx a shot. --- docs/conf.py | 1 + docs/index.rst | 14 ++++++++------ docs/quick_tour.rst | 54 +++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 9b2f2f083..fe094a943 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,6 +55,7 @@ extensions = [ # Looks for objects in external projects intersphinx_mapping = { + 'tutorials': ('http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/', None), 'zcomponent': ('http://docs.zope.org/zope.component', None), 'webtest': ('http://webtest.pythonpaste.org/en/latest', None), 'webob': ('http://docs.webob.org/en/latest', None), diff --git a/docs/index.rst b/docs/index.rst index c4b81ad7d..f9f92e505 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -49,14 +49,15 @@ Getting Started =============== If you are new to Pyramid, we have a few resources that can help you get -up to speed right away. Our *Quick Tour* shows a little about a lot: +up to speed right away. .. toctree:: - :maxdepth: 2 + :hidden: quick_tour -Also: +* :doc:`quick_tour` goes through the major features in Pyramid, covering + a little about a lot. * To see a minimal Pyramid web application, check out `creating your first Pyramid application <../narr/firstapp>`_. @@ -67,10 +68,11 @@ Also: * To get the feel of how a Pyramid web application is created, go to the `single file tasks tutorial `_ page. -* Like learning by example? Check out to the `wiki tutorial - <../tutorials/wiki2/index.html>`_. +* Like learning by example? Check out to the :doc:`wiki tutorial + <../tutorials/wiki2/index>`. -* Need help? See `Support `_. +* Need help? See :ref:`Support and + Development `. .. _html_narrative_documentation: diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index cc4afe67d..13d936a6b 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -2,6 +2,10 @@ Quick Tour of Pyramid ===================== +TODO: + +- Convert all the See Also below into Intersphinx links + Pyramid lets you start small and finish big. This *Quick Tour* guide walks you through many of Pyramid's key features. Let's put the emphasis on *start* by doing a quick tour through Pyramid, with @@ -32,6 +36,10 @@ 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. +See Also: http://docs.python.org/dev/library/venv.html, +https://pypi.python.org/pypi/setuptools/0.9.8#installation-instructions, +http://www.pip-installer.org/en/latest/, narr/install.html#before-you-install + Pyramid Installation ==================== @@ -45,6 +53,8 @@ installed is easy: Our virtual environment now has the Pyramid software available to its Python. +See Also: narr/install.html#installing-pyramid-on-a-unix-system, + Hello World =========== @@ -82,6 +92,9 @@ in Pyramid development. Building an application from loosely-coupled parts via :doc:`../narr/configuration` is a central idea in Pyramid, one that we will revisit regurlarly in this *Quick Tour*. +See Also: narr/firstapp, +http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/single_file_tasks/single_file_tasks.html + Handling Web Requests and Responses =================================== @@ -110,6 +123,10 @@ the name is included in the body of the response:: Finally, we set the response's content type and return the Response. +See Also: http://localhost:8080/projects/pyramid/docs +.gettingstarted/docs/_build/narr/webob.html#webob-chapter, + + Views ===== @@ -158,6 +175,8 @@ configuration`, in which a Python :term:`decorator` is placed on the line above the view. Both approaches result in the same final configuration, thus usually, it is simply a matter of taste. +See Also: narr/views.html, narr/viewconfig, +narr/viewconfig.html#debugging-view-configuration Routing ======= @@ -200,10 +219,8 @@ view: "replacement patterns" (the curly braces) in the route declaration. This information can then be used in your view. -As you might imagine, Pyramid provides -:doc:`many more features in routing <../narr/urldispatch>` -(route factories, custom predicates, security statements, -etc.) We will see more features later in *Geting Started*. +See Also: narr/urldispatch, narr/urldispatch +.html#debugging-route-matching, narr/router Templating ========== @@ -234,6 +251,9 @@ Since our view returned ``dict(name=request.matchdict['name'])``, we can use ``name`` as a variable in our template via ``${name}``. +See Also: narr/templates, narr/templates.html#debugging-templates, +templates.html#templating-with-mako-templates, + Templating With ``jinja2`` ========================== @@ -276,6 +296,7 @@ renderer. At the time of this writing, Jinja2 had not released a version compatible with Python 3.3. +See Also: Jinja2, pyramid_jinja2, Static Assets ============= @@ -320,6 +341,9 @@ By using ``request.static_url`` to generate the full URL to the static assets, you both ensure you stay in sync with the configuration and gain refactoring flexibility later. +See Also: narr/assets, narr/environment.html#preventing-http-caching, +narr/viewconfig.html#influencing-http-caching, + Returning JSON ============== @@ -335,6 +359,9 @@ This wires up a view that returns some data through the JSON :term:`renderer`, which calls Python's JSON support to serialize the data into JSON and set the appropriate HTTP headers. +See Also: narr/renderers.html#json-renderer, +narr/renderers.html#adding-and-overriding-renderers + View Classes ============ @@ -376,6 +403,8 @@ Only one route needed, stated in one place atop the view class. Also, the assignment of the ``name`` is done in the ``__init__``. Our templates can then use ``{{ view.name }}``. +See Also: narr/views.html#defining-a-view-callable-as-a-class + Quick Project Startup with Scaffolds ==================================== @@ -422,6 +451,8 @@ configuration. This includes a new way of running your application: Let's look at ``pserve`` and configuration in more depth. +See Also: narr/project.html#creating-a-pyramid-project, narr/scaffolding.html + Application Running with ``pserve`` =================================== @@ -493,6 +524,9 @@ Additionally, the ``development.ini`` generated by this scaffold wired up Python's standard logging. We'll now see in the console, for example, a log on every request that comes in, as well traceback information. +See Also: narr/environment.html#environment-variables-and-ini-file +-settings, narr/paste.html + Easier Development with ``debugtoolbar`` ======================================== @@ -542,6 +576,8 @@ you want to disable this toolbar, no need to change code: you can remove it from ``pyramid.includes`` in the relevant ``.ini`` configuration file. +See Also: pyramid_debugtoolbar + Unit Tests and ``nose`` ======================= @@ -592,6 +628,9 @@ Pyramid supplies helpers for test writing, which we use in the test setup and teardown. Our one test imports the view, makes a dummy request, and sees if the view returns what we expected. +See Also: nose, narr/testing +.html#unit-integration-and-functional-testing, + Logging ======= @@ -633,6 +672,8 @@ visit ``http://localhost:6543`` your console will now show:: 2013-08-09 10:42:42,968 DEBUG [hello_world.views][MainThread] Some Message +See Also: narr/sessions.html, narr/sessions.html#flash-messages, + Sessions ======== @@ -677,6 +718,7 @@ Jinja2 template: :start-after: Start Sphinx Include 1 :end-before: End Sphinx Include 1 +See Also: narr/sessions.html#sessions, api/session.html Databases ========= @@ -721,6 +763,9 @@ of the system, can then easily get at the data thanks to SQLAlchemy: :start-after: Start Sphinx Include :end-before: End Sphinx Include +See Also: sqlalchemy, narr/commandline + .html#making-your-script-into-a-console-script, pyramid_tm, + Forms ===== @@ -780,6 +825,7 @@ Also, the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform widgets using attractive CSS from Bootstrap and more powerful widgets from Chosen. +See Also: Deform, Colander Conclusion ========== -- cgit v1.2.3 From a1f768cc766516e81f295c7ad507305e526a740e Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Mon, 12 Aug 2013 20:50:55 +0200 Subject: Allow explicit cookie domain setting. This is useful as an escape hatch when dealing with enviroments where no normal rules apply. --- CHANGES.txt | 10 +++++++--- pyramid/authentication.py | 29 ++++++++++++++++++++++------- pyramid/tests/test_authentication.py | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index e9533ab48..2e1a2efd4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -49,9 +49,13 @@ Features ``pyramid.config.Configurator.add_static_view``. This allows externally-hosted static URLs to be generated based on the current protocol. -- The ``AuthTktAuthenticationPolicy`` has a new ``parent_domain`` option to - set the authentication cookie as a wildcard cookie on the parent domain. This - is useful if you have multiple sites sharing the same domain. +- The ``AuthTktAuthenticationPolicy`` has two new options to configure its + domain usage: + * ``parent_domain``: if set the authentication cookie is set on + the parent domain. This is useful if you have multiple sites sharing the + same domain. + * ``domain``: if provided the cookie is always set for this domain, bypassing + all usual logic. - The ``AuthTktAuthenticationPolicy`` now supports IPv6 addresses when using the ``include_ip=True`` option. This is possibly incompatible with diff --git a/pyramid/authentication.py b/pyramid/authentication.py index 565393a34..454ebd4b2 100644 --- a/pyramid/authentication.py +++ b/pyramid/authentication.py @@ -528,6 +528,15 @@ class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy): This option is available as of :app:`Pyramid` 1.5. + ``domain`` + + Default: ``None``. If provided the auth_tkt cookie will only be + set for this domain. This option is not compatible with ``wild_domain`` + and ``parent_domain``. + Optional. + + This option is available as of :app:`Pyramid` 1.5. + ``hashalg`` Default: ``md5`` (the literal string). @@ -581,6 +590,7 @@ class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy): debug=False, hashalg=_marker, parent_domain=False, + domain=None, ): if hashalg is _marker: hashalg = 'md5' @@ -619,6 +629,7 @@ class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy): wild_domain=wild_domain, hashalg=hashalg, parent_domain=parent_domain, + domain=domain, ) self.callback = callback self.debug = debug @@ -816,7 +827,7 @@ class AuthTktCookieHelper(object): def __init__(self, secret, cookie_name='auth_tkt', secure=False, include_ip=False, timeout=None, reissue_time=None, max_age=None, http_only=False, path="/", wild_domain=True, - hashalg='md5', parent_domain=False): + hashalg='md5', parent_domain=False, domain=None): self.secret = secret self.cookie_name = cookie_name self.include_ip = include_ip @@ -828,6 +839,7 @@ class AuthTktCookieHelper(object): self.path = path self.wild_domain = wild_domain self.parent_domain = parent_domain + self.domain = domain self.hashalg = hashalg static_flags = [] @@ -867,13 +879,16 @@ class AuthTktCookieHelper(object): domains = [] - if self.parent_domain and cur_domain.count('.') > 1: - domains.append('.' + cur_domain.split('.', 1)[1]) + if self.domain: + domains.append(self.domain) else: - domains.append(None) - domains.append(cur_domain) - if self.wild_domain: - domains.append('.' + cur_domain) + if self.parent_domain and cur_domain.count('.') > 1: + domains.append('.' + cur_domain.split('.', 1)[1]) + else: + domains.append(None) + domains.append(cur_domain) + if self.wild_domain: + domains.append('.' + cur_domain) cookies = [] base_cookie = '%s="%s"; Path=%s%s%s' % (self.cookie_name, value, diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py index d787d09b7..6e9e3920d 100644 --- a/pyramid/tests/test_authentication.py +++ b/pyramid/tests/test_authentication.py @@ -966,6 +966,26 @@ class TestAuthTktCookieHelper(unittest.TestCase): self.assertEqual(len(result), 1) self.assertTrue(result[0][1].endswith('; Domain=.example.com')) + def test_remember_explicit_domain(self): + helper = self._makeOne('secret', domain='pyramid.bazinga') + request = self._makeRequest() + request.environ['HTTP_HOST'] = 'www.example.com' + result = helper.remember(request, 'other') + self.assertEqual(len(result), 1) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith('; Path=/; Domain=pyramid.bazinga')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + def test_remember_domain_supercedes_parent_and_wild_domain(self): + helper = self._makeOne('secret', domain='pyramid.bazinga', + parent_domain=True, wild_domain=True) + request = self._makeRequest() + request.environ['HTTP_HOST'] = 'www.example.com' + result = helper.remember(request, 'other') + self.assertEqual(len(result), 1) + self.assertTrue(result[0][1].endswith('; Path=/; Domain=pyramid.bazinga')) + def test_remember_domain_has_port(self): helper = self._makeOne('secret', wild_domain=False) request = self._makeRequest() -- cgit v1.2.3 From 49d634bd813e63c3db5e56d29376126c2646182a Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Mon, 12 Aug 2013 19:29:23 -0400 Subject: All wrapped up, pre-merge. --- docs/conf.py | 13 ++++++ docs/index.rst | 77 ++++++------------------------------ docs/narr/sessions.rst | 2 + docs/narr/templates.rst | 2 + docs/narr/viewconfig.rst | 2 + docs/quick_tour.rst | 100 +++++++++++++++++++++++++++-------------------- 6 files changed, 88 insertions(+), 108 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index fe094a943..5870ce872 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -56,9 +56,22 @@ extensions = [ # Looks for objects in external projects intersphinx_mapping = { 'tutorials': ('http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/', None), + 'jinja2': ('http://docs.pylonsproject.org/projects/pyramid_jinja2/en/latest/', None), + 'tm': ( + 'http://docs.pylonsproject.org/projects/pyramid_tm/en/latest/', + None, + ), + 'debugtoolbar': ( + 'http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest/', None), 'zcomponent': ('http://docs.zope.org/zope.component', None), 'webtest': ('http://webtest.pythonpaste.org/en/latest', None), 'webob': ('http://docs.webob.org/en/latest', None), + 'colander': ( + 'http://docs.pylonsproject.org/projects/colander/en/latest', + None), + 'deform': ( + 'http://docs.pylonsproject.org/projects/deform/en/latest', + None), 'sqla': ('http://docs.sqlalchemy.org/en/latest', None), 'who': ('http://docs.repoze.org/who/latest', None), 'python': ('http://docs.python.org', None), diff --git a/docs/index.rst b/docs/index.rst index f9f92e505..d570e7811 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -31,18 +31,6 @@ Front Matter copyright.rst conventions.rst -What's New -========== - -.. toctree:: - :maxdepth: 1 - - whatsnew-1.4 - whatsnew-1.3 - whatsnew-1.2 - whatsnew-1.1 - whatsnew-1.0 - .. _html_getting_started: Getting Started @@ -59,17 +47,17 @@ up to speed right away. * :doc:`quick_tour` goes through the major features in Pyramid, covering a little about a lot. -* To see a minimal Pyramid web application, check out `creating your first - Pyramid application <../narr/firstapp>`_. - * For help getting Pyramid set up, try the `install guide <../narr/install>`_. -* To get the feel of how a Pyramid web application is created, go to the - `single file tasks tutorial `_ page. +* To see a minimal Pyramid web application, check out `creating your first + Pyramid application <../narr/firstapp>`_. -* Like learning by example? Check out to the :doc:`wiki tutorial - <../tutorials/wiki2/index>`. +* Like learning by example? Visit the official + :doc:`wiki tutorial <../tutorials/wiki2/index>` as well as the + community-contributed + :ref:`Pyramid tutorials `, which include + a :ref:`single file tasks tutorial `. * Need help? See :ref:`Support and Development `. @@ -158,6 +146,11 @@ Change History .. toctree:: :maxdepth: 1 + whatsnew-1.4 + whatsnew-1.3 + whatsnew-1.2 + whatsnew-1.1 + whatsnew-1.0 changes Design Documents @@ -168,52 +161,6 @@ Design Documents designdefense -Sample Applications -=================== - -.. note:: - - These applications run only on Python 2.x, and so do some of their - dependencies. - -`cluegun `_ is a simple pastebin -application based on Rocky Burt's `ClueBin -`_. It demonstrates form -processing, security, and the use of :term:`ZODB` within a :app:`Pyramid` -application. Check this application out via: - -.. code-block:: text - - git clone git://github.com/Pylons/cluegun.git - -`virginia `_ is a very simple dynamic -file rendering application. It is willing to render structured text -documents, HTML documents, and images from a filesystem directory. -It's also a good example of :term:`traversal`. An -earlier version of this application runs the `repoze.org -`_ website. Check this application out via: - -.. code-block:: text - - git clone git://github.com/Pylons/virginia.git - -`shootout `_ is an example "idea -competition" application by Carlos de la Guardia and Lukasz Fidosz. It -demonstrates :term:`URL dispatch`, simple authentication, integration -with `SQLAlchemy `_ and ``pyramid_simpleform``. -Check this application out of version control via: - -.. code-block:: text - - git clone git://github.com/Pylons/shootout.git - -`KARL `_ is a moderately-sized application (roughly -80K lines of Python code) built on top of :app:`Pyramid`. It is an open -source web system for collaboration, organizational intranets, and knowledge -management. It provides facilities for wikis, calendars, manuals, searching, -tagging, commenting, and file uploads. See the `KARL site -`_ for download and installation details. - .. _support-and-development: Support and Development diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst index 7ec280c8a..7ba46c92c 100644 --- a/docs/narr/sessions.rst +++ b/docs/narr/sessions.rst @@ -181,6 +181,8 @@ implementation in the :mod:`pyramid.session` module as inspiration. .. index:: single: flash messages +.. _flash_messages: + Flash Messages -------------- diff --git a/docs/narr/templates.rst b/docs/narr/templates.rst index f1e1634b8..a70398c80 100644 --- a/docs/narr/templates.rst +++ b/docs/narr/templates.rst @@ -616,6 +616,8 @@ extension so that these ``svn:ignore`` patterns work. .. index:: pair: debugging; templates +.. _debugging_templates: + Debugging Templates ------------------- diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index 241ce62b5..047898cfe 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -976,6 +976,8 @@ invoked as the result of the ``http_cache`` argument to view configuration. .. index:: pair: view configuration; debugging +.. _debugging_view_configuration: + Debugging View Configuration ---------------------------- diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 13d936a6b..28fefb49c 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -1,11 +1,9 @@ +.. _quick_tour: + ===================== Quick Tour of Pyramid ===================== -TODO: - -- Convert all the See Also below into Intersphinx links - Pyramid lets you start small and finish big. This *Quick Tour* guide walks you through many of Pyramid's key features. Let's put the emphasis on *start* by doing a quick tour through Pyramid, with @@ -36,9 +34,12 @@ 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. -See Also: http://docs.python.org/dev/library/venv.html, -https://pypi.python.org/pypi/setuptools/0.9.8#installation-instructions, -http://www.pip-installer.org/en/latest/, narr/install.html#before-you-install +.. seealso:: See Also: Python 3's :mod:`venv module `, + the ``setuptools`` `installation + instructions `_, + documentation for `pip `_, + and + Pyramid's :ref:`Before You Install ` Pyramid Installation ==================== @@ -53,7 +54,7 @@ installed is easy: Our virtual environment now has the Pyramid software available to its Python. -See Also: narr/install.html#installing-pyramid-on-a-unix-system, +.. seealso:: See Also: :ref:`installing_unix` Hello World =========== @@ -92,8 +93,8 @@ in Pyramid development. Building an application from loosely-coupled parts via :doc:`../narr/configuration` is a central idea in Pyramid, one that we will revisit regurlarly in this *Quick Tour*. -See Also: narr/firstapp, -http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/single_file_tasks/single_file_tasks.html +.. seealso:: See Also: :ref:`firstapp_chapter` and + :ref:`Single File Tasks tutorial ` Handling Web Requests and Responses =================================== @@ -123,9 +124,7 @@ the name is included in the body of the response:: Finally, we set the response's content type and return the Response. -See Also: http://localhost:8080/projects/pyramid/docs -.gettingstarted/docs/_build/narr/webob.html#webob-chapter, - +.. seealso:: See Also: :ref:`webob_chapter` Views ===== @@ -175,8 +174,9 @@ configuration`, in which a Python :term:`decorator` is placed on the line above the view. Both approaches result in the same final configuration, thus usually, it is simply a matter of taste. -See Also: narr/views.html, narr/viewconfig, -narr/viewconfig.html#debugging-view-configuration +.. seealso:: See Also: :doc:`../narr/views`, + :doc:`../narr/viewconfig`, and + :ref:`debugging_view_configuration` Routing ======= @@ -219,8 +219,9 @@ view: "replacement patterns" (the curly braces) in the route declaration. This information can then be used in your view. -See Also: narr/urldispatch, narr/urldispatch -.html#debugging-route-matching, narr/router +.. seealso:: See Also: :doc:`../narr/urldispatch`, + :ref:`debug_routematch_section`, and + :doc:`../narr/router` Templating ========== @@ -251,8 +252,9 @@ Since our view returned ``dict(name=request.matchdict['name'])``, we can use ``name`` as a variable in our template via ``${name}``. -See Also: narr/templates, narr/templates.html#debugging-templates, -templates.html#templating-with-mako-templates, +.. seealso:: See Also: :doc:`../narr/templates`, + :ref:`debugging_templates`, and + :ref:`mako_templates` Templating With ``jinja2`` ========================== @@ -291,12 +293,9 @@ filename extensions. In this case, changing the extension from ``.pt`` to ``.jinja2`` passed the view response through the ``pyramid_jinja2`` renderer. -.. note:: - - At the time of this writing, Jinja2 had not released a version - compatible with Python 3.3. - -See Also: Jinja2, pyramid_jinja2, +.. seealso:: See Also: `Jinja2 homepage `_, + and + :ref:`pyramid_jinja2 Overview ` Static Assets ============= @@ -341,8 +340,9 @@ By using ``request.static_url`` to generate the full URL to the static assets, you both ensure you stay in sync with the configuration and gain refactoring flexibility later. -See Also: narr/assets, narr/environment.html#preventing-http-caching, -narr/viewconfig.html#influencing-http-caching, +.. seealso:: See Also: :doc:`../narr/assets`, + :ref:`preventing_http_caching`, and + :ref:`influencing_http_caching` Returning JSON ============== @@ -359,8 +359,9 @@ This wires up a view that returns some data through the JSON :term:`renderer`, which calls Python's JSON support to serialize the data into JSON and set the appropriate HTTP headers. -See Also: narr/renderers.html#json-renderer, -narr/renderers.html#adding-and-overriding-renderers +.. seealso:: See Also: :ref:`views_which_use_a_renderer`, + :ref:`json_renderer`, and + :ref:`adding_and_overriding_renderers` View Classes ============ @@ -403,7 +404,7 @@ Only one route needed, stated in one place atop the view class. Also, the assignment of the ``name`` is done in the ``__init__``. Our templates can then use ``{{ view.name }}``. -See Also: narr/views.html#defining-a-view-callable-as-a-class +.. seealso:: See Also: :ref:`class_as_view` Quick Project Startup with Scaffolds ==================================== @@ -451,7 +452,8 @@ configuration. This includes a new way of running your application: Let's look at ``pserve`` and configuration in more depth. -See Also: narr/project.html#creating-a-pyramid-project, narr/scaffolding.html +.. seealso:: See Also: :ref:`project_narr` and + :doc:`../narr/scaffolding` Application Running with ``pserve`` =================================== @@ -479,6 +481,8 @@ Most of the work, though, comes from your project's wiring, as expressed in the configuration file you supply to ``pserve``. Let's take a look at this configuration file. +.. seealso:: See Also: :ref:`what_is_this_pserve_thing` + Configuration with ``.ini`` Files ================================= @@ -524,8 +528,9 @@ Additionally, the ``development.ini`` generated by this scaffold wired up Python's standard logging. We'll now see in the console, for example, a log on every request that comes in, as well traceback information. -See Also: narr/environment.html#environment-variables-and-ini-file --settings, narr/paste.html +.. seealso:: See Also: :ref:`environment_chapter` and + :doc:`../narr/paste` + Easier Development with ``debugtoolbar`` ======================================== @@ -576,7 +581,8 @@ you want to disable this toolbar, no need to change code: you can remove it from ``pyramid.includes`` in the relevant ``.ini`` configuration file. -See Also: pyramid_debugtoolbar +.. seealso:: See Also: `pyramid_debugtoolbar + `_ Unit Tests and ``nose`` ======================= @@ -604,8 +610,7 @@ We changed ``setup.py`` which means we need to re-run .. code-block:: bash - $ cd hello_world - $ nosetests . + $ nosetests hello_world/tests.py . Name Stmts Miss Cover Missing --------------------------------------------------- @@ -628,8 +633,7 @@ Pyramid supplies helpers for test writing, which we use in the test setup and teardown. Our one test imports the view, makes a dummy request, and sees if the view returns what we expected. -See Also: nose, narr/testing -.html#unit-integration-and-functional-testing, +.. seealso:: See Also: :ref:`testing_chapter` Logging ======= @@ -672,7 +676,7 @@ visit ``http://localhost:6543`` your console will now show:: 2013-08-09 10:42:42,968 DEBUG [hello_world.views][MainThread] Some Message -See Also: narr/sessions.html, narr/sessions.html#flash-messages, +.. seealso:: See Also: :ref:`logging_chapter` Sessions ======== @@ -718,7 +722,11 @@ Jinja2 template: :start-after: Start Sphinx Include 1 :end-before: End Sphinx Include 1 -See Also: narr/sessions.html#sessions, api/session.html +.. seealso:: See Also: + :ref:`sessions_chapter`, :ref:`flash_messages`, + :ref:`session_module`, and + `Beaker sessioning middleware + `_ Databases ========= @@ -763,8 +771,11 @@ of the system, can then easily get at the data thanks to SQLAlchemy: :start-after: Start Sphinx Include :end-before: End Sphinx Include -See Also: sqlalchemy, narr/commandline - .html#making-your-script-into-a-console-script, pyramid_tm, +.. seealso:: See Also: `SQLAlchemy `_, + :ref:`making_a_console_script`, + :ref:`bfg_sql_wiki_tutorial`, and + `Application Transactions With pyramid_tm + `_ Forms ===== @@ -825,7 +836,10 @@ Also, the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform widgets using attractive CSS from Bootstrap and more powerful widgets from Chosen. -See Also: Deform, Colander +.. seealso:: See Also: + `Deform `_, + `Colander `_, and + `deform_bootstrap `_ Conclusion ========== -- cgit v1.2.3 From c90471defdd552b4a8c2073914cfd49e7d9f2ca0 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Mon, 12 Aug 2013 19:59:33 -0400 Subject: Forgot to add the subdir --- docs/conf.py | 2 - docs/quick_tour.rst | 3 +- docs/quick_tour/awesome/CHANGES.txt | 4 + docs/quick_tour/awesome/MANIFEST.in | 2 + docs/quick_tour/awesome/README.txt | 4 + docs/quick_tour/awesome/awesome/__init__.py | 23 ++ docs/quick_tour/awesome/awesome/locale/awesome.pot | 21 ++ .../awesome/locale/de/LC_MESSAGES/awesome.mo | Bin 0 -> 460 bytes .../awesome/locale/de/LC_MESSAGES/awesome.po | 21 ++ .../awesome/locale/fr/LC_MESSAGES/awesome.mo | Bin 0 -> 461 bytes .../awesome/locale/fr/LC_MESSAGES/awesome.po | 21 ++ docs/quick_tour/awesome/awesome/models.py | 8 + docs/quick_tour/awesome/awesome/static/favicon.ico | Bin 0 -> 1406 bytes docs/quick_tour/awesome/awesome/static/logo.png | Bin 0 -> 6641 bytes docs/quick_tour/awesome/awesome/static/pylons.css | 73 ++++ .../awesome/awesome/templates/mytemplate.jinja2 | 87 +++++ docs/quick_tour/awesome/awesome/tests.py | 21 ++ docs/quick_tour/awesome/awesome/views.py | 6 + docs/quick_tour/awesome/development.ini | 49 +++ docs/quick_tour/awesome/message-extraction.ini | 3 + docs/quick_tour/awesome/setup.cfg | 28 ++ docs/quick_tour/awesome/setup.py | 36 ++ docs/quick_tour/hello_world/app.py | 16 + docs/quick_tour/jinja2/app.py | 11 + docs/quick_tour/jinja2/hello_world.jinja2 | 8 + docs/quick_tour/jinja2/views.py | 8 + docs/quick_tour/json/app.py | 15 + docs/quick_tour/json/hello_world.jinja2 | 10 + docs/quick_tour/json/hello_world.pt | 17 + docs/quick_tour/json/views.py | 13 + docs/quick_tour/package/CHANGES.txt | 4 + docs/quick_tour/package/MANIFEST.in | 2 + docs/quick_tour/package/README.txt | 4 + docs/quick_tour/package/development.ini | 57 ++++ docs/quick_tour/package/hello_world/__init__.py | 34 ++ docs/quick_tour/package/hello_world/init.py | 34 ++ .../locale/de/LC_MESSAGES/hello_world.mo | Bin 0 -> 460 bytes .../locale/de/LC_MESSAGES/hello_world.po | 21 ++ .../locale/fr/LC_MESSAGES/hello_world.mo | Bin 0 -> 461 bytes .../locale/fr/LC_MESSAGES/hello_world.po | 21 ++ .../package/hello_world/locale/hello_world.pot | 21 ++ docs/quick_tour/package/hello_world/models.py | 8 + .../package/hello_world/static/favicon.ico | Bin 0 -> 1406 bytes .../quick_tour/package/hello_world/static/logo.png | Bin 0 -> 6641 bytes .../package/hello_world/static/pylons.css | 73 ++++ .../hello_world/templates/mytemplate.jinja2 | 90 +++++ docs/quick_tour/package/hello_world/tests.py | 20 ++ docs/quick_tour/package/hello_world/views.py | 22 ++ docs/quick_tour/package/message-extraction.ini | 3 + docs/quick_tour/package/setup.cfg | 28 ++ docs/quick_tour/package/setup.py | 41 +++ docs/quick_tour/requests/app.py | 24 ++ docs/quick_tour/routing/app.py | 12 + docs/quick_tour/routing/views.py | 10 + docs/quick_tour/sqla_demo/CHANGES.txt | 4 + docs/quick_tour/sqla_demo/MANIFEST.in | 2 + docs/quick_tour/sqla_demo/README.txt | 14 + docs/quick_tour/sqla_demo/development.ini | 71 ++++ docs/quick_tour/sqla_demo/production.ini | 62 ++++ docs/quick_tour/sqla_demo/setup.cfg | 27 ++ docs/quick_tour/sqla_demo/setup.py | 44 +++ docs/quick_tour/sqla_demo/sqla_demo.sqlite | Bin 0 -> 3072 bytes docs/quick_tour/sqla_demo/sqla_demo/__init__.py | 20 ++ docs/quick_tour/sqla_demo/sqla_demo/models.py | 29 ++ .../sqla_demo/sqla_demo/scripts/__init__.py | 1 + .../sqla_demo/sqla_demo/scripts/initializedb.py | 37 ++ .../sqla_demo/sqla_demo/static/favicon.ico | Bin 0 -> 1406 bytes .../sqla_demo/sqla_demo/static/footerbg.png | Bin 0 -> 333 bytes .../sqla_demo/sqla_demo/static/headerbg.png | Bin 0 -> 203 bytes docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css | 8 + .../sqla_demo/sqla_demo/static/middlebg.png | Bin 0 -> 2797 bytes .../sqla_demo/sqla_demo/static/pylons.css | 372 +++++++++++++++++++++ .../sqla_demo/sqla_demo/static/pyramid-small.png | Bin 0 -> 7044 bytes .../sqla_demo/sqla_demo/static/pyramid.png | Bin 0 -> 33055 bytes .../sqla_demo/sqla_demo/static/transparent.gif | Bin 0 -> 49 bytes .../sqla_demo/sqla_demo/templates/mytemplate.pt | 76 +++++ docs/quick_tour/sqla_demo/sqla_demo/tests.py | 33 ++ docs/quick_tour/sqla_demo/sqla_demo/views.py | 37 ++ docs/quick_tour/static_assets/app.py | 14 + docs/quick_tour/static_assets/hello_world.jinja2 | 10 + docs/quick_tour/static_assets/hello_world.pt | 16 + docs/quick_tour/static_assets/static/app.css | 4 + docs/quick_tour/static_assets/views.py | 6 + docs/quick_tour/templating/app.py | 10 + docs/quick_tour/templating/hello_world.pt | 9 + docs/quick_tour/templating/views.py | 8 + docs/quick_tour/view_classes/app.py | 13 + docs/quick_tour/view_classes/delete.jinja2 | 9 + docs/quick_tour/view_classes/edit.jinja2 | 9 + docs/quick_tour/view_classes/hello.jinja2 | 17 + docs/quick_tour/view_classes/views.py | 32 ++ docs/quick_tour/views/app.py | 13 + docs/quick_tour/views/views.py | 29 ++ 93 files changed, 2071 insertions(+), 4 deletions(-) create mode 100644 docs/quick_tour/awesome/CHANGES.txt create mode 100644 docs/quick_tour/awesome/MANIFEST.in create mode 100644 docs/quick_tour/awesome/README.txt create mode 100644 docs/quick_tour/awesome/awesome/__init__.py create mode 100644 docs/quick_tour/awesome/awesome/locale/awesome.pot create mode 100644 docs/quick_tour/awesome/awesome/locale/de/LC_MESSAGES/awesome.mo create mode 100644 docs/quick_tour/awesome/awesome/locale/de/LC_MESSAGES/awesome.po create mode 100644 docs/quick_tour/awesome/awesome/locale/fr/LC_MESSAGES/awesome.mo create mode 100644 docs/quick_tour/awesome/awesome/locale/fr/LC_MESSAGES/awesome.po create mode 100644 docs/quick_tour/awesome/awesome/models.py create mode 100644 docs/quick_tour/awesome/awesome/static/favicon.ico create mode 100644 docs/quick_tour/awesome/awesome/static/logo.png create mode 100644 docs/quick_tour/awesome/awesome/static/pylons.css create mode 100644 docs/quick_tour/awesome/awesome/templates/mytemplate.jinja2 create mode 100644 docs/quick_tour/awesome/awesome/tests.py create mode 100644 docs/quick_tour/awesome/awesome/views.py create mode 100644 docs/quick_tour/awesome/development.ini create mode 100644 docs/quick_tour/awesome/message-extraction.ini create mode 100644 docs/quick_tour/awesome/setup.cfg create mode 100644 docs/quick_tour/awesome/setup.py create mode 100644 docs/quick_tour/hello_world/app.py create mode 100644 docs/quick_tour/jinja2/app.py create mode 100644 docs/quick_tour/jinja2/hello_world.jinja2 create mode 100644 docs/quick_tour/jinja2/views.py create mode 100644 docs/quick_tour/json/app.py create mode 100644 docs/quick_tour/json/hello_world.jinja2 create mode 100644 docs/quick_tour/json/hello_world.pt create mode 100644 docs/quick_tour/json/views.py create mode 100644 docs/quick_tour/package/CHANGES.txt create mode 100644 docs/quick_tour/package/MANIFEST.in create mode 100644 docs/quick_tour/package/README.txt create mode 100644 docs/quick_tour/package/development.ini create mode 100644 docs/quick_tour/package/hello_world/__init__.py create mode 100644 docs/quick_tour/package/hello_world/init.py create mode 100644 docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo create mode 100644 docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.po create mode 100644 docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo create mode 100644 docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po create mode 100644 docs/quick_tour/package/hello_world/locale/hello_world.pot create mode 100644 docs/quick_tour/package/hello_world/models.py create mode 100644 docs/quick_tour/package/hello_world/static/favicon.ico create mode 100644 docs/quick_tour/package/hello_world/static/logo.png create mode 100644 docs/quick_tour/package/hello_world/static/pylons.css create mode 100644 docs/quick_tour/package/hello_world/templates/mytemplate.jinja2 create mode 100644 docs/quick_tour/package/hello_world/tests.py create mode 100644 docs/quick_tour/package/hello_world/views.py create mode 100644 docs/quick_tour/package/message-extraction.ini create mode 100644 docs/quick_tour/package/setup.cfg create mode 100644 docs/quick_tour/package/setup.py create mode 100644 docs/quick_tour/requests/app.py create mode 100644 docs/quick_tour/routing/app.py create mode 100644 docs/quick_tour/routing/views.py create mode 100644 docs/quick_tour/sqla_demo/CHANGES.txt create mode 100644 docs/quick_tour/sqla_demo/MANIFEST.in create mode 100644 docs/quick_tour/sqla_demo/README.txt create mode 100644 docs/quick_tour/sqla_demo/development.ini create mode 100644 docs/quick_tour/sqla_demo/production.ini create mode 100644 docs/quick_tour/sqla_demo/setup.cfg create mode 100644 docs/quick_tour/sqla_demo/setup.py create mode 100644 docs/quick_tour/sqla_demo/sqla_demo.sqlite create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/__init__.py create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/models.py create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/scripts/__init__.py create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/favicon.ico create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/footerbg.png create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/headerbg.png create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/middlebg.png create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/pylons.css create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-small.png create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.png create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/static/transparent.gif create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.pt create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/tests.py create mode 100644 docs/quick_tour/sqla_demo/sqla_demo/views.py create mode 100644 docs/quick_tour/static_assets/app.py create mode 100644 docs/quick_tour/static_assets/hello_world.jinja2 create mode 100644 docs/quick_tour/static_assets/hello_world.pt create mode 100644 docs/quick_tour/static_assets/static/app.css create mode 100644 docs/quick_tour/static_assets/views.py create mode 100644 docs/quick_tour/templating/app.py create mode 100644 docs/quick_tour/templating/hello_world.pt create mode 100644 docs/quick_tour/templating/views.py create mode 100644 docs/quick_tour/view_classes/app.py create mode 100644 docs/quick_tour/view_classes/delete.jinja2 create mode 100644 docs/quick_tour/view_classes/edit.jinja2 create mode 100644 docs/quick_tour/view_classes/hello.jinja2 create mode 100644 docs/quick_tour/view_classes/views.py create mode 100644 docs/quick_tour/views/app.py create mode 100644 docs/quick_tour/views/views.py diff --git a/docs/conf.py b/docs/conf.py index 5870ce872..e60cd7118 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -61,8 +61,6 @@ intersphinx_mapping = { 'http://docs.pylonsproject.org/projects/pyramid_tm/en/latest/', None, ), - 'debugtoolbar': ( - 'http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest/', None), 'zcomponent': ('http://docs.zope.org/zope.component', None), 'webtest': ('http://webtest.pythonpaste.org/en/latest', None), 'webob': ('http://docs.webob.org/en/latest', None), diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index 28fefb49c..4229c1f39 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -581,8 +581,7 @@ you want to disable this toolbar, no need to change code: you can remove it from ``pyramid.includes`` in the relevant ``.ini`` configuration file. -.. seealso:: See Also: `pyramid_debugtoolbar - `_ +.. seealso:: See Also: :ref:`pyramid_debugtoolbar ` Unit Tests and ``nose`` ======================= diff --git a/docs/quick_tour/awesome/CHANGES.txt b/docs/quick_tour/awesome/CHANGES.txt new file mode 100644 index 000000000..ffa255da8 --- /dev/null +++ b/docs/quick_tour/awesome/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version diff --git a/docs/quick_tour/awesome/MANIFEST.in b/docs/quick_tour/awesome/MANIFEST.in new file mode 100644 index 000000000..e78395da8 --- /dev/null +++ b/docs/quick_tour/awesome/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include awesome *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/quick_tour/awesome/README.txt b/docs/quick_tour/awesome/README.txt new file mode 100644 index 000000000..f695286d9 --- /dev/null +++ b/docs/quick_tour/awesome/README.txt @@ -0,0 +1,4 @@ +awesome README + + + diff --git a/docs/quick_tour/awesome/awesome/__init__.py b/docs/quick_tour/awesome/awesome/__init__.py new file mode 100644 index 000000000..408033997 --- /dev/null +++ b/docs/quick_tour/awesome/awesome/__init__.py @@ -0,0 +1,23 @@ +from pyramid.config import Configurator +from pyramid_jinja2 import renderer_factory +from awesome.models import get_root + +def main(global_config, **settings): + """ This function returns a WSGI application. + + It is usually called by the PasteDeploy framework during + ``paster serve``. + """ + settings = dict(settings) + settings.setdefault('jinja2.i18n.domain', 'awesome') + + config = Configurator(root_factory=get_root, settings=settings) + config.add_translation_dirs('locale/') + config.include('pyramid_jinja2') + + config.add_static_view('static', 'static') + config.add_view('awesome.views.my_view', + context='awesome.models.MyModel', + renderer="mytemplate.jinja2") + + return config.make_wsgi_app() diff --git a/docs/quick_tour/awesome/awesome/locale/awesome.pot b/docs/quick_tour/awesome/awesome/locale/awesome.pot new file mode 100644 index 000000000..9c9460cb2 --- /dev/null +++ b/docs/quick_tour/awesome/awesome/locale/awesome.pot @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "" diff --git a/docs/quick_tour/awesome/awesome/locale/de/LC_MESSAGES/awesome.mo b/docs/quick_tour/awesome/awesome/locale/de/LC_MESSAGES/awesome.mo new file mode 100644 index 000000000..40bf0c271 Binary files /dev/null and b/docs/quick_tour/awesome/awesome/locale/de/LC_MESSAGES/awesome.mo differ diff --git a/docs/quick_tour/awesome/awesome/locale/de/LC_MESSAGES/awesome.po b/docs/quick_tour/awesome/awesome/locale/de/LC_MESSAGES/awesome.po new file mode 100644 index 000000000..0df243dba --- /dev/null +++ b/docs/quick_tour/awesome/awesome/locale/de/LC_MESSAGES/awesome.po @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "Hallo!" diff --git a/docs/quick_tour/awesome/awesome/locale/fr/LC_MESSAGES/awesome.mo b/docs/quick_tour/awesome/awesome/locale/fr/LC_MESSAGES/awesome.mo new file mode 100644 index 000000000..4fc438bfe Binary files /dev/null and b/docs/quick_tour/awesome/awesome/locale/fr/LC_MESSAGES/awesome.mo differ diff --git a/docs/quick_tour/awesome/awesome/locale/fr/LC_MESSAGES/awesome.po b/docs/quick_tour/awesome/awesome/locale/fr/LC_MESSAGES/awesome.po new file mode 100644 index 000000000..dc0aae5d7 --- /dev/null +++ b/docs/quick_tour/awesome/awesome/locale/fr/LC_MESSAGES/awesome.po @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "Bonjour!" diff --git a/docs/quick_tour/awesome/awesome/models.py b/docs/quick_tour/awesome/awesome/models.py new file mode 100644 index 000000000..edd361c9c --- /dev/null +++ b/docs/quick_tour/awesome/awesome/models.py @@ -0,0 +1,8 @@ +class MyModel(object): + pass + +root = MyModel() + + +def get_root(request): + return root diff --git a/docs/quick_tour/awesome/awesome/static/favicon.ico b/docs/quick_tour/awesome/awesome/static/favicon.ico new file mode 100644 index 000000000..71f837c9e Binary files /dev/null and b/docs/quick_tour/awesome/awesome/static/favicon.ico differ diff --git a/docs/quick_tour/awesome/awesome/static/logo.png b/docs/quick_tour/awesome/awesome/static/logo.png new file mode 100644 index 000000000..88f5d9865 Binary files /dev/null and b/docs/quick_tour/awesome/awesome/static/logo.png differ diff --git a/docs/quick_tour/awesome/awesome/static/pylons.css b/docs/quick_tour/awesome/awesome/static/pylons.css new file mode 100644 index 000000000..42e2e320e --- /dev/null +++ b/docs/quick_tour/awesome/awesome/static/pylons.css @@ -0,0 +1,73 @@ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ +vertical-align:baseline;background:transparent;} +body{line-height:1;} +ol,ul{list-style:none;} +blockquote,q{quotes:none;} +blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} +/* remember to define focus styles! */ +:focus{outline:0;} +/* remember to highlight inserts somehow! */ +ins{text-decoration:none;} +del{text-decoration:line-through;} +/* tables still need 'cellspacing="0"' in the markup */ +table{border-collapse:collapse;border-spacing:0;} +/* restyling */ +sub{vertical-align:sub;font-size:smaller;line-height:normal;} +sup{vertical-align:super;font-size:smaller;line-height:normal;} +/* lists */ +ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} +ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} +li{display:list-item;} +/* nested lists have no top/bottom margins */ +ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} +/* 2 deep unordered lists use a circle */ +ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} +/* 3 deep (or more) unordered lists use a square */ +ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} +.hidden{display:none;} +p{line-height:1.5em;} +h1{font-size:1.75em;/* 28px */ +line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;/* 24px */ +line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;/* 20px */ +line-height:1.7em;font-family:helvetica,verdana;} +h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} +html,body{width:100%;height:100%;} +body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} +a{color:#1b61d6;text-decoration:none;} +a:hover{color:#e88f00;text-decoration:underline;} +body h1, +body h2, +body h3, +body h4, +body h5, +body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} +#wrap {min-height: 100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} +#header{background-color:#e88f00;top:0;font-size:14px;} +#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} +.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +.wrapper{width:100%} +#top,#bottom{width:100%;} +#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} +#bottom{color:#222;background-color:#ffffff;overflow:auto;padding-bottom:80px;} +.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} +.top{padding-top:100px;} +.app-welcome{margin-top:25px;} +.app-name{color:#000000;font-weight:bold;} +.bottom{padding-top:50px;} +#left{width:325px;float:left;padding-right:25px;} +#right{width:325px;float:right;padding-left:25px;} +.align-left{text-align:left;} +.align-right{text-align:right;} +.align-center{text-align:center;} +ul.links{margin:0;padding:0;} +ul.links li{list-style-type:none;font-size:14px;} +form{border-style:none;} +fieldset{border-style:none;} +input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} +input[type=text]{} +input[type=submit]{background-color:#ddd;font-weight:bold;} +/*Opera Fix*/ +body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/quick_tour/awesome/awesome/templates/mytemplate.jinja2 b/docs/quick_tour/awesome/awesome/templates/mytemplate.jinja2 new file mode 100644 index 000000000..8bf676041 --- /dev/null +++ b/docs/quick_tour/awesome/awesome/templates/mytemplate.jinja2 @@ -0,0 +1,87 @@ + + + + The Pyramid Web Framework + + + + + + + + + + +
+ +
+
+ Logo +

+ Welcome to {{project}}, an application generated by
+ the Pyramid web framework. +

+
+
+
+
+

{% trans %}Hello!{% endtrans %}

+

Request performed with {{ request.locale_name }} locale.

+
+
+
+

Search Pyramid documentation

+
+ + +
+
+ +
+
+
+ + + diff --git a/docs/quick_tour/awesome/awesome/tests.py b/docs/quick_tour/awesome/awesome/tests.py new file mode 100644 index 000000000..ac222e25b --- /dev/null +++ b/docs/quick_tour/awesome/awesome/tests.py @@ -0,0 +1,21 @@ +import unittest +from pyramid import testing +from pyramid.i18n import TranslationStringFactory + +_ = TranslationStringFactory('awesome') + + +class ViewTests(unittest.TestCase): + + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from awesome.views import my_view + request = testing.DummyRequest() + response = my_view(request) + self.assertEqual(response['project'], 'awesome') + diff --git a/docs/quick_tour/awesome/awesome/views.py b/docs/quick_tour/awesome/awesome/views.py new file mode 100644 index 000000000..67b282f87 --- /dev/null +++ b/docs/quick_tour/awesome/awesome/views.py @@ -0,0 +1,6 @@ +from pyramid.i18n import TranslationStringFactory + +_ = TranslationStringFactory('awesome') + +def my_view(request): + return {'project':'awesome'} diff --git a/docs/quick_tour/awesome/development.ini b/docs/quick_tour/awesome/development.ini new file mode 100644 index 000000000..a473d32f1 --- /dev/null +++ b/docs/quick_tour/awesome/development.ini @@ -0,0 +1,49 @@ +[app:awesome] +use = egg:awesome +reload_templates = true +debug_authorization = false +debug_notfound = false +debug_routematch = false +debug_templates = true +default_locale_name = en +jinja2.directories = awesome:templates + +[pipeline:main] +pipeline = + awesome + +[server:main] +use = egg:pyramid#wsgiref +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, awesome + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_awesome] +level = DEBUG +handlers = +qualname = awesome + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/quick_tour/awesome/message-extraction.ini b/docs/quick_tour/awesome/message-extraction.ini new file mode 100644 index 000000000..0c3d54bc1 --- /dev/null +++ b/docs/quick_tour/awesome/message-extraction.ini @@ -0,0 +1,3 @@ +[python: **.py] +[jinja2: **.jinja2] +encoding = utf-8 diff --git a/docs/quick_tour/awesome/setup.cfg b/docs/quick_tour/awesome/setup.cfg new file mode 100644 index 000000000..b1cd90d2c --- /dev/null +++ b/docs/quick_tour/awesome/setup.cfg @@ -0,0 +1,28 @@ +[nosetests] +match = ^test +nocapture = 1 +cover-package = awesome +with-coverage = 1 +cover-erase = 1 + +[compile_catalog] +directory = awesome/locale +domain = awesome +statistics = true + +[extract_messages] +add_comments = TRANSLATORS: +output_file = awesome/locale/awesome.pot +width = 80 +mapping_file = message-extraction.ini + +[init_catalog] +domain = awesome +input_file = awesome/locale/awesome.pot +output_dir = awesome/locale + +[update_catalog] +domain = awesome +input_file = awesome/locale/awesome.pot +output_dir = awesome/locale +previous = true diff --git a/docs/quick_tour/awesome/setup.py b/docs/quick_tour/awesome/setup.py new file mode 100644 index 000000000..32d666317 --- /dev/null +++ b/docs/quick_tour/awesome/setup.py @@ -0,0 +1,36 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +README = open(os.path.join(here, 'README.txt')).read() +CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + +requires=['pyramid>=1.0.2', 'pyramid_jinja2'] + +setup(name='awesome', + version='0.0', + description='awesome', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pylons", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + tests_require=requires, + test_suite="awesome", + entry_points = """\ + [paste.app_factory] + main = awesome:main + """, + paster_plugins=['pyramid'], + ) diff --git a/docs/quick_tour/hello_world/app.py b/docs/quick_tour/hello_world/app.py new file mode 100644 index 000000000..df5a6cf18 --- /dev/null +++ b/docs/quick_tour/hello_world/app.py @@ -0,0 +1,16 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response + + +def hello_world(request): + return Response('

Hello World!

') + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/') + config.add_view(hello_world, route_name='hello') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/jinja2/app.py b/docs/quick_tour/jinja2/app.py new file mode 100644 index 000000000..83af219db --- /dev/null +++ b/docs/quick_tour/jinja2/app.py @@ -0,0 +1,11 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/howdy/{name}') + config.include('pyramid_jinja2') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/jinja2/hello_world.jinja2 b/docs/quick_tour/jinja2/hello_world.jinja2 new file mode 100644 index 000000000..e177744b5 --- /dev/null +++ b/docs/quick_tour/jinja2/hello_world.jinja2 @@ -0,0 +1,8 @@ + + + Hello World + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/quick_tour/jinja2/views.py b/docs/quick_tour/jinja2/views.py new file mode 100644 index 000000000..916cdc720 --- /dev/null +++ b/docs/quick_tour/jinja2/views.py @@ -0,0 +1,8 @@ +from pyramid.view import view_config + + +# Start View 1 +@view_config(route_name='hello', renderer='hello_world.jinja2') +# End View 1 +def hello_world(request): + return dict(name=request.matchdict['name']) diff --git a/docs/quick_tour/json/app.py b/docs/quick_tour/json/app.py new file mode 100644 index 000000000..950cb478f --- /dev/null +++ b/docs/quick_tour/json/app.py @@ -0,0 +1,15 @@ +from wsgiref.simple_server import make_server + +from pyramid.config import Configurator + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/howdy/{name}') + config.add_route('hello_json', 'hello.json') + config.add_static_view(name='static', path='static') + config.include('pyramid_jinja2') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/json/hello_world.jinja2 b/docs/quick_tour/json/hello_world.jinja2 new file mode 100644 index 000000000..f6862e618 --- /dev/null +++ b/docs/quick_tour/json/hello_world.jinja2 @@ -0,0 +1,10 @@ + + + + Quick Glance + + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/quick_tour/json/hello_world.pt b/docs/quick_tour/json/hello_world.pt new file mode 100644 index 000000000..711054aa9 --- /dev/null +++ b/docs/quick_tour/json/hello_world.pt @@ -0,0 +1,17 @@ + + + + Quick Glance + + + + + + + + +

Hello ${name}!

+ + \ No newline at end of file diff --git a/docs/quick_tour/json/views.py b/docs/quick_tour/json/views.py new file mode 100644 index 000000000..583e220c7 --- /dev/null +++ b/docs/quick_tour/json/views.py @@ -0,0 +1,13 @@ +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) + + +# Start View 1 +@view_config(route_name='hello_json', renderer='json') +def hello_json(request): + return [1, 2, 3] + # End View 1 \ No newline at end of file diff --git a/docs/quick_tour/package/CHANGES.txt b/docs/quick_tour/package/CHANGES.txt new file mode 100644 index 000000000..ffa255da8 --- /dev/null +++ b/docs/quick_tour/package/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version diff --git a/docs/quick_tour/package/MANIFEST.in b/docs/quick_tour/package/MANIFEST.in new file mode 100644 index 000000000..18fbd855c --- /dev/null +++ b/docs/quick_tour/package/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include hello_world *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/quick_tour/package/README.txt b/docs/quick_tour/package/README.txt new file mode 100644 index 000000000..63aaf6fbd --- /dev/null +++ b/docs/quick_tour/package/README.txt @@ -0,0 +1,4 @@ +hello_world README + + + diff --git a/docs/quick_tour/package/development.ini b/docs/quick_tour/package/development.ini new file mode 100644 index 000000000..a751ff903 --- /dev/null +++ b/docs/quick_tour/package/development.ini @@ -0,0 +1,57 @@ +# Start Includes +[app:hello_world] +pyramid.includes = pyramid_debugtoolbar +# End Includes +use = egg:hello_world +reload_templates = true +debug_authorization = false +debug_notfound = false +debug_routematch = false +debug_templates = true +default_locale_name = en +jinja2.directories = hello_world:templates + + + +[pipeline:main] +pipeline = + hello_world + +[server:main] +use = egg:pyramid#wsgiref +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +# Start Sphinx Include +[loggers] +keys = root, hello_world + +[logger_hello_world] +level = DEBUG +handlers = +qualname = hello_world +# End Sphinx Include + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/quick_tour/package/hello_world/__init__.py b/docs/quick_tour/package/hello_world/__init__.py new file mode 100644 index 000000000..6e66bf40a --- /dev/null +++ b/docs/quick_tour/package/hello_world/__init__.py @@ -0,0 +1,34 @@ +from pyramid.config import Configurator +from pyramid_jinja2 import renderer_factory +# Start Sphinx Include 1 +from pyramid.session import UnencryptedCookieSessionFactoryConfig +# End Sphinx Include 1 + +from hello_world.models import get_root + +def main(global_config, **settings): + """ This function returns a WSGI application. + + It is usually called by the PasteDeploy framework during + ``paster serve``. + """ + settings = dict(settings) + settings.setdefault('jinja2.i18n.domain', 'hello_world') + + # Start Sphinx Include 2 + my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet') + config = Configurator(root_factory=get_root, settings=settings, + session_factory=my_session_factory) + # End Sphinx Include 2 + config.add_translation_dirs('locale/') + # Start Include + config.include('pyramid_jinja2') + # End Include + + + config.add_static_view('static', 'static') + config.add_view('hello_world.views.my_view', + context='hello_world.models.MyModel', + renderer="mytemplate.jinja2") + + return config.make_wsgi_app() diff --git a/docs/quick_tour/package/hello_world/init.py b/docs/quick_tour/package/hello_world/init.py new file mode 100644 index 000000000..9d7ec43d8 --- /dev/null +++ b/docs/quick_tour/package/hello_world/init.py @@ -0,0 +1,34 @@ +from pyramid.config import Configurator +from pyramid_jinja2 import renderer_factory +# Start Sphinx 1 +from pyramid.session import UnencryptedCookieSessionFactoryConfig +# End Sphinx 1 + +from hello_world.models import get_root + +def main(global_config, **settings): + """ This function returns a WSGI application. + + It is usually called by the PasteDeploy framework during + ``paster serve``. + """ + settings = dict(settings) + settings.setdefault('jinja2.i18n.domain', 'hello_world') + + config = Configurator(root_factory=get_root, settings=settings) + config.add_translation_dirs('locale/') + # Start Include + config.include('pyramid_jinja2') + # End Include + + # Start Sphinx Include 2 + my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet') + config = Configurator(session_factory=my_session_factory) + # End Sphinx Include 2 + + config.add_static_view('static', 'static') + config.add_view('hello_world.views.my_view', + context='hello_world.models.MyModel', + renderer="mytemplate.jinja2") + + return config.make_wsgi_app() diff --git a/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo b/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo new file mode 100644 index 000000000..40bf0c271 Binary files /dev/null and b/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.mo differ diff --git a/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.po b/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.po new file mode 100644 index 000000000..0df243dba --- /dev/null +++ b/docs/quick_tour/package/hello_world/locale/de/LC_MESSAGES/hello_world.po @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "Hallo!" diff --git a/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo b/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo new file mode 100644 index 000000000..4fc438bfe Binary files /dev/null and b/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.mo differ diff --git a/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po b/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po new file mode 100644 index 000000000..dc0aae5d7 --- /dev/null +++ b/docs/quick_tour/package/hello_world/locale/fr/LC_MESSAGES/hello_world.po @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "Bonjour!" diff --git a/docs/quick_tour/package/hello_world/locale/hello_world.pot b/docs/quick_tour/package/hello_world/locale/hello_world.pot new file mode 100644 index 000000000..9c9460cb2 --- /dev/null +++ b/docs/quick_tour/package/hello_world/locale/hello_world.pot @@ -0,0 +1,21 @@ +# Translations template for PROJECT. +# Copyright (C) 2011 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2011. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2011-05-12 09:14-0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.6\n" + +msgid "Hello!" +msgstr "" diff --git a/docs/quick_tour/package/hello_world/models.py b/docs/quick_tour/package/hello_world/models.py new file mode 100644 index 000000000..edd361c9c --- /dev/null +++ b/docs/quick_tour/package/hello_world/models.py @@ -0,0 +1,8 @@ +class MyModel(object): + pass + +root = MyModel() + + +def get_root(request): + return root diff --git a/docs/quick_tour/package/hello_world/static/favicon.ico b/docs/quick_tour/package/hello_world/static/favicon.ico new file mode 100644 index 000000000..71f837c9e Binary files /dev/null and b/docs/quick_tour/package/hello_world/static/favicon.ico differ diff --git a/docs/quick_tour/package/hello_world/static/logo.png b/docs/quick_tour/package/hello_world/static/logo.png new file mode 100644 index 000000000..88f5d9865 Binary files /dev/null and b/docs/quick_tour/package/hello_world/static/logo.png differ diff --git a/docs/quick_tour/package/hello_world/static/pylons.css b/docs/quick_tour/package/hello_world/static/pylons.css new file mode 100644 index 000000000..42e2e320e --- /dev/null +++ b/docs/quick_tour/package/hello_world/static/pylons.css @@ -0,0 +1,73 @@ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ +vertical-align:baseline;background:transparent;} +body{line-height:1;} +ol,ul{list-style:none;} +blockquote,q{quotes:none;} +blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} +/* remember to define focus styles! */ +:focus{outline:0;} +/* remember to highlight inserts somehow! */ +ins{text-decoration:none;} +del{text-decoration:line-through;} +/* tables still need 'cellspacing="0"' in the markup */ +table{border-collapse:collapse;border-spacing:0;} +/* restyling */ +sub{vertical-align:sub;font-size:smaller;line-height:normal;} +sup{vertical-align:super;font-size:smaller;line-height:normal;} +/* lists */ +ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} +ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} +li{display:list-item;} +/* nested lists have no top/bottom margins */ +ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} +/* 2 deep unordered lists use a circle */ +ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} +/* 3 deep (or more) unordered lists use a square */ +ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} +.hidden{display:none;} +p{line-height:1.5em;} +h1{font-size:1.75em;/* 28px */ +line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;/* 24px */ +line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;/* 20px */ +line-height:1.7em;font-family:helvetica,verdana;} +h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} +html,body{width:100%;height:100%;} +body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} +a{color:#1b61d6;text-decoration:none;} +a:hover{color:#e88f00;text-decoration:underline;} +body h1, +body h2, +body h3, +body h4, +body h5, +body h6{font-family:"Nobile","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#144fb2;font-style:normal;} +#wrap {min-height: 100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;} +#header{background-color:#e88f00;top:0;font-size:14px;} +#footer{background-color:#000000;bottom:0;position: relative;margin-top:-40px;clear:both;} +.header,.footer{width:700px;margin-right:auto;margin-left:auto;} +.wrapper{width:100%} +#top,#bottom{width:100%;} +#top{color:#888;background-color:#eee;height:300px;border-bottom:2px solid #ddd;} +#bottom{color:#222;background-color:#ffffff;overflow:auto;padding-bottom:80px;} +.top,.bottom{width:700px;margin-right:auto;margin-left:auto;} +.top{padding-top:100px;} +.app-welcome{margin-top:25px;} +.app-name{color:#000000;font-weight:bold;} +.bottom{padding-top:50px;} +#left{width:325px;float:left;padding-right:25px;} +#right{width:325px;float:right;padding-left:25px;} +.align-left{text-align:left;} +.align-right{text-align:right;} +.align-center{text-align:center;} +ul.links{margin:0;padding:0;} +ul.links li{list-style-type:none;font-size:14px;} +form{border-style:none;} +fieldset{border-style:none;} +input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} +input[type=text]{} +input[type=submit]{background-color:#ddd;font-weight:bold;} +/*Opera Fix*/ +body:before {content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/docs/quick_tour/package/hello_world/templates/mytemplate.jinja2 b/docs/quick_tour/package/hello_world/templates/mytemplate.jinja2 new file mode 100644 index 000000000..25a28ed7a --- /dev/null +++ b/docs/quick_tour/package/hello_world/templates/mytemplate.jinja2 @@ -0,0 +1,90 @@ + + + + The Pyramid Web Framework + + + + + + + + + + +
+ +
+
+ Logo +

+ Welcome to {{project}}, an application generated by
+ the Pyramid Web Framework. +

+
+
+
+
+

{% trans %}Hello!{% endtrans %}

+ +

Counter: {{ request.session.counter }}

+ +

Request performed with {{ request.locale_name }} locale.

+
+
+
+

Search Pyramid documentation

+
+ + +
+
+ +
+
+
+ + + diff --git a/docs/quick_tour/package/hello_world/tests.py b/docs/quick_tour/package/hello_world/tests.py new file mode 100644 index 000000000..ccec14f70 --- /dev/null +++ b/docs/quick_tour/package/hello_world/tests.py @@ -0,0 +1,20 @@ +import unittest +from pyramid import testing +from pyramid.i18n import TranslationStringFactory + +_ = TranslationStringFactory('hello_world') + + +class ViewTests(unittest.TestCase): + + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from hello_world.views import my_view + request = testing.DummyRequest() + response = my_view(request) + self.assertEqual(response['project'], 'hello_world') diff --git a/docs/quick_tour/package/hello_world/views.py b/docs/quick_tour/package/hello_world/views.py new file mode 100644 index 000000000..109c260ad --- /dev/null +++ b/docs/quick_tour/package/hello_world/views.py @@ -0,0 +1,22 @@ +# Start Logging 1 +import logging +log = logging.getLogger(__name__) +# End Logging 1 + +from pyramid.i18n import TranslationStringFactory + +_ = TranslationStringFactory('hello_world') + + +def my_view(request): + # Start Logging 2 + log.debug('Some Message') + # End Logging 2 + # Start Sphinx Include 1 + session = request.session + if 'counter' in session: + session['counter'] += 1 + else: + session['counter'] = 0 + # End Sphinx Include 1 + return {'project': 'hello_world'} diff --git a/docs/quick_tour/package/message-extraction.ini b/docs/quick_tour/package/message-extraction.ini new file mode 100644 index 000000000..0c3d54bc1 --- /dev/null +++ b/docs/quick_tour/package/message-extraction.ini @@ -0,0 +1,3 @@ +[python: **.py] +[jinja2: **.jinja2] +encoding = utf-8 diff --git a/docs/quick_tour/package/setup.cfg b/docs/quick_tour/package/setup.cfg new file mode 100644 index 000000000..186e796fc --- /dev/null +++ b/docs/quick_tour/package/setup.cfg @@ -0,0 +1,28 @@ +[nosetests] +match = ^test +nocapture = 1 +cover-package = hello_world +with-coverage = 1 +cover-erase = 1 + +[compile_catalog] +directory = hello_world/locale +domain = hello_world +statistics = true + +[extract_messages] +add_comments = TRANSLATORS: +output_file = hello_world/locale/hello_world.pot +width = 80 +mapping_file = message-extraction.ini + +[init_catalog] +domain = hello_world +input_file = hello_world/locale/hello_world.pot +output_dir = hello_world/locale + +[update_catalog] +domain = hello_world +input_file = hello_world/locale/hello_world.pot +output_dir = hello_world/locale +previous = true diff --git a/docs/quick_tour/package/setup.py b/docs/quick_tour/package/setup.py new file mode 100644 index 000000000..f118ed5fb --- /dev/null +++ b/docs/quick_tour/package/setup.py @@ -0,0 +1,41 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +README = open(os.path.join(here, 'README.txt')).read() +CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + +# Start Requires +requires = ['pyramid>=1.0.2', 'pyramid_jinja2', 'pyramid_debugtoolbar'] +# End Requires + +setup(name='hello_world', + version='0.0', + description='hello_world', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pylons", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + tests_require=requires, + test_suite="hello_world", + entry_points="""\ + [paste.app_factory] + main = hello_world:main + """, + paster_plugins=['pyramid'], + extras_require={ + 'testing': ['nose', ], + } +) \ No newline at end of file diff --git a/docs/quick_tour/requests/app.py b/docs/quick_tour/requests/app.py new file mode 100644 index 000000000..7ac81eb50 --- /dev/null +++ b/docs/quick_tour/requests/app.py @@ -0,0 +1,24 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator +from pyramid.response import Response + + +def hello_world(request): + # Some parameters from a request such as /?name=lisa + url = request.url + name = request.params.get('name', 'No Name Provided') + + body = 'URL %s with name: %s' % (url, name) + return Response( + content_type="text/plain", + body=body + ) + + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/') + config.add_view(hello_world, route_name='hello') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/routing/app.py b/docs/quick_tour/routing/app.py new file mode 100644 index 000000000..04a8a6344 --- /dev/null +++ b/docs/quick_tour/routing/app.py @@ -0,0 +1,12 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator + +if __name__ == '__main__': + config = Configurator() + # Start Route 1 + config.add_route('hello', '/howdy/{first}/{last}') + # End Route 1 + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/routing/views.py b/docs/quick_tour/routing/views.py new file mode 100644 index 000000000..8cb8d3780 --- /dev/null +++ b/docs/quick_tour/routing/views.py @@ -0,0 +1,10 @@ +from pyramid.response import Response +from pyramid.view import view_config + + +# Start Route 1 +@view_config(route_name='hello') +def hello_world(request): + body = '

Hi %(first)s %(last)s!

' % request.matchdict + return Response(body) + # End Route 1 \ No newline at end of file diff --git a/docs/quick_tour/sqla_demo/CHANGES.txt b/docs/quick_tour/sqla_demo/CHANGES.txt new file mode 100644 index 000000000..35a34f332 --- /dev/null +++ b/docs/quick_tour/sqla_demo/CHANGES.txt @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version diff --git a/docs/quick_tour/sqla_demo/MANIFEST.in b/docs/quick_tour/sqla_demo/MANIFEST.in new file mode 100644 index 000000000..a432577e9 --- /dev/null +++ b/docs/quick_tour/sqla_demo/MANIFEST.in @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include sqla_demo *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/quick_tour/sqla_demo/README.txt b/docs/quick_tour/sqla_demo/README.txt new file mode 100644 index 000000000..f35d3aec5 --- /dev/null +++ b/docs/quick_tour/sqla_demo/README.txt @@ -0,0 +1,14 @@ +sqla_demo README +================== + +Getting Started +--------------- + +- cd + +- $venv/bin/python setup.py develop + +- $venv/bin/initialize_sqla_demo_db development.ini + +- $venv/bin/pserve development.ini + diff --git a/docs/quick_tour/sqla_demo/development.ini b/docs/quick_tour/sqla_demo/development.ini new file mode 100644 index 000000000..174468abf --- /dev/null +++ b/docs/quick_tour/sqla_demo/development.ini @@ -0,0 +1,71 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:sqla_demo + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm + +sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite + +# By default, the toolbar only appears for clients from IP addresses +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + +[server:main] +use = egg:waitress#main +host = 0.0.0.0 +port = 6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, sqla_demo, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_sqla_demo] +level = DEBUG +handlers = +qualname = sqla_demo + +[logger_sqlalchemy] +level = INFO +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/sqla_demo/production.ini b/docs/quick_tour/sqla_demo/production.ini new file mode 100644 index 000000000..dc0ba304f --- /dev/null +++ b/docs/quick_tour/sqla_demo/production.ini @@ -0,0 +1,62 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + +[app:main] +use = egg:sqla_demo + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.default_locale_name = en +pyramid.includes = + pyramid_tm + +sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite + +[server:main] +use = egg:waitress#main +host = 0.0.0.0 +port = 6543 + +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### + +[loggers] +keys = root, sqla_demo, sqlalchemy + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_sqla_demo] +level = WARN +handlers = +qualname = sqla_demo + +[logger_sqlalchemy] +level = WARN +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s diff --git a/docs/quick_tour/sqla_demo/setup.cfg b/docs/quick_tour/sqla_demo/setup.cfg new file mode 100644 index 000000000..9f91cd122 --- /dev/null +++ b/docs/quick_tour/sqla_demo/setup.cfg @@ -0,0 +1,27 @@ +[nosetests] +match=^test +nocapture=1 +cover-package=sqla_demo +with-coverage=1 +cover-erase=1 + +[compile_catalog] +directory = sqla_demo/locale +domain = sqla_demo +statistics = true + +[extract_messages] +add_comments = TRANSLATORS: +output_file = sqla_demo/locale/sqla_demo.pot +width = 80 + +[init_catalog] +domain = sqla_demo +input_file = sqla_demo/locale/sqla_demo.pot +output_dir = sqla_demo/locale + +[update_catalog] +domain = sqla_demo +input_file = sqla_demo/locale/sqla_demo.pot +output_dir = sqla_demo/locale +previous = true diff --git a/docs/quick_tour/sqla_demo/setup.py b/docs/quick_tour/sqla_demo/setup.py new file mode 100644 index 000000000..ac2eed035 --- /dev/null +++ b/docs/quick_tour/sqla_demo/setup.py @@ -0,0 +1,44 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +README = open(os.path.join(here, 'README.txt')).read() +CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() + +requires = [ + 'pyramid', + 'SQLAlchemy', + 'transaction', + 'pyramid_tm', + 'pyramid_debugtoolbar', + 'zope.sqlalchemy', + 'waitress', + ] + +setup(name='sqla_demo', + version='0.0', + description='sqla_demo', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web wsgi bfg pylons pyramid', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + test_suite='sqla_demo', + install_requires=requires, + entry_points="""\ + [paste.app_factory] + main = sqla_demo:main + [console_scripts] + initialize_sqla_demo_db = sqla_demo.scripts.initializedb:main + """, + ) diff --git a/docs/quick_tour/sqla_demo/sqla_demo.sqlite b/docs/quick_tour/sqla_demo/sqla_demo.sqlite new file mode 100644 index 000000000..fa6adb104 Binary files /dev/null and b/docs/quick_tour/sqla_demo/sqla_demo.sqlite differ diff --git a/docs/quick_tour/sqla_demo/sqla_demo/__init__.py b/docs/quick_tour/sqla_demo/sqla_demo/__init__.py new file mode 100644 index 000000000..aac7c5e69 --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/__init__.py @@ -0,0 +1,20 @@ +from pyramid.config import Configurator +from sqlalchemy import engine_from_config + +from .models import ( + DBSession, + Base, + ) + + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.bind = engine + config = Configurator(settings=settings) + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('home', '/') + config.scan() + return config.make_wsgi_app() diff --git a/docs/quick_tour/sqla_demo/sqla_demo/models.py b/docs/quick_tour/sqla_demo/sqla_demo/models.py new file mode 100644 index 000000000..3dfb40e58 --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/models.py @@ -0,0 +1,29 @@ +from sqlalchemy import ( + Column, + Integer, + Text, + ) + +from sqlalchemy.ext.declarative import declarative_base + +from sqlalchemy.orm import ( + scoped_session, + sessionmaker, + ) + +from zope.sqlalchemy import ZopeTransactionExtension + +DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) +Base = declarative_base() + +# Start Sphinx Include +class MyModel(Base): + __tablename__ = 'models' + id = Column(Integer, primary_key=True) + name = Column(Text, unique=True) + value = Column(Integer) + + def __init__(self, name, value): + self.name = name + self.value = value + # End Sphinx Include diff --git a/docs/quick_tour/sqla_demo/sqla_demo/scripts/__init__.py b/docs/quick_tour/sqla_demo/sqla_demo/scripts/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/scripts/__init__.py @@ -0,0 +1 @@ +# package diff --git a/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py b/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py new file mode 100644 index 000000000..66feb3008 --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py @@ -0,0 +1,37 @@ +import os +import sys +import transaction + +from sqlalchemy import engine_from_config + +from pyramid.paster import ( + get_appsettings, + setup_logging, + ) + +from ..models import ( + DBSession, + MyModel, + Base, + ) + + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s \n' + '(example: "%s development.ini")' % (cmd, cmd)) + sys.exit(1) + + +def main(argv=sys.argv): + if len(argv) != 2: + usage(argv) + config_uri = argv[1] + setup_logging(config_uri) + settings = get_appsettings(config_uri) + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.create_all(engine) + with transaction.manager: + model = MyModel(name='one', value=1) + DBSession.add(model) diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/favicon.ico b/docs/quick_tour/sqla_demo/sqla_demo/static/favicon.ico new file mode 100644 index 000000000..71f837c9e Binary files /dev/null and b/docs/quick_tour/sqla_demo/sqla_demo/static/favicon.ico differ diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/footerbg.png b/docs/quick_tour/sqla_demo/sqla_demo/static/footerbg.png new file mode 100644 index 000000000..1fbc873da Binary files /dev/null and b/docs/quick_tour/sqla_demo/sqla_demo/static/footerbg.png differ diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/headerbg.png b/docs/quick_tour/sqla_demo/sqla_demo/static/headerbg.png new file mode 100644 index 000000000..0596f2020 Binary files /dev/null and b/docs/quick_tour/sqla_demo/sqla_demo/static/headerbg.png differ diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css b/docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/middlebg.png b/docs/quick_tour/sqla_demo/sqla_demo/static/middlebg.png new file mode 100644 index 000000000..2369cfb7d Binary files /dev/null and b/docs/quick_tour/sqla_demo/sqla_demo/static/middlebg.png differ diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/pylons.css b/docs/quick_tour/sqla_demo/sqla_demo/static/pylons.css new file mode 100644 index 000000000..4b1c017cd --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/static/pylons.css @@ -0,0 +1,372 @@ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td +{ + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; /* 16px */ + vertical-align: baseline; + background: transparent; +} + +body +{ + line-height: 1; +} + +ol, ul +{ + list-style: none; +} + +blockquote, q +{ + quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after +{ + content: ''; + content: none; +} + +:focus +{ + outline: 0; +} + +ins +{ + text-decoration: none; +} + +del +{ + text-decoration: line-through; +} + +table +{ + border-collapse: collapse; + border-spacing: 0; +} + +sub +{ + vertical-align: sub; + font-size: smaller; + line-height: normal; +} + +sup +{ + vertical-align: super; + font-size: smaller; + line-height: normal; +} + +ul, menu, dir +{ + display: block; + list-style-type: disc; + margin: 1em 0; + padding-left: 40px; +} + +ol +{ + display: block; + list-style-type: decimal-leading-zero; + margin: 1em 0; + padding-left: 40px; +} + +li +{ + display: list-item; +} + +ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl +{ + margin-top: 0; + margin-bottom: 0; +} + +ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir +{ + list-style-type: circle; +} + +ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir +{ + list-style-type: square; +} + +.hidden +{ + display: none; +} + +p +{ + line-height: 1.5em; +} + +h1 +{ + font-size: 1.75em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h2 +{ + font-size: 1.5em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h3 +{ + font-size: 1.25em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h4 +{ + font-size: 1em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +html, body +{ + width: 100%; + height: 100%; +} + +body +{ + margin: 0; + padding: 0; + background-color: #fff; + position: relative; + font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; +} + +a +{ + color: #1b61d6; + text-decoration: none; +} + +a:hover +{ + color: #e88f00; + text-decoration: underline; +} + +body h1, body h2, body h3, body h4, body h5, body h6 +{ + font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; + font-weight: 400; + color: #373839; + font-style: normal; +} + +#wrap +{ + min-height: 100%; +} + +#header, #footer +{ + width: 100%; + color: #fff; + height: 40px; + position: absolute; + text-align: center; + line-height: 40px; + overflow: hidden; + font-size: 12px; + vertical-align: middle; +} + +#header +{ + background: #000; + top: 0; + font-size: 14px; +} + +#footer +{ + bottom: 0; + background: #000 url(footerbg.png) repeat-x 0 top; + position: relative; + margin-top: -40px; + clear: both; +} + +.header, .footer +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.wrapper +{ + width: 100%; +} + +#top, #top-small, #bottom +{ + width: 100%; +} + +#top +{ + color: #000; + height: 230px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#top-small +{ + color: #000; + height: 60px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#bottom +{ + color: #222; + background-color: #fff; +} + +.top, .top-small, .middle, .bottom +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.top +{ + padding-top: 40px; +} + +.top-small +{ + padding-top: 10px; +} + +#middle +{ + width: 100%; + height: 100px; + background: url(middlebg.png) repeat-x; + border-top: 2px solid #fff; + border-bottom: 2px solid #b2b2b2; +} + +.app-welcome +{ + margin-top: 25px; +} + +.app-name +{ + color: #000; + font-weight: 700; +} + +.bottom +{ + padding-top: 50px; +} + +#left +{ + width: 350px; + float: left; + padding-right: 25px; +} + +#right +{ + width: 350px; + float: right; + padding-left: 25px; +} + +.align-left +{ + text-align: left; +} + +.align-right +{ + text-align: right; +} + +.align-center +{ + text-align: center; +} + +ul.links +{ + margin: 0; + padding: 0; +} + +ul.links li +{ + list-style-type: none; + font-size: 14px; +} + +form +{ + border-style: none; +} + +fieldset +{ + border-style: none; +} + +input +{ + color: #222; + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 12px; + line-height: 16px; +} + +input[type=text], input[type=password] +{ + width: 205px; +} + +input[type=submit] +{ + background-color: #ddd; + font-weight: 700; +} + +/*Opera Fix*/ +body:before +{ + content: ""; + height: 100%; + float: left; + width: 0; + margin-top: -32767px; +} diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-small.png b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-small.png new file mode 100644 index 000000000..a5bc0ade7 Binary files /dev/null and b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-small.png differ diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.png b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.png new file mode 100644 index 000000000..347e05549 Binary files /dev/null and b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.png differ diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/transparent.gif b/docs/quick_tour/sqla_demo/sqla_demo/static/transparent.gif new file mode 100644 index 000000000..0341802e5 Binary files /dev/null and b/docs/quick_tour/sqla_demo/sqla_demo/static/transparent.gif differ diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.pt b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.pt new file mode 100644 index 000000000..321c0f5fb --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.pt @@ -0,0 +1,76 @@ + + + + The Pyramid Web Framework + + + + + + + + + + +
+
+
+
pyramid
+
+
+
+
+

+ Welcome to ${project}, an application generated by
+ the Pyramid web framework. +

+
+
+
+
+
+

Search documentation

+
+ + +
+
+ +
+
+
+ + + diff --git a/docs/quick_tour/sqla_demo/sqla_demo/tests.py b/docs/quick_tour/sqla_demo/sqla_demo/tests.py new file mode 100644 index 000000000..6fef6d695 --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/tests.py @@ -0,0 +1,33 @@ +import unittest +import transaction + +from pyramid import testing + +from .models import DBSession + + +class TestMyView(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + from sqlalchemy import create_engine + engine = create_engine('sqlite://') + from .models import ( + Base, + MyModel, + ) + DBSession.configure(bind=engine) + Base.metadata.create_all(engine) + with transaction.manager: + model = MyModel(name='one', value=55) + DBSession.add(model) + + def tearDown(self): + DBSession.remove() + testing.tearDown() + + def test_it(self): + from .views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['one'].name, 'one') + self.assertEqual(info['project'], 'sqla_demo') diff --git a/docs/quick_tour/sqla_demo/sqla_demo/views.py b/docs/quick_tour/sqla_demo/sqla_demo/views.py new file mode 100644 index 000000000..768a7e42e --- /dev/null +++ b/docs/quick_tour/sqla_demo/sqla_demo/views.py @@ -0,0 +1,37 @@ +from pyramid.response import Response +from pyramid.view import view_config + +from sqlalchemy.exc import DBAPIError + +from .models import ( + DBSession, + MyModel, + ) + + +@view_config(route_name='home', renderer='templates/mytemplate.pt') +def my_view(request): + try: + # Start Sphinx Include + one = DBSession.query(MyModel).filter(MyModel.name == 'one').first() + # End Sphinx Include + except DBAPIError: + return Response(conn_err_msg, content_type='text/plain', status_int=500) + return {'one': one, 'project': 'sqla_demo'} + +conn_err_msg = """\ +Pyramid is having a problem using your SQL database. The problem +might be caused by one of the following things: + +1. You may need to run the "initialize_sqla_demo_db" script + to initialize your database tables. Check your virtual + environment's "bin" directory for this script and try to run it. + +2. Your database server may not be running. Check that the + database server referred to by the "sqlalchemy.url" setting in + your "development.ini" file is running. + +After you fix the problem, please restart the Pyramid application to +try it again. +""" + diff --git a/docs/quick_tour/static_assets/app.py b/docs/quick_tour/static_assets/app.py new file mode 100644 index 000000000..9c808972f --- /dev/null +++ b/docs/quick_tour/static_assets/app.py @@ -0,0 +1,14 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator + +if __name__ == '__main__': + config = Configurator() + config.add_route('hello', '/howdy/{name}') + # Start Static 1 + config.add_static_view(name='static', path='static') + # End Static 1 + config.include('pyramid_jinja2') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/static_assets/hello_world.jinja2 b/docs/quick_tour/static_assets/hello_world.jinja2 new file mode 100644 index 000000000..f6862e618 --- /dev/null +++ b/docs/quick_tour/static_assets/hello_world.jinja2 @@ -0,0 +1,10 @@ + + + + Quick Glance + + + +

Hello {{ name }}!

+ + \ No newline at end of file diff --git a/docs/quick_tour/static_assets/hello_world.pt b/docs/quick_tour/static_assets/hello_world.pt new file mode 100644 index 000000000..1797146eb --- /dev/null +++ b/docs/quick_tour/static_assets/hello_world.pt @@ -0,0 +1,16 @@ + + + Quick Glance + + + + + + + + +

Hello ${name}!

+ + \ No newline at end of file diff --git a/docs/quick_tour/static_assets/static/app.css b/docs/quick_tour/static_assets/static/app.css new file mode 100644 index 000000000..f8acf3164 --- /dev/null +++ b/docs/quick_tour/static_assets/static/app.css @@ -0,0 +1,4 @@ +body { + margin: 2em; + font-family: sans-serif; +} \ No newline at end of file diff --git a/docs/quick_tour/static_assets/views.py b/docs/quick_tour/static_assets/views.py new file mode 100644 index 000000000..90730ae32 --- /dev/null +++ b/docs/quick_tour/static_assets/views.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config + + +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) diff --git a/docs/quick_tour/templating/app.py b/docs/quick_tour/templating/app.py new file mode 100644 index 000000000..6d1a29f4e --- /dev/null +++ b/docs/quick_tour/templating/app.py @@ -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', '/howdy/{name}') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/templating/hello_world.pt b/docs/quick_tour/templating/hello_world.pt new file mode 100644 index 000000000..ae14f447d --- /dev/null +++ b/docs/quick_tour/templating/hello_world.pt @@ -0,0 +1,9 @@ + + + + Quick Glance + + +

Hello ${name}

+ + \ No newline at end of file diff --git a/docs/quick_tour/templating/views.py b/docs/quick_tour/templating/views.py new file mode 100644 index 000000000..6c7846efa --- /dev/null +++ b/docs/quick_tour/templating/views.py @@ -0,0 +1,8 @@ +from pyramid.view import view_config + + +# Start View 1 +@view_config(route_name='hello', renderer='hello_world.pt') +def hello_world(request): + return dict(name=request.matchdict['name']) + # End View 1 \ No newline at end of file diff --git a/docs/quick_tour/view_classes/app.py b/docs/quick_tour/view_classes/app.py new file mode 100644 index 000000000..468c8c29e --- /dev/null +++ b/docs/quick_tour/view_classes/app.py @@ -0,0 +1,13 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator + +if __name__ == '__main__': + config = Configurator() + # Start Routes 1 + config.add_route('hello', '/howdy/{name}') + # End Routes 1 + config.include('pyramid_jinja2') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/view_classes/delete.jinja2 b/docs/quick_tour/view_classes/delete.jinja2 new file mode 100644 index 000000000..ba45b7d16 --- /dev/null +++ b/docs/quick_tour/view_classes/delete.jinja2 @@ -0,0 +1,9 @@ + + + + Delete World + + +

Delete {{ view.name }}!

+ + \ No newline at end of file diff --git a/docs/quick_tour/view_classes/edit.jinja2 b/docs/quick_tour/view_classes/edit.jinja2 new file mode 100644 index 000000000..ce0eb5bd1 --- /dev/null +++ b/docs/quick_tour/view_classes/edit.jinja2 @@ -0,0 +1,9 @@ + + + + Edit World + + +

Edit {{ view.name }}!

+ + \ No newline at end of file diff --git a/docs/quick_tour/view_classes/hello.jinja2 b/docs/quick_tour/view_classes/hello.jinja2 new file mode 100644 index 000000000..3446b96ce --- /dev/null +++ b/docs/quick_tour/view_classes/hello.jinja2 @@ -0,0 +1,17 @@ + + + + Hello World + + +

Hello {{ view.name }}!

+ +
+ + + +
+ + + \ No newline at end of file diff --git a/docs/quick_tour/view_classes/views.py b/docs/quick_tour/view_classes/views.py new file mode 100644 index 000000000..62556142e --- /dev/null +++ b/docs/quick_tour/view_classes/views.py @@ -0,0 +1,32 @@ +from pyramid.view import ( + view_config, + view_defaults + ) + + +# Start View 1 +# One route, at /howdy/amy, so don't repeat on each @view_config +@view_defaults(route_name='hello') +class HelloWorldViews: + def __init__(self, request): + self.request = request + # Our templates can now say {{ view.name }} + self.name = request.matchdict['name'] + + # Retrieving /howdy/amy the first time + @view_config(renderer='hello.jinja2') + def hello_view(self): + return dict() + + # Posting to /howdy/amy via the "Edit" submit button + @view_config(request_param='form.edit', renderer='edit.jinja2') + def edit_view(self): + print('Edited') + return dict() + + # Posting to /howdy/amy via the "Delete" submit button + @view_config(request_param='form.delete', renderer='delete.jinja2') + def delete_view(self): + print('Deleted') + return dict() + # End View 1 \ No newline at end of file diff --git a/docs/quick_tour/views/app.py b/docs/quick_tour/views/app.py new file mode 100644 index 000000000..54dc9ed4b --- /dev/null +++ b/docs/quick_tour/views/app.py @@ -0,0 +1,13 @@ +from wsgiref.simple_server import make_server +from pyramid.config import Configurator + +if __name__ == '__main__': + config = Configurator() + config.add_route('home', '/') + config.add_route('hello', '/howdy') + config.add_route('redirect', '/goto') + config.add_route('exception', '/problem') + config.scan('views') + app = config.make_wsgi_app() + server = make_server('0.0.0.0', 6543, app) + server.serve_forever() \ No newline at end of file diff --git a/docs/quick_tour/views/views.py b/docs/quick_tour/views/views.py new file mode 100644 index 000000000..9dc795f14 --- /dev/null +++ b/docs/quick_tour/views/views.py @@ -0,0 +1,29 @@ +from pyramid.httpexceptions import HTTPFound +from pyramid.response import Response +from pyramid.view import view_config + + +# First view, available at http://localhost:6543/ +@view_config(route_name='home') +def home_view(request): + return Response('

Visit hello

') + + +# /howdy?name=alice which links to the next view +@view_config(route_name='hello') +def hello_view(request): + name = request.params.get('name', 'No Name') + body = '

Hi %s, this redirects

' + return Response(body % name) + + +# /goto which issues HTTP redirect to the last view +@view_config(route_name='redirect') +def redirect_view(request): + return HTTPFound(location="/problem") + + +# /problem which causes an site error +@view_config(route_name='exception') +def exception_view(request): + raise Exception() -- cgit v1.2.3 From bf84d90b4dccb9fc52c8fe385e52f7a63e9a5535 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 13 Aug 2013 07:36:48 -0400 Subject: Add Intersphinx for Beaker, clean up some broken references, change from pip to virtualenv (and give an explanation), explain virtualenv on Python 2.7. --- docs/conf.py | 3 +++ docs/index.rst | 8 ++++---- docs/quick_tour.rst | 35 ++++++++++++++++++++--------------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index e60cd7118..1ddcf95da 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -71,6 +71,9 @@ intersphinx_mapping = { 'http://docs.pylonsproject.org/projects/deform/en/latest', None), 'sqla': ('http://docs.sqlalchemy.org/en/latest', None), + 'beaker': ( + 'http://docs.pylonsproject.org/projects/pyramid_beaker/en/latest', + None), 'who': ('http://docs.repoze.org/who/latest', None), 'python': ('http://docs.python.org', None), 'python3': ('http://docs.python.org/3', None), diff --git a/docs/index.rst b/docs/index.rst index d570e7811..550a5312e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -47,11 +47,11 @@ up to speed right away. * :doc:`quick_tour` goes through the major features in Pyramid, covering a little about a lot. -* For help getting Pyramid set up, try the `install guide - <../narr/install>`_. +* To see a minimal Pyramid web application, check out + :ref:`firstapp_chapter`. -* To see a minimal Pyramid web application, check out `creating your first - Pyramid application <../narr/firstapp>`_. +* For help getting Pyramid set up, try + :ref:`installing_chapter`. * Like learning by example? Visit the official :doc:`wiki tutorial <../tutorials/wiki2/index>` as well as the diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index cb07826cf..ba2a517ef 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -29,15 +29,25 @@ area in place. For Python 3.3: $ source env33/bin/activate $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python -We make a :term:`virtualenv` then activate it. We then get Python -packaging tools installed. +We make a :term:`virtualenv` then activate it. Next we download +Python's packaging support and install it, giving us the +``easy_install`` command-line script for adding new packages. Python +2.7 users will need to use ``virtualenv`` instead of ``pyvenv`` to make +their virtual environment. + +.. note:: + + Why ``easy_install`` and not ``pip``? Pyramid encourages use of + namespace packages which, until recently, ``pip`` didn't permit. + Also, Pyramid has some optional C extensions for performance. With + ``easy_install``, Windows users can get these extensions without + needing a C compiler. .. seealso:: See Also: Python 3's :mod:`venv module `, the ``setuptools`` `installation instructions `_, - documentation for `pip `_, - and - Pyramid's :ref:`Before You Install ` + `easy_install help `_, + and Pyramid's :ref:`Before You Install `. Pyramid Installation ==================== @@ -722,8 +732,7 @@ Jinja2 template: .. seealso:: See Also: :ref:`sessions_chapter`, :ref:`flash_messages`, :ref:`session_module`, and - `Beaker sessioning middleware - `_ + :ref:`Beaker sessioning middleware ` Databases ========= @@ -771,8 +780,7 @@ of the system, can then easily get at the data thanks to SQLAlchemy: .. seealso:: See Also: `SQLAlchemy `_, :ref:`making_a_console_script`, :ref:`bfg_sql_wiki_tutorial`, and - `Application Transactions With pyramid_tm - `_ + :ref:`Application Transactions With pyramid_tm ` Forms ===== @@ -823,10 +831,7 @@ We'd like to handle form submission, validation, and saving: Deform and Colander provide a very flexible combination for forms, widgets, schemas, and validation. Recent versions of Deform also -include a -`retail mode `_ -for gaining Deform +include a :ref:`retail mode ` for gaining Deform features on custom forms. Also, the ``deform_bootstrap`` Pyramid add-on restyles the stock Deform @@ -834,8 +839,8 @@ widgets using attractive CSS from Bootstrap and more powerful widgets from Chosen. .. seealso:: See Also: - `Deform `_, - `Colander `_, and + :ref:`Deform `, + :ref:`Colander `, and `deform_bootstrap `_ Conclusion -- cgit v1.2.3 From fe8c0f5f2de669941015c222005be1b5e62e39ed Mon Sep 17 00:00:00 2001 From: Jonathan Villemaire-Krajden Date: Tue, 13 Aug 2013 11:26:43 -0400 Subject: Request.current_route_url() now returns the query string by default. --- pyramid/tests/test_url.py | 28 ++++++++++++++++++++++++++++ pyramid/url.py | 2 ++ 2 files changed, 30 insertions(+) diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index e33eeebfd..2830f8f10 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -485,6 +485,34 @@ class TestURLMethodsMixin(unittest.TestCase): self.assertEqual(result, 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + def test_current_route_url_with_request_query(self): + from pyramid.interfaces import IRoutesMapper + from webob.multidict import GetDict + request = self._makeOne() + request.GET = GetDict([('q', '123')], {}) + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_url() + self.assertEqual(result, + 'http://example.com:5432/1/2/3?q=123') + + def test_current_route_url_with_query_override(self): + from pyramid.interfaces import IRoutesMapper + from webob.multidict import GetDict + request = self._makeOne() + request.GET = GetDict([('q', '123')], {}) + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_url(_query={'a':1}) + self.assertEqual(result, + 'http://example.com:5432/1/2/3?a=1') + def test_current_route_path(self): from pyramid.interfaces import IRoutesMapper request = self._makeOne() diff --git a/pyramid/url.py b/pyramid/url.py index 83f0d1eab..feb304fb8 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -221,6 +221,8 @@ class URLMethodsMixin(object): query = kw.pop('_query') if query: qs = '?' + urlencode(query, doseq=True) + elif getattr(self, 'GET', None): + qs = '?' + urlencode(self.GET, doseq=True) if '_anchor' in kw: anchor = kw.pop('_anchor') -- cgit v1.2.3 From e160a44cc459baf5e30ad19e18b7c95b0a6397ac Mon Sep 17 00:00:00 2001 From: Jonathan Villemaire-Krajden Date: Tue, 13 Aug 2013 12:33:41 -0400 Subject: Updated doc string for Request.current_route_url. --- pyramid/url.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/pyramid/url.py b/pyramid/url.py index feb304fb8..b135c361a 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -124,15 +124,18 @@ class URLMethodsMixin(object): ``*remainder`` replacement value, it is tacked on to the URL after being URL-quoted-except-for-embedded-slashes. - If a keyword argument ``_query`` is present, it will be used to - compose a query string that will be tacked on to the end of the - URL. The value of ``_query`` must be a sequence of two-tuples - *or* a data structure with an ``.items()`` method that returns a + If no ``_query`` keyword argument is provided, the request + query string will be returned in the URL. If it is present, it + will be used to compose a query string that will be tacked on + to the end of the URL, replacing any request query string. + The value of ``_query`` must be a sequence of two-tuples *or* + a data structure with an ``.items()`` method that returns a sequence of two-tuples (presumably a dictionary). This data - structure will be turned into a query string per the documentation - of :func:`pyramid.encode.urlencode` function. After the query - data is turned into a query string, a leading ``?`` is prepended, - and the resulting string is appended to the generated URL. + structure will be turned into a query string per the + documentation of :func:`pyramid.encode.urlencode` function. + After the query data is turned into a query string, a leading + ``?`` is prepended, and the resulting string is appended to + the generated URL. .. note:: -- cgit v1.2.3 From 0f1bc5286f772d2001bbcab8235bf5f7805b7634 Mon Sep 17 00:00:00 2001 From: Jonathan Villemaire-Krajden Date: Tue, 13 Aug 2013 13:10:47 -0400 Subject: Updated CHANGES Fixes 1040. --- CHANGES.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index e9533ab48..1b4c3492c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -168,6 +168,9 @@ Bug Fixes - The ``alchemy`` scaffold would break when the database was MySQL during tables creation. See https://github.com/Pylons/pyramid/pull/1049 +- The route ``current_route_url`` method now attaches the query string to the URL by default. See + https://github.com/Pylons/pyramid/issues/1040 + 1.4 (2012-12-18) ================ @@ -205,6 +208,8 @@ Backwards Incompatibilities similar way to the changes described to ``_depth`` above. This argument remains undocumented, but might be used in the wild by some insane person. +- Modified the ``current_route_url`` method in pyramid.Request. The method previously returned the URL without the query string by default, it now does attach the query string unless it is overriden. + 1.4b1 (2012-11-21) ================== -- cgit v1.2.3 From 33e0fe18037d99312d8d4d966a8e01baffc2e62d Mon Sep 17 00:00:00 2001 From: Jonathan Villemaire-Krajden Date: Tue, 13 Aug 2013 13:25:17 -0400 Subject: Fixes to documentation, added change to what's new. --- CHANGES.txt | 9 ++++++--- docs/whatsnew-1.5.rst | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1b4c3492c..42b3e7546 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -168,9 +168,14 @@ Bug Fixes - The ``alchemy`` scaffold would break when the database was MySQL during tables creation. See https://github.com/Pylons/pyramid/pull/1049 -- The route ``current_route_url`` method now attaches the query string to the URL by default. See +- The ``current_route_url`` method now attaches the query string to the URL by default. See https://github.com/Pylons/pyramid/issues/1040 +Backwards Incompatibilities +--------------------------- + +- Modified the ``current_route_url`` method in pyramid.Request. The method previously returned the URL without the query string by default, it now does attach the query string unless it is overriden. + 1.4 (2012-12-18) ================ @@ -208,8 +213,6 @@ Backwards Incompatibilities similar way to the changes described to ``_depth`` above. This argument remains undocumented, but might be used in the wild by some insane person. -- Modified the ``current_route_url`` method in pyramid.Request. The method previously returned the URL without the query string by default, it now does attach the query string unless it is overriden. - 1.4b1 (2012-11-21) ================== diff --git a/docs/whatsnew-1.5.rst b/docs/whatsnew-1.5.rst index b987fa77f..89bfdbee3 100644 --- a/docs/whatsnew-1.5.rst +++ b/docs/whatsnew-1.5.rst @@ -134,7 +134,8 @@ The feature additions in Pyramid 1.5 follow. Backwards Incompatibilities --------------------------- -This release has no known backwards incompatibilities with Pyramid 1.4.X. +- Modified the ``current_route_url`` method in pyramid.Request. The method previously returned the URL without the query string by default, it now does attach the query string unless it is overriden. + Deprecations ------------ -- cgit v1.2.3 From 6a4a3413756a94f5e7ebbe7720788f28ca280a72 Mon Sep 17 00:00:00 2001 From: Jonathan Villemaire-Krajden Date: Tue, 13 Aug 2013 14:01:25 -0400 Subject: Fixed documentation width, signed contributors agreement and added a test for duplicate query strings. --- CHANGES.txt | 7 +++++-- CONTRIBUTORS.txt | 2 ++ pyramid/tests/test_url.py | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 42b3e7546..0479e3011 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -168,13 +168,16 @@ Bug Fixes - The ``alchemy`` scaffold would break when the database was MySQL during tables creation. See https://github.com/Pylons/pyramid/pull/1049 -- The ``current_route_url`` method now attaches the query string to the URL by default. See +- The ``current_route_url`` method now attaches the query string to the URL by + default. See https://github.com/Pylons/pyramid/issues/1040 Backwards Incompatibilities --------------------------- -- Modified the ``current_route_url`` method in pyramid.Request. The method previously returned the URL without the query string by default, it now does attach the query string unless it is overriden. +- Modified the ``current_route_url`` method in pyramid.Request. The method + previously returned the URL without the query string by default, it now does + attach the query string unless it is overriden. 1.4 (2012-12-18) ================ diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 0cecc93df..be9f36338 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -208,3 +208,5 @@ Contributors - Junaid Ali, 2013/08/10 - Chris Davies, 2013/08/11 + +- Jonathan Villemaire-Krajden, 2013/08/13 diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index 2830f8f10..9841c143e 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -499,6 +499,20 @@ class TestURLMethodsMixin(unittest.TestCase): self.assertEqual(result, 'http://example.com:5432/1/2/3?q=123') + def test_current_route_url_with_request_query_duplicate_entries(self): + from pyramid.interfaces import IRoutesMapper + from webob.multidict import GetDict + request = self._makeOne() + request.GET = GetDict([('q', '123'), ('b', '2'), ('b', '2'), ('q', '456')], {}) + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_url() + self.assertEqual(result, + 'http://example.com:5432/1/2/3?q=123&b=2&b=2&q=456') + def test_current_route_url_with_query_override(self): from pyramid.interfaces import IRoutesMapper from webob.multidict import GetDict @@ -525,7 +539,7 @@ class TestURLMethodsMixin(unittest.TestCase): result = request.current_route_path('extra1', 'extra2', _query={'a':1}, _anchor=text_(b"foo")) self.assertEqual(result, '/script_name/1/2/3/extra1/extra2?a=1#foo') - + def test_route_path_with_elements(self): from pyramid.interfaces import IRoutesMapper request = self._makeOne() -- cgit v1.2.3 From b4ae4260ea434a39e5d3dfa026a7f6e70ef8d70c Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 13 Aug 2013 15:10:18 -0500 Subject: fix line length --- docs/whatsnew-1.5.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/whatsnew-1.5.rst b/docs/whatsnew-1.5.rst index 89bfdbee3..445eb84ae 100644 --- a/docs/whatsnew-1.5.rst +++ b/docs/whatsnew-1.5.rst @@ -123,8 +123,8 @@ The feature additions in Pyramid 1.5 follow. :func:`pyramid.paster.get_appsettings`. This also allowed the generated ``initialize_db`` script from the ``alchemy`` scaffold to grow support for options in the form ``a=1 b=2`` so you can fill in values in a parameterized - ``.ini`` file, e.g. ``initialize_myapp_db etc/development.ini a=1 b=2``. See - https://github.com/Pylons/pyramid/pull/911 + ``.ini`` file, e.g. ``initialize_myapp_db etc/development.ini a=1 b=2``. + See https://github.com/Pylons/pyramid/pull/911 - The ``request.session.check_csrf_token()`` method and the ``check_csrf`` view predicate now take into account the value of the HTTP header named @@ -134,7 +134,9 @@ The feature additions in Pyramid 1.5 follow. Backwards Incompatibilities --------------------------- -- Modified the ``current_route_url`` method in pyramid.Request. The method previously returned the URL without the query string by default, it now does attach the query string unless it is overriden. +- Modified the ``current_route_url`` method in pyramid.Request. The method + previously returned the URL without the query string by default, it now does + attach the query string unless it is overriden. Deprecations -- cgit v1.2.3 From a54d7d6f33904e925da27e74d34039f56b7b68e1 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 13 Aug 2013 15:22:07 -0500 Subject: fix a regression with the current_route_url changes in #1081 --- pyramid/url.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyramid/url.py b/pyramid/url.py index b135c361a..3d95d7cc9 100644 --- a/pyramid/url.py +++ b/pyramid/url.py @@ -224,8 +224,6 @@ class URLMethodsMixin(object): query = kw.pop('_query') if query: qs = '?' + urlencode(query, doseq=True) - elif getattr(self, 'GET', None): - qs = '?' + urlencode(self.GET, doseq=True) if '_anchor' in kw: anchor = kw.pop('_anchor') @@ -684,6 +682,9 @@ class URLMethodsMixin(object): if route_name is None: raise ValueError('Current request matches no route') + if '_query' not in kw: + kw['_query'] = self.GET + newkw = {} newkw.update(self.matchdict) newkw.update(kw) -- cgit v1.2.3 From 86553245537393611da769b3fcc29a23e9ef68b0 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Tue, 13 Aug 2013 16:38:42 -0400 Subject: Shut up warning about latexindex not being in a TOC. Add back in a label that could be used for api_documentation references. --- docs/index.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index 9d38fb297..f899ddac3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -129,6 +129,8 @@ platforms. tutorials/bfg/index.rst tutorials/modwsgi/index.rst +.. _api_documentation: + API Documentation ================= @@ -202,4 +204,5 @@ Index and Glossary :hidden: glossary + latexindex -- cgit v1.2.3 From 4c6754fee3114b9d6baca135e75fbd51169c5cf9 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 13 Aug 2013 23:24:59 -0400 Subject: fixed mako renderer returning a tuple with a previous defname value in some circumstances --- pyramid/mako_templating.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index 8d4583d82..fa45b671c 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -215,12 +215,9 @@ class MakoLookupTemplateRenderer(object): context = system.pop('context', None) if context is not None: system['_context'] = context - if self.defname is None: - if isinstance(value, tuple): - self.defname, value = value - else: - if isinstance(value, tuple): - _, value = value + # tuple returned to be deprecated + if isinstance(value, tuple): + self.defname, value = value try: system.update(value) except (TypeError, ValueError): -- cgit v1.2.3 From 894d304ed5f738746195f956a204f7e551e1cb5b Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 13 Aug 2013 23:25:23 -0400 Subject: added mako renderer test --- pyramid/tests/test_mako_templating.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pyramid/tests/test_mako_templating.py b/pyramid/tests/test_mako_templating.py index f607a5497..a57ac0aaa 100644 --- a/pyramid/tests/test_mako_templating.py +++ b/pyramid/tests/test_mako_templating.py @@ -416,6 +416,21 @@ class MakoLookupTemplateRendererTests(Base, maybe_unittest()): self.assertEqual(result, text_('result')) self.assertEqual(lookup.values, {'_context':1}) + def test_call_with_defname_with_tuple_value_twice(self): + lookup = DummyLookup() + instance1 = self._makeOne('path', 'defname', lookup) + result1 = instance1(('defname1', {}), {'context':1}) + self.assertEqual(lookup.deffed, 'defname1') + self.assertEqual(result1, text_('result')) + self.assertEqual(lookup.values, {'_context':1}) + instance2 = self._makeOne('path', 'defname', lookup) + result2 = instance2(('defname2', {}), {'context':2}) + self.assertNotEqual(lookup.deffed, 'defname1') + self.assertEqual(lookup.deffed, 'defname2') + self.assertEqual(result2, text_('result')) + self.assertEqual(lookup.values, {'_context':2}) + + def test_call_with_nondict_value(self): lookup = DummyLookup() instance = self._makeOne('path', None, lookup) -- cgit v1.2.3 From 96df8d5c511ec6742873b3e86d3c875899dc77e3 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Tue, 13 Aug 2013 23:51:17 -0400 Subject: added deprecation warning for mako tuple --- pyramid/mako_templating.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyramid/mako_templating.py b/pyramid/mako_templating.py index fa45b671c..c07ee227f 100644 --- a/pyramid/mako_templating.py +++ b/pyramid/mako_templating.py @@ -2,6 +2,7 @@ import os import posixpath import sys import threading +import warnings from zope.interface import ( implementer, @@ -217,6 +218,14 @@ class MakoLookupTemplateRenderer(object): system['_context'] = context # tuple returned to be deprecated if isinstance(value, tuple): + warnings.warn( + 'Using a tuple in the form (\'defname\', {}) to render a ' + 'Mako partial will be deprecated in the future. Use a ' + 'Mako template renderer as documented in the "Using A ' + 'Mako def name Within a Renderer Name" chapter of the ' + 'Pyramid narrative documentation instead', + DeprecationWarning, + 3) self.defname, value = value try: system.update(value) -- cgit v1.2.3 From 24c932646ace774d39341bc52cfa01ef84eeede5 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Wed, 14 Aug 2013 00:04:46 -0400 Subject: added bug fix to changes --- CHANGES.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 0479e3011..84f3aaf54 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -133,6 +133,10 @@ Features Bug Fixes --------- +- Fixed a Mako renderer bug returning a tuple with a previous defname value +in some circumstances. See https://github.com/Pylons/pyramid/issues/1037 for +more information. + - Make the ``pyramid.config.assets.PackageOverrides`` object implement the API for ``__loader__`` objects specified in PEP 302. Proxies to the ``__loader__`` set by the importer, if present; otherwise, raises @@ -270,7 +274,7 @@ Features @subscriber(SomeOtherEvent) def asubscriber(event): pass - + And you wanted to use a subscriber predicate:: @subscriber([SomeEvent, SomeContextType], mypredicate=True) @@ -344,7 +348,7 @@ Features @subscriber([SomeContextType, SomeEvent]) def asubscriber(event): - # bzzt! you'll be getting the context here as ``event``, and it'll + # bzzt! you'll be getting the context here as ``event``, and it'll # be useless Existing multiple-argument subscribers continue to work without issue, so you @@ -614,7 +618,7 @@ Bug Fixes https://github.com/Pylons/pyramid/issues/606 https://github.com/Pylons/pyramid/issues/607 -- In Mako Templates lookup, check for absolute uri (using mako directories) +- In Mako Templates lookup, check for absolute uri (using mako directories) when mixing up inheritance with asset specs. https://github.com/Pylons/pyramid/issues/662 @@ -833,13 +837,13 @@ Backwards Incompatibilities * ``registerAdapter``, use ``pyramid.config.Configurator.registry.registerAdapter`` instead. - * ``registerSubscriber``, use + * ``registerSubscriber``, use ``pyramid.config.Configurator.add_subscriber`` instead. - * ``registerRoute``, use + * ``registerRoute``, use ``pyramid.config.Configurator.add_route`` instead. - * ``registerSettings``, use + * ``registerSettings``, use ``pyramid.config.Configurator.add_settings`` instead. - In Pyramid 1.3 and previous, the ``__call__`` method of a Response object -- cgit v1.2.3 From 3de54e3009f624f3c3dabe531fbcc25483368fe4 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Wed, 14 Aug 2013 00:10:03 -0400 Subject: fixed line indentation --- CHANGES.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 84f3aaf54..76522695a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -134,8 +134,8 @@ Bug Fixes --------- - Fixed a Mako renderer bug returning a tuple with a previous defname value -in some circumstances. See https://github.com/Pylons/pyramid/issues/1037 for -more information. + in some circumstances. See https://github.com/Pylons/pyramid/issues/1037 + for more information. - Make the ``pyramid.config.assets.PackageOverrides`` object implement the API for ``__loader__`` objects specified in PEP 302. Proxies to the -- cgit v1.2.3 From 1378f1f9dc704d3939bd4bab8642d57a908cab8d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 13 Aug 2013 23:29:41 -0500 Subject: remove some dead code --- pyramid/util.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pyramid/util.py b/pyramid/util.py index 02bd7ba2a..98732d17f 100644 --- a/pyramid/util.py +++ b/pyramid/util.py @@ -69,17 +69,12 @@ class InstancePropertyMixin(object): can accept multiple ``(name, property)`` pairs generated via :meth:`pyramid.util.InstancePropertyMixin._make_property`. - ``attrs`` is a sequence of 2-tuples *or* a data structure with - an ``.items()`` method which returns a sequence of 2-tuples + ``properties`` is a sequence of two-tuples *or* a data structure + with an ``.items()`` method which returns a sequence of two-tuples (presumably a dictionary). It will be used to add several properties to the instance in a manner that is more efficient than simply calling ``set_property`` repeatedly. """ - - if hasattr(properties, 'items'): - attrs = properties.items() - else: - attrs = properties attrs = dict(properties) parent = self.__class__ -- cgit v1.2.3 From 0cd88bcb8a309c8ae890883459c55deaccd3794f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 14 Aug 2013 11:04:52 -0500 Subject: prevent reparenting if no properties are defined --- pyramid/util.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyramid/util.py b/pyramid/util.py index 98732d17f..73f3ebdb0 100644 --- a/pyramid/util.py +++ b/pyramid/util.py @@ -77,9 +77,10 @@ class InstancePropertyMixin(object): """ attrs = dict(properties) - parent = self.__class__ - cls = type(parent.__name__, (parent, object), attrs) - self.__class__ = cls + if attrs: + parent = self.__class__ + cls = type(parent.__name__, (parent, object), attrs) + self.__class__ = cls def _set_extensions(self, extensions): for name, fn in iteritems_(extensions.methods): -- cgit v1.2.3 From 2d81001b80195e31a45c4d088285c5ed93712989 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Wed, 14 Aug 2013 16:07:17 -0400 Subject: Changes recommended by Lisa Ballard at PyLadies via Steve Piercy, thanks Lisa! --- docs/quick_tour.rst | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index ba2a517ef..e191de198 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -29,8 +29,16 @@ area in place. For Python 3.3: $ source env33/bin/activate $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python -We make a :term:`virtualenv` then activate it. Next we download -Python's packaging support and install it, giving us the +If ``wget`` complains with a certificate error, run it with: + +.. code-block:: bash + + $ wget --no-check-certificate + +In these steps above we first made a :term:`virtualenv` and then +"activated" it, which adjusted our path to look first in +``env33/bin`` for commands (such as ``python``.) We next downloaded +Python's packaging support and installed it, giving us the ``easy_install`` command-line script for adding new packages. Python 2.7 users will need to use ``virtualenv`` instead of ``pyvenv`` to make their virtual environment. @@ -202,7 +210,8 @@ Above we saw the basics of routing URLs to views in Pyramid: .. note:: - Why do this twice? Other systems don't make us repeat this! As + Why do this twice? Other Python web frameworks let you create a + route and associate it with a view in one step. As illustrated in :ref:`routes_need_ordering`, multiple routes might match the same URL pattern. Rather than provide ways to help guess, Pyramid lets you be explicit in ordering. Pyramid also gives -- cgit v1.2.3 From b13a1c3499f256942eff69fa47162fce36811e0c Mon Sep 17 00:00:00 2001 From: themanwithoutaplan Date: Thu, 15 Aug 2013 11:05:30 +0200 Subject: Added myself to the contributors. --- CONTRIBUTORS.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index be9f36338..2fb7cc85d 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -210,3 +210,6 @@ Contributors - Chris Davies, 2013/08/11 - Jonathan Villemaire-Krajden, 2013/08/13 + +- Charlie Clark, 2013/08/15 + -- cgit v1.2.3 From 3ea7883a5822fb1279aa2dbad54ba77fa2c6db8f Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Thu, 15 Aug 2013 12:12:49 +0200 Subject: Add reference to the pull requests Conflicts: CHANGES.txt --- CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index f98de6c29..53724fdcb 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -56,6 +56,9 @@ Features same domain. * ``domain``: if provided the cookie is always set for this domain, bypassing all usual logic. + See https://github.com/Pylons/pyramid/pull/1028, + https://github.com/Pylons/pyramid/pull/1072 and + https://github.com/Pylons/pyramid/pull/1078. - The ``AuthTktAuthenticationPolicy`` now supports IPv6 addresses when using the ``include_ip=True`` option. This is possibly incompatible with -- cgit v1.2.3 From 5710a15399fcbf7d682171087393418473fdea6a Mon Sep 17 00:00:00 2001 From: kusut Date: Thu, 15 Aug 2013 20:26:58 +0700 Subject: Update install.rst - simplify installation by removing distribute (merge with setuptools) - update setuptools link - simplify windows tutorial by dropping 3.2, latest python version only (2.7 and 3.3) --- docs/narr/install.rst | 144 ++++++++++++-------------------------------------- 1 file changed, 33 insertions(+), 111 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 8fc63f3a4..d05c8abeb 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -162,19 +162,19 @@ also prevent :app:`Pyramid` from globally installing versions of packages that are not compatible with your system Python. To set up a virtualenv in which to install :app:`Pyramid`, first ensure that -:term:`setuptools` or :term:`distribute` is installed. To do so, invoke +:term:`setuptools` is installed. To do so, invoke ``import setuptools`` within the Python interpreter you'd like to run :app:`Pyramid` under. -The following command will not display anything if setuptools or distribute is +The following command will not display anything if setuptools is already installed: .. code-block:: text $ python2.7 -c 'import setuptools' -Running the same command will yield the following output if setuptools or -distribute is not yet installed: +Running the same command will yield the following output if setuptools is not +yet installed: .. code-block:: text @@ -183,27 +183,23 @@ distribute is not yet installed: ImportError: No module named setuptools If ``import setuptools`` raises an :exc:`ImportError` as it does above, you -will need to install setuptools or distribute manually. +will need to install setuptools manually. If you are using a "system" Python (one installed by your OS distributor or a 3rd-party packager such as Fink or MacPorts), you can usually install the -setuptools or distribute package by using your system's package manager. If +setuptools package by using your system's package manager. If you cannot do this, or if you're using a self-installed version of Python, -you will need to install setuptools or distribute "by hand". Installing -setuptools or distribute "by hand" is always a reasonable thing to do, even +you will need to install setuptools "by hand". Installing +setuptools "by hand" is always a reasonable thing to do, even if your package manager already has a pre-chewed version of setuptools for installation. -If you're using Python 2, you'll want to install ``setuptools``. If you're -using Python 3, you'll want to install ``distribute``. Below we tell you how -to do both. - -Installing Setuptools On Python 2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Installing Setuptools +~~~~~~~~~~~~~~~~~~~~~ To install setuptools by hand under Python 2, first download `ez_setup.py -`_ then invoke it using the -Python interpreter into which you want to install setuptools. +`_ then +invoke it using the Python interpreter into which you want to install setuptools. .. code-block:: text @@ -218,35 +214,13 @@ the script. To remediate this, you may need to do: $ sudo python ez_setup.py -Installing Distribute On Python 3 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``setuptools`` doesn't work under Python 3. Instead, you can use -``distribute``, which is a fork of setuptools. To -install it, first download `distribute_setup.py -`_ then invoke it using the -Python interpreter into which you want to install setuptools. - -.. code-block:: text - - $ python3 distribute_setup.py - -Once this command is invoked, distribute should be installed on your system. -If the command fails due to permission errors, you may need to be the -administrative user on your system to successfully invoke the script. To -remediate this, you may need to do: - -.. code-block:: text - - $ sudo python3 distribute_setup.py - .. index:: pair: install; virtualenv Installing the ``virtualenv`` Package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've got setuptools or distribute installed, you should install the +Once you've got setuptools installed, you should install the :term:`virtualenv` package. To install the :term:`virtualenv` package into your setuptools-enabled Python interpreter, use the ``easy_install`` command. @@ -261,7 +235,7 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. Turing-complete. If you insist on using ``pyvenv``, you'll need to understand how to install - software such as ``distribute`` into the virtual environment manually, + software such as ``setuptools`` into the virtual environment manually, which this guide does not cover. .. code-block:: text @@ -335,91 +309,37 @@ complete, as it downloads and installs a number of dependencies. Installing :app:`Pyramid` on a Windows System ------------------------------------------------- -You can use Pyramid on Windows under Python 2 or under Python 3. Directions -for both versions are included below. +You can use Pyramid on Windows under Python 2 or under Python 3. -Windows Using Python 2 -~~~~~~~~~~~~~~~~~~~~~~ - -#. Install the most recent `Python 2.7.x version +#. Install the most recent `Python 2.7.x or 3.3.x version `_ for your system. #. Install the `Python for Windows extensions `_. Make sure to - pick the right download for Python 2.7 and install it using the - same Python installation from the previous step. + pick the right download for Python 2.7 or Python 3.3 and install it + using the same Python installation from the previous step. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step above: download `ez_setup.py - `_ and run it using - the ``python`` interpreter of your Python 2.7 installation using a - command prompt: + `_ + and run it using the ``python`` interpreter of your Python 2.7 or 3.3 + installation using a command prompt: .. code-block:: text + # modify the command according to the python version, e.g.: + # for Python 2.7: c:\> c:\Python27\python ez_setup.py + # for Python 3.3: + c:\> c:\Python33\python ez_setup.py #. Install `virtualenv`: .. code-block:: text - - c:\> c:\Python27\Scripts\easy_install virtualenv - -#. Make a :term:`virtualenv` workspace: - - .. code-block:: text - - c:\> set VENV=c:\env - c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% - - You can either follow the use of the environment variable, ``%VENV%``, - or replace it with the root directory of the :term:`virtualenv`. - In that case, the `set` command can be skipped. - If you choose the former approach, ensure that it's an absolute path. - -#. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell - environment wired to use the virtualenv. - -#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies - installed: - - .. code-block:: text - - c:\env> %VENV%\Scripts\easy_install pyramid - -Windows Using Python 3 -~~~~~~~~~~~~~~~~~~~~~~ - -#. Install, or find the latest version of `Python 3.x - `_ for your system and which is - supported by Pyramid. - -#. Install the `Python for Windows extensions - `_. Make sure to - pick the right download for Python 3.x and install it using the - same Python installation from the previous step. - -#. Install latest :term:`distribute` distribution into the Python you - obtained/installed/found in the step above: download `distribute_setup.py - `_ and run it using the - ``python`` interpreter of your Python 3.x installation using a command - prompt: - - .. code-block:: text - # modify the command according to the python version, e.g.: - # for Python 3.2.x: - c:\> c:\Python32\python distribute_setup.py - # for Python 3.3.x: - c:\> c:\Python33\python distribute_setup.py - -#. Install :term:`virtualenv`: - - .. code-block:: text - - # for Python 3.2.x: - c:\> c:\Python32\Scripts\easy_install virtualenv - # for Python 3.3.x: + # for Python 2.7: + c:\> c:\Python27\Scripts\easy_install virtualenv + # for Python 3.3: c:\> c:\Python33\Scripts\easy_install virtualenv #. Make a :term:`virtualenv` workspace: @@ -427,9 +347,11 @@ Windows Using Python 3 .. code-block:: text c:\> set VENV=c:\env - # for Python 3.2.x: - c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% - # for Python 3.3.x: + + # modify the command according to the python version, e.g.: + # for Python 2.7: + c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% + # for Python 3.3: c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV% You can either follow the use of the environment variable, ``%VENV%``, -- cgit v1.2.3 From bcfd25cbb2b7b7c0d1a897f33926caa203c44290 Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Thu, 15 Aug 2013 15:39:25 +0200 Subject: added myself to contributors list --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 2fb7cc85d..dab27469a 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -213,3 +213,4 @@ Contributors - Charlie Clark, 2013/08/15 +- Tom Lazar, 2013/08/15 -- cgit v1.2.3 From b6803d0b11f38cd353ec5b00301f5558ebb9be3b Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Thu, 15 Aug 2013 16:30:34 +0200 Subject: sign the contribution agreement... --- CONTRIBUTORS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index dab27469a..ef02bf7f4 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -214,3 +214,5 @@ Contributors - Charlie Clark, 2013/08/15 - Tom Lazar, 2013/08/15 + +- Andreas Zeidler, 2013/08/15 -- cgit v1.2.3 From d6e8b86723d8601df924ec31205f016b86778b98 Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Thu, 15 Aug 2013 16:43:46 +0200 Subject: Make ``pserve.cherrypy_server_runner`` Python 3 compatible. Closes https://github.com/Pylons/pyramid/issues/718 --- CHANGES.txt | 3 +++ pyramid/scripts/pserve.py | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 53724fdcb..679f8ed4a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -183,6 +183,9 @@ Bug Fixes default. See https://github.com/Pylons/pyramid/issues/1040 +- Make ``pserve.cherrypy_server_runner`` Python 3 compatible. See + https://github.com/Pylons/pyramid/issues/718 + Backwards Incompatibilities --------------------------- diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index cc368d721..75c648c01 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -959,7 +959,14 @@ def cherrypy_server_runner( server = wsgiserver.CherryPyWSGIServer(bind_addr, app, server_name=server_name, **kwargs) - server.ssl_certificate = server.ssl_private_key = ssl_pem + if ssl_pem is not None: + import sys + if sys.version_info < (3, 0): + server.ssl_certificate = server.ssl_private_key = ssl_pem + else: + wsgiserver.get_ssl_adapter_class() # creates wsgiserver.ssl_builtin as side-effect + server.ssl_adapter = wsgiserver.ssl_builtin.BuiltinSSLAdapter(ssl_pem, ssl_pem) + if protocol_version: server.protocol = protocol_version -- cgit v1.2.3 From 7319ab677216063581e47a231fd70b8b55a19466 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 15 Aug 2013 10:25:55 -0500 Subject: cleanup cherrypy runner --- pyramid/scripts/pserve.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pyramid/scripts/pserve.py b/pyramid/scripts/pserve.py index 75c648c01..8cceecbb3 100644 --- a/pyramid/scripts/pserve.py +++ b/pyramid/scripts/pserve.py @@ -25,6 +25,7 @@ import traceback from paste.deploy import loadserver from paste.deploy import loadapp +from pyramid.compat import PY3 from pyramid.compat import WIN from pyramid.paster import setup_logging @@ -960,12 +961,13 @@ def cherrypy_server_runner( server = wsgiserver.CherryPyWSGIServer(bind_addr, app, server_name=server_name, **kwargs) if ssl_pem is not None: - import sys - if sys.version_info < (3, 0): + if not PY3: server.ssl_certificate = server.ssl_private_key = ssl_pem else: - wsgiserver.get_ssl_adapter_class() # creates wsgiserver.ssl_builtin as side-effect - server.ssl_adapter = wsgiserver.ssl_builtin.BuiltinSSLAdapter(ssl_pem, ssl_pem) + # creates wsgiserver.ssl_builtin as side-effect + wsgiserver.get_ssl_adapter_class() + server.ssl_adapter = wsgiserver.ssl_builtin.BuiltinSSLAdapter( + ssl_pem, ssl_pem) if protocol_version: server.protocol = protocol_version -- cgit v1.2.3 From 58c5fefd37109fe7f27ca77a3d0896cc4b8e0470 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 15 Aug 2013 21:57:48 +0200 Subject: fix some rST issues --- CHANGES.txt | 4 +++- docs/narr/install.rst | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 679f8ed4a..48efad6d4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -51,11 +51,13 @@ Features - The ``AuthTktAuthenticationPolicy`` has two new options to configure its domain usage: + * ``parent_domain``: if set the authentication cookie is set on the parent domain. This is useful if you have multiple sites sharing the same domain. * ``domain``: if provided the cookie is always set for this domain, bypassing - all usual logic. + all usual logic. + See https://github.com/Pylons/pyramid/pull/1028, https://github.com/Pylons/pyramid/pull/1072 and https://github.com/Pylons/pyramid/pull/1078. diff --git a/docs/narr/install.rst b/docs/narr/install.rst index d05c8abeb..ef5772f79 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -336,6 +336,7 @@ You can use Pyramid on Windows under Python 2 or under Python 3. #. Install `virtualenv`: .. code-block:: text + # modify the command according to the python version, e.g.: # for Python 2.7: c:\> c:\Python27\Scripts\easy_install virtualenv -- cgit v1.2.3 From b3cfa2a91925b008fbfedf7f87371b56cd086213 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 15 Aug 2013 23:17:21 +0200 Subject: fix misplaced symbol --- docs/quick_tour.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst index e191de198..f75533220 100644 --- a/docs/quick_tour.rst +++ b/docs/quick_tour.rst @@ -37,7 +37,7 @@ If ``wget`` complains with a certificate error, run it with: In these steps above we first made a :term:`virtualenv` and then "activated" it, which adjusted our path to look first in -``env33/bin`` for commands (such as ``python``.) We next downloaded +``env33/bin`` for commands (such as ``python``). We next downloaded Python's packaging support and installed it, giving us the ``easy_install`` command-line script for adding new packages. Python 2.7 users will need to use ``virtualenv`` instead of ``pyvenv`` to make -- cgit v1.2.3 From 575515b28f5e9cca48c6989b44ba964312995be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Martano?= Date: Thu, 15 Aug 2013 18:50:53 -0300 Subject: ZODB now supports Python3. --- docs/narr/project.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/narr/project.rst b/docs/narr/project.rst index ec5d706aa..52f13d5a8 100644 --- a/docs/narr/project.rst +++ b/docs/narr/project.rst @@ -49,9 +49,7 @@ The included scaffolds are these: URL mapping via :term:`URL dispatch` and no persistence mechanism. ``zodb`` - URL mapping via :term:`traversal` and persistence via :term:`ZODB`. *Note - that, as of this writing, this scaffold will not run under Python 3, only - under Python 2.* + URL mapping via :term:`traversal` and persistence via :term:`ZODB`. ``alchemy`` URL mapping via :term:`URL dispatch` and persistence via -- cgit v1.2.3 From 916c2c7b9f0efa39458090e8406ed9f5de580fa6 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Fri, 16 Aug 2013 00:20:30 +0200 Subject: remove extraneous space --- docs/quick_tour/package/development.ini | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/quick_tour/package/development.ini b/docs/quick_tour/package/development.ini index a751ff903..a3a73e885 100644 --- a/docs/quick_tour/package/development.ini +++ b/docs/quick_tour/package/development.ini @@ -11,8 +11,6 @@ debug_templates = true default_locale_name = en jinja2.directories = hello_world:templates - - [pipeline:main] pipeline = hello_world @@ -44,7 +42,6 @@ keys = generic level = INFO handlers = console - [handler_console] class = StreamHandler args = (sys.stderr,) -- cgit v1.2.3 From edfc4f80a1240f6f5f0c41e53078a8f5d305075f Mon Sep 17 00:00:00 2001 From: Philip Jenvey Date: Thu, 15 Aug 2013 15:57:14 -0700 Subject: prefer the functionish print --- docs/designdefense.rst | 2 +- docs/narr/commandline.rst | 6 +++--- docs/narr/events.rst | 6 +++--- docs/narr/extconfig.rst | 4 ++-- docs/narr/hooks.rst | 4 ++-- docs/narr/webob.rst | 2 +- pyramid/config/__init__.py | 2 +- pyramid/decorator.py | 4 ++-- pyramid/events.py | 4 ++-- pyramid/interfaces.py | 8 ++++---- pyramid/path.py | 2 +- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/designdefense.rst b/docs/designdefense.rst index 22570c23d..cebcf6218 100644 --- a/docs/designdefense.rst +++ b/docs/designdefense.rst @@ -1461,7 +1461,7 @@ code below: def afunc(): for i in range(10): - print i + print(i) By its nature, the *request* object created as the result of a WSGI server's call into a long-lived web framework cannot be global, because the lifetime diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst index 17e5227fa..58b9bdd21 100644 --- a/docs/narr/commandline.rst +++ b/docs/narr/commandline.rst @@ -538,7 +538,7 @@ representing Pyramid your application configuration as a single argument: from pyramid.paster import bootstrap env = bootstrap('/path/to/my/development.ini') - print env['request'].route_url('home') + print(env['request'].route_url('home')) :func:`pyramid.paster.bootstrap` returns a dictionary containing framework-related information. This dictionary will always contain a @@ -606,7 +606,7 @@ to load instead of ``main``: from pyramid.paster import bootstrap env = bootstrap('/path/to/my/development.ini#another') - print env['request'].route_url('home') + print(env['request'].route_url('home')) The above example specifies the ``another`` ``app``, ``pipeline``, or ``composite`` section of your PasteDeploy configuration file. The ``app`` @@ -643,7 +643,7 @@ the desired request and passing it into :func:`~pyramid.paster.bootstrap`: request = Request.blank('/', base_url='https://example.com/prefix') env = bootstrap('/path/to/my/development.ini#another', request=request) - print env['request'].application_url + print(env['request'].application_url) # will print 'https://example.com/prefix' Now you can readily use Pyramid's APIs for generating URLs: diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 11af89ca6..2accb3dbe 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -26,7 +26,7 @@ subscriber is a function that accepts a single argument named `event`: :linenos: def mysubscriber(event): - print event + print(event) The above is a subscriber that simply prints the event to the console when it's called. @@ -113,10 +113,10 @@ your application like so: :linenos: def handle_new_request(event): - print 'request', event.request + print('request', event.request) def handle_new_response(event): - print 'response', event.response + print('response', event.response) You may configure these functions to be called at the appropriate times by adding the following code to your application's diff --git a/docs/narr/extconfig.rst b/docs/narr/extconfig.rst index 659056952..6587aef92 100644 --- a/docs/narr/extconfig.rst +++ b/docs/narr/extconfig.rst @@ -55,7 +55,7 @@ method of the Configurator: :linenos: def mysubscriber(event): - print event.request + print(event.request) config.add_newrequest_subscriber(mysubscriber) @@ -79,7 +79,7 @@ able to install it and subsequently do: :linenos: def mysubscriber(event): - print event.request + print(event.request) from pyramid.config import Configurator config = Configurator() diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 37a74b53a..3a2568775 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -291,7 +291,7 @@ actually execute the function until accessed. return sum(args) def prop(request): - print "getting the property" + print("getting the property") return "the property" config = Configurator() @@ -332,7 +332,7 @@ Here is an example of passing a class to ``Configurator.add_request_method``: # use @property if you don't want to cache the result @reify def prop(self): - print "getting the property" + print("getting the property") return "the property" config = Configurator() diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index c0ca450b1..f0a4b5a0b 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -287,7 +287,7 @@ When such a request reaches a view in your application, the @view_config(renderer='string') def aview(request): - print request.json_body + print(request.json_body) return 'OK' For the above view, printed to the console will be: diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index d52ee0e7a..d4557d6b1 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -1055,7 +1055,7 @@ class ActionState(object): ... v = context.execute_actions() ... except ConfigurationExecutionError, v: ... pass - >>> print v + >>> print(v) exceptions.AttributeError: 'function' object has no attribute 'xxx' in: oops diff --git a/pyramid/decorator.py b/pyramid/decorator.py index e5f2996dc..0d17bc398 100644 --- a/pyramid/decorator.py +++ b/pyramid/decorator.py @@ -10,7 +10,7 @@ class reify(object): class Foo(object): @reify def jammy(self): - print 'jammy called' + print('jammy called') return 1 And usage of Foo: @@ -18,7 +18,7 @@ class reify(object): >>> f = Foo() >>> v = f.jammy 'jammy called' - >>> print v + >>> print(v) 1 >>> f.jammy 1 diff --git a/pyramid/events.py b/pyramid/events.py index 836466ba2..31af8e1fc 100644 --- a/pyramid/events.py +++ b/pyramid/events.py @@ -40,7 +40,7 @@ class subscriber(object): @subscriber(NewRequest, NewResponse) def mysubscriber(event): - print event + print(event) When the ``subscriber`` decorator is used without passing an arguments, the function it decorates is called for every event sent: @@ -51,7 +51,7 @@ class subscriber(object): @subscriber() def mysubscriber(event): - print event + print(event) This method will have no effect until a :term:`scan` is performed against the package or module which contains it, ala: diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 275209737..2a14df7c7 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -760,15 +760,15 @@ class IContextURL(IResourceURL): # # class Fudge(object): # def __init__(self, one, two): - # print one, two + # print(one, two) # class Another(object): # def __init__(self, one, two): - # print one, two + # print(one, two) # ob = object() # r.registerAdapter(Fudge, (Interface, Interface), IContextURL) - # print r.queryMultiAdapter((ob, ob), IResourceURL) + # print(r.queryMultiAdapter((ob, ob), IResourceURL)) # r.registerAdapter(Another, (Interface, Interface), IResourceURL) - # print r.queryMultiAdapter((ob, ob), IResourceURL) + # print(r.queryMultiAdapter((ob, ob), IResourceURL)) # # prints # diff --git a/pyramid/path.py b/pyramid/path.py index 57eccdb19..ab39a85d9 100644 --- a/pyramid/path.py +++ b/pyramid/path.py @@ -181,7 +181,7 @@ class AssetResolver(Resolver): a = AssetResolver('myproject') resolver = a.resolve('templates/foo.pt') - print resolver.abspath() + print(resolver.abspath()) # -> /path/to/myproject/templates/foo.pt If the AssetResolver is constructed without a ``package`` argument of -- cgit v1.2.3 From d04e2c8e7d12768f92f18ab4771b76492927bb6d Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 02:44:39 -0700 Subject: Clean up directions for install Python 2 and 3 and Python extensions on Windows, per feedback from Windows guinea pigs at SFPython Hack Night. --- docs/narr/install.rst | 149 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 114 insertions(+), 35 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index ef5772f79..c1ce64406 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -162,19 +162,19 @@ also prevent :app:`Pyramid` from globally installing versions of packages that are not compatible with your system Python. To set up a virtualenv in which to install :app:`Pyramid`, first ensure that -:term:`setuptools` is installed. To do so, invoke +:term:`setuptools` or :term:`distribute` is installed. To do so, invoke ``import setuptools`` within the Python interpreter you'd like to run :app:`Pyramid` under. -The following command will not display anything if setuptools is +The following command will not display anything if setuptools or distribute is already installed: .. code-block:: text $ python2.7 -c 'import setuptools' -Running the same command will yield the following output if setuptools is not -yet installed: +Running the same command will yield the following output if setuptools or +distribute is not yet installed: .. code-block:: text @@ -183,23 +183,27 @@ yet installed: ImportError: No module named setuptools If ``import setuptools`` raises an :exc:`ImportError` as it does above, you -will need to install setuptools manually. +will need to install setuptools or distribute manually. If you are using a "system" Python (one installed by your OS distributor or a 3rd-party packager such as Fink or MacPorts), you can usually install the -setuptools package by using your system's package manager. If +setuptools or distribute package by using your system's package manager. If you cannot do this, or if you're using a self-installed version of Python, -you will need to install setuptools "by hand". Installing -setuptools "by hand" is always a reasonable thing to do, even +you will need to install setuptools or distribute "by hand". Installing +setuptools or distribute "by hand" is always a reasonable thing to do, even if your package manager already has a pre-chewed version of setuptools for installation. -Installing Setuptools -~~~~~~~~~~~~~~~~~~~~~ +If you're using Python 2, you'll want to install ``setuptools``. If you're +using Python 3, you'll want to install ``distribute``. Below we tell you how +to do both. + +Installing Setuptools On Python 2 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To install setuptools by hand under Python 2, first download `ez_setup.py -`_ then -invoke it using the Python interpreter into which you want to install setuptools. +`_ then invoke it using the +Python interpreter into which you want to install setuptools. .. code-block:: text @@ -214,13 +218,35 @@ the script. To remediate this, you may need to do: $ sudo python ez_setup.py +Installing Distribute On Python 3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``setuptools`` doesn't work under Python 3. Instead, you can use +``distribute``, which is a fork of setuptools. To +install it, first download `distribute_setup.py +`_ then invoke it using the +Python interpreter into which you want to install setuptools. + +.. code-block:: text + + $ python3 distribute_setup.py + +Once this command is invoked, distribute should be installed on your system. +If the command fails due to permission errors, you may need to be the +administrative user on your system to successfully invoke the script. To +remediate this, you may need to do: + +.. code-block:: text + + $ sudo python3 distribute_setup.py + .. index:: pair: install; virtualenv Installing the ``virtualenv`` Package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've got setuptools installed, you should install the +Once you've got setuptools or distribute installed, you should install the :term:`virtualenv` package. To install the :term:`virtualenv` package into your setuptools-enabled Python interpreter, use the ``easy_install`` command. @@ -235,7 +261,7 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. Turing-complete. If you insist on using ``pyvenv``, you'll need to understand how to install - software such as ``setuptools`` into the virtual environment manually, + software such as ``distribute`` into the virtual environment manually, which this guide does not cover. .. code-block:: text @@ -309,50 +335,103 @@ complete, as it downloads and installs a number of dependencies. Installing :app:`Pyramid` on a Windows System ------------------------------------------------- -You can use Pyramid on Windows under Python 2 or under Python 3. +You can use Pyramid on Windows under Python 2 or under Python 3. Directions +for both versions are included below. -#. Install the most recent `Python 2.7.x or 3.3.x version +Windows Using Python 2 +~~~~~~~~~~~~~~~~~~~~~~ + +#. Download and install the most recent `Python 2.7.x version `_ for your system. -#. Install the `Python for Windows extensions - `_. Make sure to - pick the right download for Python 2.7 or Python 3.3 and install it - using the same Python installation from the previous step. +#. Download and install the `Python for Windows extensions + `_. Carefully read + the README.txt file at the end of the list of builds, and follow its + directions. Make sure you get the proper bittedness of build and Python + 2.7 version. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step above: download `ez_setup.py - `_ - and run it using the ``python`` interpreter of your Python 2.7 or 3.3 - installation using a command prompt: + `_ and run it using + the ``python`` interpreter of your Python 2.7 installation using a + command prompt: .. code-block:: text - # modify the command according to the python version, e.g.: - # for Python 2.7: c:\> c:\Python27\python ez_setup.py - # for Python 3.3: - c:\> c:\Python33\python ez_setup.py #. Install `virtualenv`: .. code-block:: text - # modify the command according to the python version, e.g.: - # for Python 2.7: c:\> c:\Python27\Scripts\easy_install virtualenv - # for Python 3.3: - c:\> c:\Python33\Scripts\easy_install virtualenv #. Make a :term:`virtualenv` workspace: .. code-block:: text c:\> set VENV=c:\env - - # modify the command according to the python version, e.g.: - # for Python 2.7: c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% - # for Python 3.3: + + You can either follow the use of the environment variable, ``%VENV%``, + or replace it with the root directory of the :term:`virtualenv`. + In that case, the `set` command can be skipped. + If you choose the former approach, ensure that it's an absolute path. + +#. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell + environment wired to use the virtualenv. + +#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies + installed: + + .. code-block:: text + + c:\env> %VENV%\Scripts\easy_install pyramid + +Windows Using Python 3 +~~~~~~~~~~~~~~~~~~~~~~ + +#. Download and install the latest version of `Python 3.x + `_ for your system and which is + supported by Pyramid. + +#. Download and install the `Python for Windows extensions + `_. Carefully read + the README.txt file at the end of the list of builds, and follow its + directions. Make sure you get the proper bittedness of build and Python + 3.x version. + +#. Install latest :term:`distribute` distribution into the Python you + obtained/installed/found in the step above: download `distribute_setup.py + `_ and run it using the + ``python`` interpreter of your Python 3.x installation using a command + prompt: + + .. code-block:: text + + # modify the command according to the python version, e.g.: + # for Python 3.2.x: + c:\> c:\Python32\python distribute_setup.py + # for Python 3.3.x: + c:\> c:\Python33\python distribute_setup.py + +#. Install :term:`virtualenv`: + + .. code-block:: text + + # for Python 3.2.x: + c:\> c:\Python32\Scripts\easy_install virtualenv + # for Python 3.3.x: + c:\> c:\Python33\Scripts\easy_install virtualenv + +#. Make a :term:`virtualenv` workspace: + + .. code-block:: text + + c:\> set VENV=c:\env + # for Python 3.2.x: + c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% + # for Python 3.3.x: c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV% You can either follow the use of the environment variable, ``%VENV%``, -- cgit v1.2.3 From b35dc8716d2281e9ee7856736d19a45000802c81 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 04:45:21 -0700 Subject: Sphinx: WAAAAAAH! Just shut up and duplicate the link already. --- docs/narr/install.rst | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index c1ce64406..eaa9642a8 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -344,11 +344,8 @@ Windows Using Python 2 #. Download and install the most recent `Python 2.7.x version `_ for your system. -#. Download and install the `Python for Windows extensions - `_. Carefully read - the README.txt file at the end of the list of builds, and follow its - directions. Make sure you get the proper bittedness of build and Python - 2.7 version. +#. Download and install the `Python for Windows extensions (for Python 2.7) `_. + Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper bittedness of build and Python 2.7 version. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step above: download `ez_setup.py @@ -395,11 +392,8 @@ Windows Using Python 3 `_ for your system and which is supported by Pyramid. -#. Download and install the `Python for Windows extensions - `_. Carefully read - the README.txt file at the end of the list of builds, and follow its - directions. Make sure you get the proper bittedness of build and Python - 3.x version. +#. Download and install the `Python for Windows extensions (for Python 3.x) `_. + Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper bittedness of build and Python 3.x version. #. Install latest :term:`distribute` distribution into the Python you obtained/installed/found in the step above: download `distribute_setup.py -- cgit v1.2.3 From 96645b9b7efb55976d5a87fc3d27982b572e031a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 04:49:08 -0700 Subject: and fix 79 cols --- docs/narr/install.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index eaa9642a8..54109e70f 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -344,8 +344,11 @@ Windows Using Python 2 #. Download and install the most recent `Python 2.7.x version `_ for your system. -#. Download and install the `Python for Windows extensions (for Python 2.7) `_. - Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper bittedness of build and Python 2.7 version. +#. Download and install the `Python for Windows extensions (for Python 2.7) + `_. Carefully read + the README.txt file at the end of the list of builds, and follow its + directions. Make sure you get the proper bittedness of build and Python 2.7 + version. #. Install latest :term:`setuptools` distribution into the Python you obtained/installed/found in the step above: download `ez_setup.py @@ -392,8 +395,11 @@ Windows Using Python 3 `_ for your system and which is supported by Pyramid. -#. Download and install the `Python for Windows extensions (for Python 3.x) `_. - Carefully read the README.txt file at the end of the list of builds, and follow its directions. Make sure you get the proper bittedness of build and Python 3.x version. +#. Download and install the `Python for Windows extensions (for Python 3.x) + `_. Carefully read + the README.txt file at the end of the list of builds, and follow its + directions. Make sure you get the proper bittedness of build and Python 3.x + version. #. Install latest :term:`distribute` distribution into the Python you obtained/installed/found in the step above: download `distribute_setup.py -- cgit v1.2.3 From bb0f9b899a45aaa347bf7be3c55bfa78edfeec61 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 23:17:07 -0700 Subject: merge changes from kusut PR#1085 and stevepiercy PR#1084 wrap to 79 columns remove duplicate link of Windows extensions at top of file to prevent early clickage --- docs/narr/install.rst | 369 +++++++++++++++++++------------------------------- 1 file changed, 141 insertions(+), 228 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 54109e70f..e3dc1da2a 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -9,49 +9,50 @@ Installing :app:`Pyramid` Before You Install ------------------ -You will need `Python `_ version 2.6 or better to -run :app:`Pyramid`. +You will need `Python `_ version 2.6 or better to run +:app:`Pyramid`. .. sidebar:: Python Versions - As of this writing, :app:`Pyramid` has been tested under Python 2.6, - Python 2.7, Python 3.2, and Python 3.3. :app:`Pyramid` does not - run under any version of Python before 2.6. + As of this writing, :app:`Pyramid` has been tested under Python 2.6, Python + 2.7, Python 3.2, and Python 3.3. :app:`Pyramid` does not run under any + version of Python before 2.6. -:app:`Pyramid` is known to run on all popular UNIX-like systems such as -Linux, Mac OS X, and FreeBSD as well as on Windows platforms. It is -also known to run on :term:`PyPy` (1.9+). +:app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, +Mac OS X, and FreeBSD as well as on Windows platforms. It is also known to run +on :term:`PyPy` (1.9+). -:app:`Pyramid` installation does not require the compilation of any -C code, so you need only a Python interpreter that meets the -requirements mentioned. +:app:`Pyramid` installation does not require the compilation of any C code, so +you need only a Python interpreter that meets the requirements mentioned. For Mac OS X Users ~~~~~~~~~~~~~~~~~~ From `Python.org `_: - Python comes pre-installed on Mac OS X, but due to Apple's release - cycle, it's often one or even two years old. The overwhelming - recommendation of the "MacPython" community is to upgrade your - Python by downloading and installing a newer version from - `the Python standard release page `_. + Python comes pre-installed on Mac OS X, but due to Apple's release cycle, + it's often one or even two years old. The overwhelming recommendation of + the "MacPython" community is to upgrade your Python by downloading and + installing a newer version from `the Python standard release page + `_. -It is recommended to download one of the *installer* versions, unless you prefer to install your Python through a packgage manager (e.g., macports or homebrew) or to build your Python from source. +It is recommended to download one of the *installer* versions, unless you +prefer to install your Python through a packgage manager (e.g., macports or +homebrew) or to build your Python from source. -Unless you have a need for a specific earlier version, it is recommended -to install the latest 2.x or 3.x version of Python. +Unless you have a need for a specific earlier version, it is recommended to +install the latest 2.x or 3.x version of Python. -If you use an installer for your Python, then you can skip to the -section :ref:`installing_unix`. +If you use an installer for your Python, then you can skip to the section +:ref:`installing_unix`. If You Don't Yet Have A Python Interpreter (UNIX) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If your system doesn't have a Python interpreter, and you're on UNIX, -you can either install Python using your operating system's package -manager *or* you can install Python from source fairly easily on any -UNIX system that has development tools. +If your system doesn't have a Python interpreter, and you're on UNIX, you can +either install Python using your operating system's package manager *or* you +can install Python from source fairly easily on any UNIX system that has +development tools. .. index:: pair: install; Python (from package, UNIX) @@ -59,13 +60,12 @@ UNIX system that has development tools. Package Manager Method ++++++++++++++++++++++ -You can use your system's "package manager" to install Python. -Each package manager is slightly different, but the "flavor" of -them is usually the same. +You can use your system's "package manager" to install Python. Each package +manager is slightly different, but the "flavor" of them is usually the same. For example, on a Debian or Ubuntu system, use the following command: -.. code-block:: text +.. code-block:: bash $ sudo apt-get install python2.7-dev @@ -82,30 +82,29 @@ invokable via ``python2.7`` from a shell prompt. Source Compile Method +++++++++++++++++++++ -It's useful to use a Python interpreter that *isn't* the "system" -Python interpreter to develop your software. The authors of -:app:`Pyramid` tend not to use the system Python for development -purposes; always a self-compiled one. Compiling Python is usually -easy, and often the "system" Python is compiled with options that -aren't optimal for web development. For an explanation, see +It's useful to use a Python interpreter that *isn't* the "system" Python +interpreter to develop your software. The authors of :app:`Pyramid` tend not +to use the system Python for development purposes; always a self-compiled one. +Compiling Python is usually easy, and often the "system" Python is compiled +with options that aren't optimal for web development. For an explanation, see https://github.com/Pylons/pyramid/issues/747. -To compile software on your UNIX system, typically you need -development tools. Often these can be installed via the package -manager. For example, this works to do so on an Ubuntu Linux system: +To compile software on your UNIX system, typically you need development tools. +Often these can be installed via the package manager. For example, this works +to do so on an Ubuntu Linux system: -.. code-block:: text +.. code-block:: bash $ sudo apt-get install build-essential -On Mac OS X, installing `XCode -`_ has much the same effect. +On Mac OS X, installing `XCode `_ has +much the same effect. -Once you've got development tools installed on your system, you can -install a Python 2.7 interpreter from *source*, on the same system, -using the following commands: +Once you've got development tools installed on your system, you can install a +Python 2.7 interpreter from *source*, on the same system, using the following +commands: -.. code-block:: text +.. code-block:: bash $ cd ~ $ mkdir tmp @@ -117,9 +116,8 @@ using the following commands: $ ./configure --prefix=$HOME/opt/Python-2.7.3 $ make && make install -Once these steps are performed, the Python interpreter will be -invokable via ``$HOME/opt/Python-2.7.3/bin/python`` from a shell -prompt. +Once these steps are performed, the Python interpreter will be invokable via +``$HOME/opt/Python-2.7.3/bin/python`` from a shell prompt. .. index:: pair: install; Python (from package, Windows) @@ -127,24 +125,21 @@ prompt. If You Don't Yet Have A Python Interpreter (Windows) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If your Windows system doesn't have a Python interpreter, you'll need -to install it by downloading a Python 2.7-series interpreter -executable from `python.org's download section -`_ (the files labeled "Windows -Installer"). Once you've downloaded it, double click on the -executable and accept the defaults during the installation process. -You may also need to download and install the `Python for Windows -extensions `_. +If your Windows system doesn't have a Python interpreter, you'll need to +install it by downloading a Python 2.7-series interpreter executable from +`python.org's download section `_ (the files +labeled "Windows Installer"). Once you've downloaded it, double click on the +executable and accept the defaults during the installation process. You may +also need to download and install the Python for Windows extensions. .. warning:: - After you install Python on Windows, you may need to add the - ``C:\Python27`` directory to your environment's ``Path`` in order - to make it possible to invoke Python from a command prompt by - typing ``python``. To do so, right click ``My Computer``, select - ``Properties`` --> ``Advanced Tab`` --> ``Environment Variables`` - and add that directory to the end of the ``Path`` environment - variable. + After you install Python on Windows, you may need to add the ``C:\Python27`` + directory to your environment's ``Path`` in order to make it possible to + invoke Python from a command prompt by typing ``python``. To do so, right + click ``My Computer``, select ``Properties`` --> ``Advanced Tab`` --> + ``Environment Variables`` and add that directory to the end of the ``Path`` + environment variable. .. index:: single: installing on UNIX @@ -154,91 +149,63 @@ extensions `_. Installing :app:`Pyramid` on a UNIX System --------------------------------------------- -It is best practice to install :app:`Pyramid` into a "virtual" -Python environment in order to obtain isolation from any "system" -packages you've got installed in your Python version. This can be -done by using the :term:`virtualenv` package. Using a virtualenv will -also prevent :app:`Pyramid` from globally installing versions of -packages that are not compatible with your system Python. +It is best practice to install :app:`Pyramid` into a "virtual" Python +environment in order to obtain isolation from any "system" packages you've got +installed in your Python version. This can be done by using the +:term:`virtualenv` package. Using a virtualenv will also prevent +:app:`Pyramid` from globally installing versions of packages that are not +compatible with your system Python. To set up a virtualenv in which to install :app:`Pyramid`, first ensure that -:term:`setuptools` or :term:`distribute` is installed. To do so, invoke -``import setuptools`` within the Python interpreter you'd like to run -:app:`Pyramid` under. +:term:`setuptools` is installed. To do so, invoke ``import setuptools`` within +the Python interpreter you'd like to run :app:`Pyramid` under. -The following command will not display anything if setuptools or distribute is -already installed: +The following command will not display anything if setuptools is already +installed: -.. code-block:: text +.. code-block:: bash $ python2.7 -c 'import setuptools' -Running the same command will yield the following output if setuptools or -distribute is not yet installed: +Running the same command will yield the following output if setuptools is not +yet installed: -.. code-block:: text +.. code-block:: bash Traceback (most recent call last): File "", line 1, in ImportError: No module named setuptools If ``import setuptools`` raises an :exc:`ImportError` as it does above, you -will need to install setuptools or distribute manually. +will need to install setuptools manually. If you are using a "system" Python (one installed by your OS distributor or a -3rd-party packager such as Fink or MacPorts), you can usually install the -setuptools or distribute package by using your system's package manager. If -you cannot do this, or if you're using a self-installed version of Python, -you will need to install setuptools or distribute "by hand". Installing -setuptools or distribute "by hand" is always a reasonable thing to do, even -if your package manager already has a pre-chewed version of setuptools for -installation. +third-party packager such as Fink or MacPorts), you can usually install the +setuptools package by using your system's package manager. If you cannot do +this, or if you're using a self-installed version of Python, you will need to +install setuptools "by hand". Installing setuptools "by hand" is always a +reasonable thing to do, even if your package manager already has a pre-chewed +version of setuptools for installation. -If you're using Python 2, you'll want to install ``setuptools``. If you're -using Python 3, you'll want to install ``distribute``. Below we tell you how -to do both. - -Installing Setuptools On Python 2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Installing Setuptools +~~~~~~~~~~~~~~~~~~~~~ To install setuptools by hand under Python 2, first download `ez_setup.py -`_ then invoke it using the -Python interpreter into which you want to install setuptools. +`_ then invoke +it using the Python interpreter into which you want to install setuptools. -.. code-block:: text +.. code-block:: bash $ python ez_setup.py -Once this command is invoked, setuptools should be installed on your -system. If the command fails due to permission errors, you may need -to be the administrative user on your system to successfully invoke -the script. To remediate this, you may need to do: - -.. code-block:: text - - $ sudo python ez_setup.py - -Installing Distribute On Python 3 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -``setuptools`` doesn't work under Python 3. Instead, you can use -``distribute``, which is a fork of setuptools. To -install it, first download `distribute_setup.py -`_ then invoke it using the -Python interpreter into which you want to install setuptools. - -.. code-block:: text - - $ python3 distribute_setup.py - -Once this command is invoked, distribute should be installed on your system. +Once this command is invoked, setuptools should be installed on your system. If the command fails due to permission errors, you may need to be the administrative user on your system to successfully invoke the script. To remediate this, you may need to do: -.. code-block:: text +.. code-block:: bash - $ sudo python3 distribute_setup.py + $ sudo python ez_setup.py .. index:: pair: install; virtualenv @@ -246,9 +213,9 @@ remediate this, you may need to do: Installing the ``virtualenv`` Package ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've got setuptools or distribute installed, you should install the -:term:`virtualenv` package. To install the :term:`virtualenv` package into -your setuptools-enabled Python interpreter, use the ``easy_install`` command. +Once you've got setuptools installed, you should install the :term:`virtualenv` +package. To install the :term:`virtualenv` package into your +setuptools-enabled Python interpreter, use the ``easy_install`` command. .. warning:: @@ -261,18 +228,18 @@ your setuptools-enabled Python interpreter, use the ``easy_install`` command. Turing-complete. If you insist on using ``pyvenv``, you'll need to understand how to install - software such as ``distribute`` into the virtual environment manually, - which this guide does not cover. + software such as ``setuptools`` into the virtual environment manually, which + this guide does not cover. -.. code-block:: text +.. code-block:: bash $ easy_install virtualenv This command should succeed, and tell you that the virtualenv package is now -installed. If it fails due to permission errors, you may need to install it -as your system's administrative user. For example: +installed. If it fails due to permission errors, you may need to install it as +your system's administrative user. For example: -.. code-block:: text +.. code-block:: bash $ sudo easy_install virtualenv @@ -286,41 +253,40 @@ Creating the Virtual Python Environment Once the :term:`virtualenv` package is installed in your Python environment, you can then create a virtual environment. To do so, invoke the following: -.. code-block:: text +.. code-block:: bash $ export VENV=~/env $ virtualenv --no-site-packages $VENV New python executable in /home/foo/env/bin/python Installing setuptools.............done. -You can either follow the use of the environment variable, ``$VENV``, -or replace it with the root directory of the :term:`virtualenv`. -In that case, the `export` command can be skipped. -If you choose the former approach, ensure that it's an absolute path. +You can either follow the use of the environment variable, ``$VENV``, or +replace it with the root directory of the :term:`virtualenv`. In that case, the +`export` command can be skipped. If you choose the former approach, ensure that +it's an absolute path. .. warning:: - Using ``--no-site-packages`` when generating your - virtualenv is *very important*. This flag provides the necessary - isolation for running the set of packages required by - :app:`Pyramid`. If you do not specify ``--no-site-packages``, - it's possible that :app:`Pyramid` will not install properly into - the virtualenv, or, even if it does, may not run properly, - depending on the packages you've already got installed into your - Python's "main" site-packages dir. + Using ``--no-site-packages`` when generating your virtualenv is *very + important*. This flag provides the necessary isolation for running the set + of packages required by :app:`Pyramid`. If you do not specify + ``--no-site-packages``, it's possible that :app:`Pyramid` will not install + properly into the virtualenv, or, even if it does, may not run properly, + depending on the packages you've already got installed into your Python's + "main" site-packages dir. .. warning:: *do not* use ``sudo`` to run the - ``virtualenv`` script. It's perfectly acceptable (and desirable) - to create a virtualenv as a normal user. + ``virtualenv`` script. It's perfectly acceptable (and desirable) to create + a virtualenv as a normal user. Installing :app:`Pyramid` Into the Virtual Python Environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -After you've got your virtualenv installed, you may install -:app:`Pyramid` itself using the following commands: +After you've got your virtualenv installed, you may install :app:`Pyramid` +itself using the following commands: -.. code-block:: text +.. code-block:: bash $ $VENV/bin/easy_install pyramid @@ -335,109 +301,56 @@ complete, as it downloads and installs a number of dependencies. Installing :app:`Pyramid` on a Windows System ------------------------------------------------- -You can use Pyramid on Windows under Python 2 or under Python 3. Directions -for both versions are included below. - -Windows Using Python 2 -~~~~~~~~~~~~~~~~~~~~~~ +You can use Pyramid on Windows under Python 2 or 3. -#. Download and install the most recent `Python 2.7.x version +#. Download and install the most recent `Python 2.7.x or 3.3.x version `_ for your system. -#. Download and install the `Python for Windows extensions (for Python 2.7) +#. Download and install the `Python for Windows extensions `_. Carefully read the README.txt file at the end of the list of builds, and follow its - directions. Make sure you get the proper bittedness of build and Python 2.7 + directions. Make sure you get the proper "bittedness" of build and Python version. -#. Install latest :term:`setuptools` distribution into the Python you - obtained/installed/found in the step above: download `ez_setup.py - `_ and run it using - the ``python`` interpreter of your Python 2.7 installation using a - command prompt: +#. Install latest :term:`setuptools` distribution into the Python from step 1 + above: download `ez_setup.py + `_ and run + it using the ``python`` interpreter of your Python 2.7 or 3.3 installation + using a command prompt: - .. code-block:: text + .. code-block:: bash + # modify the command according to the python version, e.g.: + # for Python 2.7: c:\> c:\Python27\python ez_setup.py + # for Python 3.3: + c:\> c:\Python33\python ez_setup.py #. Install `virtualenv`: - .. code-block:: text - - c:\> c:\Python27\Scripts\easy_install virtualenv - -#. Make a :term:`virtualenv` workspace: - - .. code-block:: text - - c:\> set VENV=c:\env - c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% - - You can either follow the use of the environment variable, ``%VENV%``, - or replace it with the root directory of the :term:`virtualenv`. - In that case, the `set` command can be skipped. - If you choose the former approach, ensure that it's an absolute path. - -#. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell - environment wired to use the virtualenv. - -#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies - installed: - - .. code-block:: text - - c:\env> %VENV%\Scripts\easy_install pyramid - -Windows Using Python 3 -~~~~~~~~~~~~~~~~~~~~~~ - -#. Download and install the latest version of `Python 3.x - `_ for your system and which is - supported by Pyramid. - -#. Download and install the `Python for Windows extensions (for Python 3.x) - `_. Carefully read - the README.txt file at the end of the list of builds, and follow its - directions. Make sure you get the proper bittedness of build and Python 3.x - version. - -#. Install latest :term:`distribute` distribution into the Python you - obtained/installed/found in the step above: download `distribute_setup.py - `_ and run it using the - ``python`` interpreter of your Python 3.x installation using a command - prompt: - - .. code-block:: text + .. code-block:: bash # modify the command according to the python version, e.g.: - # for Python 3.2.x: - c:\> c:\Python32\python distribute_setup.py - # for Python 3.3.x: - c:\> c:\Python33\python distribute_setup.py - -#. Install :term:`virtualenv`: - - .. code-block:: text - - # for Python 3.2.x: - c:\> c:\Python32\Scripts\easy_install virtualenv - # for Python 3.3.x: + # for Python 2.7: + c:\> c:\Python27\Scripts\easy_install virtualenv + # for Python 3.3: c:\> c:\Python33\Scripts\easy_install virtualenv #. Make a :term:`virtualenv` workspace: - .. code-block:: text + .. code-block:: bash c:\> set VENV=c:\env - # for Python 3.2.x: - c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% - # for Python 3.3.x: + # modify the command according to the python version, e.g.: + # for Python 2.7: + c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% + # for Python 3.3: c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV% - You can either follow the use of the environment variable, ``%VENV%``, - or replace it with the root directory of the :term:`virtualenv`. - In that case, the `set` command can be skipped. - If you choose the former approach, ensure that it's an absolute path. + You can either follow the use of the environment variable, ``%VENV%``, or + replace it with the root directory of the :term:`virtualenv`. In that case, + the `set` command can be skipped. If you choose the former approach, ensure + that it's an absolute path. #. (Optional) Consider using ``%VENV%\Scripts\activate.bat`` to make your shell environment wired to use the virtualenv. @@ -445,7 +358,7 @@ Windows Using Python 3 #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: - .. code-block:: text + .. code-block:: bash c:\env> %VENV%\Scripts\easy_install pyramid -- cgit v1.2.3 From ca25863d5100535e1b91117b3487b1b3a03e2522 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 15 Aug 2013 23:30:04 -0700 Subject: undoing bash highlighting to just text. bash prepends a $ which makes copy/paste of commands annoying, and for Windows with \ in the path, it is an escape character and does weird colorization. --- docs/narr/install.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index e3dc1da2a..7f549e824 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -65,7 +65,7 @@ manager is slightly different, but the "flavor" of them is usually the same. For example, on a Debian or Ubuntu system, use the following command: -.. code-block:: bash +.. code-block:: text $ sudo apt-get install python2.7-dev @@ -93,7 +93,7 @@ To compile software on your UNIX system, typically you need development tools. Often these can be installed via the package manager. For example, this works to do so on an Ubuntu Linux system: -.. code-block:: bash +.. code-block:: text $ sudo apt-get install build-essential @@ -104,7 +104,7 @@ Once you've got development tools installed on your system, you can install a Python 2.7 interpreter from *source*, on the same system, using the following commands: -.. code-block:: bash +.. code-block:: text $ cd ~ $ mkdir tmp @@ -163,14 +163,14 @@ the Python interpreter you'd like to run :app:`Pyramid` under. The following command will not display anything if setuptools is already installed: -.. code-block:: bash +.. code-block:: text $ python2.7 -c 'import setuptools' Running the same command will yield the following output if setuptools is not yet installed: -.. code-block:: bash +.. code-block:: text Traceback (most recent call last): File "", line 1, in @@ -194,7 +194,7 @@ To install setuptools by hand under Python 2, first download `ez_setup.py `_ then invoke it using the Python interpreter into which you want to install setuptools. -.. code-block:: bash +.. code-block:: text $ python ez_setup.py @@ -203,7 +203,7 @@ If the command fails due to permission errors, you may need to be the administrative user on your system to successfully invoke the script. To remediate this, you may need to do: -.. code-block:: bash +.. code-block:: text $ sudo python ez_setup.py @@ -231,7 +231,7 @@ setuptools-enabled Python interpreter, use the ``easy_install`` command. software such as ``setuptools`` into the virtual environment manually, which this guide does not cover. -.. code-block:: bash +.. code-block:: text $ easy_install virtualenv @@ -239,7 +239,7 @@ This command should succeed, and tell you that the virtualenv package is now installed. If it fails due to permission errors, you may need to install it as your system's administrative user. For example: -.. code-block:: bash +.. code-block:: text $ sudo easy_install virtualenv @@ -253,7 +253,7 @@ Creating the Virtual Python Environment Once the :term:`virtualenv` package is installed in your Python environment, you can then create a virtual environment. To do so, invoke the following: -.. code-block:: bash +.. code-block:: text $ export VENV=~/env $ virtualenv --no-site-packages $VENV @@ -286,7 +286,7 @@ Installing :app:`Pyramid` Into the Virtual Python Environment After you've got your virtualenv installed, you may install :app:`Pyramid` itself using the following commands: -.. code-block:: bash +.. code-block:: text $ $VENV/bin/easy_install pyramid @@ -318,7 +318,7 @@ You can use Pyramid on Windows under Python 2 or 3. it using the ``python`` interpreter of your Python 2.7 or 3.3 installation using a command prompt: - .. code-block:: bash + .. code-block:: text # modify the command according to the python version, e.g.: # for Python 2.7: @@ -328,7 +328,7 @@ You can use Pyramid on Windows under Python 2 or 3. #. Install `virtualenv`: - .. code-block:: bash + .. code-block:: text # modify the command according to the python version, e.g.: # for Python 2.7: @@ -338,7 +338,7 @@ You can use Pyramid on Windows under Python 2 or 3. #. Make a :term:`virtualenv` workspace: - .. code-block:: bash + .. code-block:: text c:\> set VENV=c:\env # modify the command according to the python version, e.g.: @@ -358,7 +358,7 @@ You can use Pyramid on Windows under Python 2 or 3. #. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies installed: - .. code-block:: bash + .. code-block:: text c:\env> %VENV%\Scripts\easy_install pyramid -- cgit v1.2.3 From 0a973db36f6fa79b931b63fd52aac76432ef9879 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Aug 2013 09:29:53 +0200 Subject: remove dead code --- pyramid/tests/test_config/test_init.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py index 7c2880a18..b8cbbd676 100644 --- a/pyramid/tests/test_config/test_init.py +++ b/pyramid/tests/test_config/test_init.py @@ -1955,12 +1955,6 @@ class DummyRequest: self.params = {} self.cookies = {} -class DummyResponse: - status = '200 OK' - headerlist = () - app_iter = () - body = '' - class DummyThreadLocalManager(object): pushed = None popped = False @@ -1992,11 +1986,6 @@ class DummyRegistry(object): def queryUtility(self, *arg, **kw): return self.util -from pyramid.interfaces import IResponse -@implementer(IResponse) -class DummyResponse(object): - pass - from zope.interface import Interface class IOther(Interface): pass -- cgit v1.2.3 From 061907bc6ce9c2f0c8421f32a767de971afccb1a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Aug 2013 09:35:03 +0200 Subject: rename teststaticappbase to staticappbase so non-nose testrunner (e.g. pytest testrunner) wont pick it up as a test, tear down the global registries in a new teardown to avoid globals pollution seen when running under py.test testrunner --- pyramid/tests/test_integration.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pyramid/tests/test_integration.py b/pyramid/tests/test_integration.py index 66205e618..eda4ae9f3 100644 --- a/pyramid/tests/test_integration.py +++ b/pyramid/tests/test_integration.py @@ -72,7 +72,7 @@ class IntegrationBase(object): here = os.path.dirname(__file__) -class TestStaticAppBase(IntegrationBase): +class StaticAppBase(IntegrationBase): def test_basic(self): res = self.testapp.get('/minimal.pt', status=200) _assertBody(res.body, os.path.join(here, 'fixtures/minimal.pt')) @@ -198,10 +198,10 @@ class TestEventOnlySubscribers(IntegrationBase, unittest.TestCase): self.assertEqual(sorted(res.body.split()), [b'foobar', b'foobar2', b'foobaryup', b'foobaryup2']) -class TestStaticAppUsingAbsPath(TestStaticAppBase, unittest.TestCase): +class TestStaticAppUsingAbsPath(StaticAppBase, unittest.TestCase): package = 'pyramid.tests.pkgs.static_abspath' -class TestStaticAppUsingAssetSpec(TestStaticAppBase, unittest.TestCase): +class TestStaticAppUsingAssetSpec(StaticAppBase, unittest.TestCase): package = 'pyramid.tests.pkgs.static_assetspec' class TestStaticAppNoSubpath(unittest.TestCase): @@ -649,6 +649,10 @@ class AcceptContentTypeTest(unittest.TestCase): from webtest import TestApp self.testapp = TestApp(app) + def tearDown(self): + import pyramid.config + pyramid.config.global_registries.empty() + def test_ordering(self): res = self.testapp.get('/hello', headers={'Accept': 'application/json; q=1.0, text/plain; q=0.9'}, status=200) self.assertEqual(res.content_type, 'application/json') -- cgit v1.2.3 From 5870e340e4ef935ff5a7977d753fa07568461b07 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Aug 2013 09:35:28 +0200 Subject: unused import --- pyramid/tests/test_scripts/test_pdistreport.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyramid/tests/test_scripts/test_pdistreport.py b/pyramid/tests/test_scripts/test_pdistreport.py index a8316c0e5..e229667c5 100644 --- a/pyramid/tests/test_scripts/test_pdistreport.py +++ b/pyramid/tests/test_scripts/test_pdistreport.py @@ -1,5 +1,4 @@ import unittest -from pyramid.tests.test_scripts import dummy class TestPDistReportCommand(unittest.TestCase): def _callFUT(self, **kw): -- cgit v1.2.3 From 8a6ee22c9f81bdb4ce985e3dd0952e0b39507d8c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 16 Aug 2013 09:43:43 +0200 Subject: unused imports --- pyramid/tests/test_url.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py index 9841c143e..bf1c514c5 100644 --- a/pyramid/tests/test_url.py +++ b/pyramid/tests/test_url.py @@ -611,7 +611,6 @@ class TestURLMethodsMixin(unittest.TestCase): ('pyramid.tests:static/foo.css', request, {}) ) def test_static_url_abspath_integration_with_staticurlinfo(self): - import os from pyramid.interfaces import IStaticURLInfo from pyramid.config.views import StaticURLInfo info = StaticURLInfo() @@ -626,7 +625,6 @@ class TestURLMethodsMixin(unittest.TestCase): 'http://example.com:5432/absstatic/test_url.py') def test_static_url_noscheme_uses_scheme_from_request(self): - import os from pyramid.interfaces import IStaticURLInfo from pyramid.config.views import StaticURLInfo info = StaticURLInfo() -- cgit v1.2.3 From 65c60a85f90f7bf8f97848e7314b6d0e9ecc5599 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Aug 2013 00:48:12 -0700 Subject: restore earlier fixes on latexindex don't make up funny words and use explicit 32- or 64-bit phrase --- docs/index.rst | 3 +-- docs/latexindex.rst | 40 ++++++++++++---------------------------- docs/narr/install.rst | 2 +- 3 files changed, 14 insertions(+), 31 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index f899ddac3..d2a0008a8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -129,7 +129,7 @@ platforms. tutorials/bfg/index.rst tutorials/modwsgi/index.rst -.. _api_documentation: +.. _html_api_documentation: API Documentation ================= @@ -204,5 +204,4 @@ Index and Glossary :hidden: glossary - latexindex diff --git a/docs/latexindex.rst b/docs/latexindex.rst index 13ba61648..eb14f5076 100644 --- a/docs/latexindex.rst +++ b/docs/latexindex.rst @@ -1,3 +1,5 @@ +:orphan: + .. _latexindex: ========================= @@ -28,8 +30,8 @@ Narrative Documentation narr/introduction narr/install - narr/configuration narr/firstapp + narr/configuration narr/project narr/startup narr/router @@ -50,6 +52,7 @@ Narrative Documentation narr/vhosting narr/testing narr/resources + narr/hellotraversal narr/muchadoabouttraversal narr/traversal narr/security @@ -60,6 +63,8 @@ Narrative Documentation narr/extending narr/advconfig narr/extconfig + narr/scaffolding + narr/upgrading narr/threadlocals narr/zca @@ -71,42 +76,21 @@ Tutorials .. toctree:: :maxdepth: 1 - tutorials/wiki/index.rst tutorials/wiki2/index.rst + tutorials/wiki/index.rst tutorials/bfg/index.rst tutorials/modwsgi/index.rst -.. _api_reference: +.. _api_documentation: -API Reference -@@@@@@@@@@@@@ +API Documentation +@@@@@@@@@@@@@@@@@ .. toctree:: :maxdepth: 1 + :glob: - api/authorization - api/authentication - api/config - api/events - api/exceptions - api/httpexceptions - api/i18n - api/interfaces - api/location - api/paster - api/registry - api/renderers - api/request - api/response - api/scripting - api/security - api/settings - api/testing - api/threadlocal - api/traversal - api/url - api/view - api/wsgi + api/* .. backmatter:: diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 7f549e824..15e9e8699 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -309,7 +309,7 @@ You can use Pyramid on Windows under Python 2 or 3. #. Download and install the `Python for Windows extensions `_. Carefully read the README.txt file at the end of the list of builds, and follow its - directions. Make sure you get the proper "bittedness" of build and Python + directions. Make sure you get the proper 32- or 64-bit build and Python version. #. Install latest :term:`setuptools` distribution into the Python from step 1 -- cgit v1.2.3 From 2ded59ba248156d92e0f5a8e6c991af93b38384c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Aug 2013 01:26:05 -0700 Subject: remove --no-site-packages and add usage note --- docs/narr/install.rst | 23 ++++++++++------------- docs/tutorials/bfg/index.rst | 2 +- docs/tutorials/modwsgi/index.rst | 2 +- docs/tutorials/wiki2/installation.rst | 6 +++--- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index 15e9e8699..d193cbab3 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -256,7 +256,7 @@ you can then create a virtual environment. To do so, invoke the following: .. code-block:: text $ export VENV=~/env - $ virtualenv --no-site-packages $VENV + $ virtualenv $VENV New python executable in /home/foo/env/bin/python Installing setuptools.............done. @@ -267,17 +267,14 @@ it's an absolute path. .. warning:: - Using ``--no-site-packages`` when generating your virtualenv is *very - important*. This flag provides the necessary isolation for running the set - of packages required by :app:`Pyramid`. If you do not specify - ``--no-site-packages``, it's possible that :app:`Pyramid` will not install - properly into the virtualenv, or, even if it does, may not run properly, - depending on the packages you've already got installed into your Python's - "main" site-packages dir. + ``--no-site-packages`` is now the default for virtualenv and can be + omitted. Do not override the default and use ``--system-site-packages`` + unless you know what you are doing. -.. warning:: *do not* use ``sudo`` to run the - ``virtualenv`` script. It's perfectly acceptable (and desirable) to create - a virtualenv as a normal user. +.. warning:: + + *do not* use ``sudo`` to run the ``virtualenv`` script. It's perfectly + acceptable (and desirable) to create a virtualenv as a normal user. Installing :app:`Pyramid` Into the Virtual Python Environment @@ -343,9 +340,9 @@ You can use Pyramid on Windows under Python 2 or 3. c:\> set VENV=c:\env # modify the command according to the python version, e.g.: # for Python 2.7: - c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% + c:\> c:\Python27\Scripts\virtualenv %VENV% # for Python 3.3: - c:\> c:\Python33\Scripts\virtualenv --no-site-packages %VENV% + c:\> c:\Python33\Scripts\virtualenv %VENV% You can either follow the use of the environment variable, ``%VENV%``, or replace it with the root directory of the :term:`virtualenv`. In that case, diff --git a/docs/tutorials/bfg/index.rst b/docs/tutorials/bfg/index.rst index a50637279..1abb26466 100644 --- a/docs/tutorials/bfg/index.rst +++ b/docs/tutorials/bfg/index.rst @@ -60,7 +60,7 @@ Here's how to convert a :mod:`repoze.bfg` application to a .. code-block:: bash $ cd ~ - $ virtualenv --no-site-packages pyramidenv + $ virtualenv pyramidenv $ cd pyramidenv $ $VENV/bin/easy_install pyramid diff --git a/docs/tutorials/modwsgi/index.rst b/docs/tutorials/modwsgi/index.rst index e0021f8db..ddd968927 100644 --- a/docs/tutorials/modwsgi/index.rst +++ b/docs/tutorials/modwsgi/index.rst @@ -46,7 +46,7 @@ specific path information for commands and files. $ cd ~ $ mkdir modwsgi $ cd modwsgi - $ /usr/local/bin/virtualenv --no-site-packages env + $ /usr/local/bin/virtualenv env #. Install :app:`Pyramid` into the newly created virtualenv: diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst index 17788cdde..e21bf7108 100644 --- a/docs/tutorials/wiki2/installation.rst +++ b/docs/tutorials/wiki2/installation.rst @@ -26,7 +26,7 @@ On UNIX .. code-block:: text $ export VENV=~/pyramidtut - $ virtualenv --no-site-packages $VENV + $ virtualenv $VENV New python executable in /home/foo/env/bin/python Installing setuptools.............done. @@ -46,13 +46,13 @@ Python 2.7: .. code-block:: text - c:\> c:\Python27\Scripts\virtualenv --no-site-packages %VENV% + c:\> c:\Python27\Scripts\virtualenv %VENV% Python 3.2: .. code-block:: text - c:\> c:\Python32\Scripts\virtualenv --no-site-packages %VENV% + c:\> c:\Python32\Scripts\virtualenv %VENV% Install Pyramid Into the Virtual Python Environment --------------------------------------------------- -- cgit v1.2.3 From b189a3ed0f44544687e68d0287417c42cd0fdca3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Aug 2013 01:51:59 -0700 Subject: Another crack at the note for venv options --- docs/narr/install.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/narr/install.rst b/docs/narr/install.rst index d193cbab3..fb67b899b 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -267,9 +267,11 @@ it's an absolute path. .. warning:: - ``--no-site-packages`` is now the default for virtualenv and can be - omitted. Do not override the default and use ``--system-site-packages`` - unless you know what you are doing. + Avoid using the ``--system-site-packages`` option when creating the + virtualenv unless you know what you are doing. For versions of virtualenv + prior to 1.7, make sure to use the ``--no-site-packages`` option, because + this option was formerly not the default and may produce undesirable + results. .. warning:: -- cgit v1.2.3 From 63bac441d95637a06d628bb8e8b9888eaf812c44 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 16 Aug 2013 04:47:34 -0700 Subject: One more "The Pyramid Web Application Development Framework" to "The Pyramid Web Framework" change --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 4c6ed76ad..3a8076cdf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -403,7 +403,7 @@ latex_elements = { 'wrapperclass': 'book', 'date': '', 'releasename': 'Version', - 'title': r'The Pyramid Web Application \newline Development Framework', + 'title': r'The Pyramid Web Framework', # 'pointsize':'12pt', # uncomment for 12pt version } -- cgit v1.2.3 From 00a08a307574b231a5a8c1142bc675732a03632b Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Fri, 16 Aug 2013 14:26:57 +0200 Subject: add custom tox config that creates a development environment --- HACKING.txt | 22 ++++++++++++++++++++-- hacking-tox.ini | 25 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 hacking-tox.ini diff --git a/HACKING.txt b/HACKING.txt index 5b5dcc458..563903f2f 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -16,13 +16,31 @@ checkout. - Check out a read-only copy of the Pyramid source:: - $ git clone git://github.com/Pylons/pyramid.git + $ git clone git://github.com/Pylons/pyramid.git . (alternately, create a writeable fork on GitHub and check that out). +Since pyramid is a framework and not an application, it can be +convenient to work against a sample application, preferably in its +own virtualenv. A quick way to achieve this is to (ab-)use ``tox`` +with a custom configuration file that's part of the checkout:: + + tox -c hacking-tox.ini + +This will create a python-2.7 based virtualenv named ``env27`` (pyramid's +``.gitconfig` ignores all top-level folders that start with ``env`` specifically +for this use case) and inside that a simple pyramid application named +``hacking`` that you can then fire up like so:: + + cd env27/hacking + ../bin/pserve development.ini + +Alternatively, if you don't want to install ``tox`` at this point, +you an achieve the same manually by following these steps: + - Create a virtualenv in which to install Pyramid:: - $ virtualenv2.6 --no-site-packages env + $ virtualenv --no-site-packages env - Install ``setuptools-git`` into the virtualenv (for good measure, as we're using git to do version control):: diff --git a/hacking-tox.ini b/hacking-tox.ini new file mode 100644 index 000000000..9520b7aef --- /dev/null +++ b/hacking-tox.ini @@ -0,0 +1,25 @@ +[tox] +envlist = + env27,ttw27-create,ttw27-install + +[testenv:env27] +envdir = env27 +basepython = python2.7 +usedevelop = True +deps = setuptools-git +commands = + python setup.py dev + +[testenv:ttw27-create] +envdir = env27 +usedevelop = True +changedir = env27 +commands = + pcreate -s starter hacking + +[testenv:ttw27-install] +envdir = env27 +usedevelop = True +changedir = env27/hacking +commands = + python setup.py develop -- cgit v1.2.3 From 7a2df29602b207954a4d00fae4556f57ed3675e1 Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Fri, 16 Aug 2013 16:42:08 +0200 Subject: add info how to run the tests using pytest (http://pytest.org/) --- HACKING.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/HACKING.txt b/HACKING.txt index 563903f2f..87538d0ad 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -128,6 +128,13 @@ Running Tests $ cd ~/hack-on-pyramid/pyramid $ /usr/bin/tox +- The tests can also be run usign ``pytest`` (http://pytest.org/). This is + intended as a convenience for people who are more used or fond of ``pytest``. + Run the tests like so:: + + $ pip install pytest + $ py.test --strict pyramid/ + Test Coverage ------------- -- cgit v1.2.3 From 852e015f9b3864b0c07569a9753c4107b8d1238a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 16 Aug 2013 09:48:19 -0500 Subject: recommend easy_install until we don't --- HACKING.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HACKING.txt b/HACKING.txt index 87538d0ad..5d33aa0ab 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -40,7 +40,7 @@ you an achieve the same manually by following these steps: - Create a virtualenv in which to install Pyramid:: - $ virtualenv --no-site-packages env + $ virtualenv env - Install ``setuptools-git`` into the virtualenv (for good measure, as we're using git to do version control):: @@ -132,7 +132,7 @@ Running Tests intended as a convenience for people who are more used or fond of ``pytest``. Run the tests like so:: - $ pip install pytest + $ $VENV/bin/easy_install pytest $ py.test --strict pyramid/ Test Coverage -- cgit v1.2.3 From 4448c35f820a0cd66720ab15c2384536f1173a46 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Fri, 16 Aug 2013 16:37:21 -0400 Subject: updated sphinx theme --- docs/_themes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_themes b/docs/_themes index 8673c4a14..de373ecb2 160000 --- a/docs/_themes +++ b/docs/_themes @@ -1 +1 @@ -Subproject commit 8673c4a14f192c15f1949dc9862821e60f31604a +Subproject commit de373ecb24eb7ecb65970a26dd6c4cd728749a85 -- cgit v1.2.3 From f6ea2275f927e88d43fb2d105bce33d0ece0df16 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Fri, 16 Aug 2013 18:50:47 -0400 Subject: updated sphinx theme --- docs/_themes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_themes b/docs/_themes index de373ecb2..a181b85d4 160000 --- a/docs/_themes +++ b/docs/_themes @@ -1 +1 @@ -Subproject commit de373ecb24eb7ecb65970a26dd6c4cd728749a85 +Subproject commit a181b85d4ca08fa109ee2786d4f1b5b17e9b4589 -- cgit v1.2.3 From a5a8019b62ddc2f73a16799ac3107e22446a4c08 Mon Sep 17 00:00:00 2001 From: adroullier Date: Sat, 17 Aug 2013 11:56:59 +0200 Subject: copy_dir() recursive overwrite fix --- pyramid/scaffolds/copydir.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyramid/scaffolds/copydir.py b/pyramid/scaffolds/copydir.py index ba0988523..7864dd1a1 100644 --- a/pyramid/scaffolds/copydir.py +++ b/pyramid/scaffolds/copydir.py @@ -90,16 +90,16 @@ def copy_dir(source, dest, vars, verbosity, simulate, indent=0, if verbosity: out('%sRecursing into %s' % (pad, os.path.basename(full))) copy_dir((source[0], full), dest_full, vars, verbosity, simulate, - indent=indent+1, - sub_vars=sub_vars, interactive=interactive, + indent=indent+1, sub_vars=sub_vars, + interactive=interactive, overwrite=overwrite, template_renderer=template_renderer, out_=out_) continue elif not use_pkg_resources and os.path.isdir(full): if verbosity: out('%sRecursing into %s' % (pad, os.path.basename(full))) copy_dir(full, dest_full, vars, verbosity, simulate, - indent=indent+1, - sub_vars=sub_vars, interactive=interactive, + indent=indent+1, sub_vars=sub_vars, + interactive=interactive, overwrite=overwrite, template_renderer=template_renderer, out_=out_) continue elif use_pkg_resources: -- cgit v1.2.3 From c138ce30a60199e1a82b2b4d5fbf1faaf9db9e70 Mon Sep 17 00:00:00 2001 From: adroullier Date: Sat, 17 Aug 2013 11:58:02 +0200 Subject: copy_dir() recursive overwrite test updates --- pyramid/tests/test_scaffolds/test_copydir.py | 47 ++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/pyramid/tests/test_scaffolds/test_copydir.py b/pyramid/tests/test_scaffolds/test_copydir.py index d757b837c..1e92b3c36 100644 --- a/pyramid/tests/test_scaffolds/test_copydir.py +++ b/pyramid/tests/test_scaffolds/test_copydir.py @@ -103,16 +103,57 @@ class Test_copy_dir(unittest.TestCase): 1, False, overwrite=False, template_renderer=dummy_template_renderer) - target = os.path.join(self.dirname, 'mypackage', '__init__.py') - with open(target, 'w') as f: - f.write('These are not the words you are looking for.') + # toplevel file + toplevel = os.path.join(self.dirname, 'mypackage', '__init__.py') + with open(toplevel, 'w') as f: + f.write('These are the words you are looking for.') + # sub directory file + sub = os.path.join(self.dirname, 'mypackage', 'templates', 'mytemplate.pt') + with open(sub, 'w') as f: + f.write('These are the words you are looking for.') self._callFUT(source, self.dirname, vars, 1, False, overwrite=False, template_renderer=dummy_template_renderer) + with open(toplevel, 'r') as f: + tcontent = f.read() + self.assertEqual('These are the words you are looking for.', tcontent) + with open(sub, 'r') as f: + tcontent = f.read() + self.assertEqual('These are the words you are looking for.', tcontent) + def test_overwrite_true(self): + vars = {'package':'mypackage'} + source = pkg_resources.resource_filename(*self.fixturetuple) + self._callFUT(source, + self.dirname, + vars, + 1, False, + overwrite=True, + template_renderer=dummy_template_renderer) + # toplevel file + toplevel = os.path.join(self.dirname, 'mypackage', '__init__.py') + with open(toplevel, 'w') as f: + f.write('These are not the words you are looking for.') + # sub directory file + sub = os.path.join(self.dirname, 'mypackage', 'templates', 'mytemplate.pt') + with open(sub, 'w') as f: + f.write('These are not the words you are looking for.') + self._callFUT(source, + self.dirname, + vars, + 1, False, + overwrite=True, + template_renderer=dummy_template_renderer) + with open(toplevel, 'r') as f: + tcontent = f.read() + self.assertNotEqual('These are not the words you are looking for.', tcontent) + with open(sub, 'r') as f: + tcontent = f.read() + self.assertNotEqual('These are not the words you are looking for.', tcontent) + def test_detect_SkipTemplate(self): vars = {'package':'mypackage'} source = pkg_resources.resource_filename(*self.fixturetuple) -- cgit v1.2.3 From c614ffc153135eb14d77472a46c20af7c6f6ed91 Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 11:48:58 +0200 Subject: add ``localizer`` property to the request (refs #508) --- CHANGES.txt | 3 +++ pyramid/i18n.py | 17 +++++++---------- pyramid/request.py | 8 ++++++++ pyramid/tests/test_i18n.py | 17 +++++++++++++++++ 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 48efad6d4..b805a12a0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,9 @@ Next Release Features -------- +- Add ``localizer`` property (reified) to the request. + See https://github.com/Pylons/pyramid/issues/508. + - Add ``pdistreport`` script, which prints the Python version in use, the Pyramid version in use, and the version number and location of all Python distributions currently installed. diff --git a/pyramid/i18n.py b/pyramid/i18n.py index b4bc0eaa7..dc2c25f18 100644 --- a/pyramid/i18n.py +++ b/pyramid/i18n.py @@ -197,17 +197,15 @@ def make_localizer(current_locale_name, translation_directories): def get_localizer(request): """ Retrieve a :class:`pyramid.i18n.Localizer` object corresponding to the current request's locale name. """ - localizer = getattr(request, 'localizer', None) - if localizer is None: - # no locale object cached on request - try: - registry = request.registry - except AttributeError: - registry = get_current_registry() + # no locale object cached on request + try: + registry = request.registry + except AttributeError: + registry = get_current_registry() - current_locale_name = get_locale_name(request) - localizer = registry.queryUtility(ILocalizer, name=current_locale_name) + current_locale_name = get_locale_name(request) + localizer = registry.queryUtility(ILocalizer, name=current_locale_name) if localizer is None: # no localizer utility registered yet @@ -216,7 +214,6 @@ def get_localizer(request): registry.registerUtility(localizer, ILocalizer, name=current_locale_name) - request.localizer = localizer return localizer diff --git a/pyramid/request.py b/pyramid/request.py index 5bca5b1f0..5dedee4f1 100644 --- a/pyramid/request.py +++ b/pyramid/request.py @@ -24,6 +24,7 @@ from pyramid.compat import ( ) from pyramid.decorator import reify +from pyramid.i18n import get_localizer from pyramid.response import Response from pyramid.url import URLMethodsMixin from pyramid.util import InstancePropertyMixin @@ -383,6 +384,13 @@ class Request(BaseRequest, DeprecatedRequestMethodsMixin, URLMethodsMixin, def json_body(self): return json.loads(text_(self.body, self.charset)) + @reify + def localizer(self): + """ Convenience property to return a localizer by calling + :func:`pyramid.i18n.get_localizer`. """ + return get_localizer(self) + + def route_request_iface(name, bases=()): # zope.interface treats the __name__ as the __doc__ and changes __name__ # to None for interfaces that contain spaces if you do not pass a diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index bd4998b10..4b4022dbc 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -292,6 +292,23 @@ class Test_get_localizer(unittest.TestCase): self.assertEqual(result.translate('Approve', 'deformsite'), 'Approve') + def test_request_has_localizer(self): + from pyramid.threadlocal import get_current_registry + from pyramid.interfaces import ILocalizer + from pyramid.request import Request + # register mock localizer + dummy = object() + registry = get_current_registry() + registry.registerUtility(dummy, ILocalizer, name='en') + request = Request(environ={}) + self.assertEqual(request.localizer, dummy) + # `get_localizer` is only called once... + other = object() + registry.registerUtility(other, ILocalizer, name='en') + self.assertNotEqual(request.localizer, other) + self.assertEqual(request.localizer, dummy) + + class Test_default_locale_negotiator(unittest.TestCase): def setUp(self): cleanUp() -- cgit v1.2.3 From dbe2dcbbed98e0fbfce195d8a6564dc296d0de89 Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:12:41 +0200 Subject: remove duplicate of `Test_get_locale_name.test_name_on_request` --- pyramid/tests/test_i18n.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index 4b4022dbc..be105495d 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -245,12 +245,6 @@ class Test_get_localizer(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, '123') - def test_locale_on_request(self): - request = DummyRequest() - request.localizer = 'abc' - result = self._callFUT(request) - self.assertEqual(result, 'abc') - def test_locale_from_registry(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer -- cgit v1.2.3 From 1e83584f47b9a584fa9624bbcac92134a926297d Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:14:45 +0200 Subject: test the default localizer --- pyramid/tests/test_i18n.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index be105495d..2ae70234c 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -230,6 +230,14 @@ class Test_get_localizer(unittest.TestCase): from pyramid.i18n import get_localizer return get_localizer(request) + def test_default_localizer(self): + # `get_localizer` returns a default localizer for `en` + from pyramid.i18n import Localizer + request = DummyRequest() + result = self._callFUT(request) + self.assertEqual(result.__class__, Localizer) + self.assertEqual(result.locale_name, 'en') + def test_no_registry_on_request(self): request = DummyRequest() request.localizer = '123' -- cgit v1.2.3 From 85448c73ccca42a0d4ef1318433acdbbb21328ce Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:16:38 +0200 Subject: test a custom localizer --- pyramid/tests/test_i18n.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index 2ae70234c..e43c642be 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -238,11 +238,15 @@ class Test_get_localizer(unittest.TestCase): self.assertEqual(result.__class__, Localizer) self.assertEqual(result.locale_name, 'en') - def test_no_registry_on_request(self): + def test_custom_localizer(self): + from pyramid.threadlocal import get_current_registry + from pyramid.interfaces import ILocalizer + registry = get_current_registry() + dummy = object() + registry.registerUtility(dummy, ILocalizer, name='en') request = DummyRequest() - request.localizer = '123' result = self._callFUT(request) - self.assertEqual(result, '123') + self.assertEqual(result, dummy) def test_with_registry_on_request(self): from pyramid.threadlocal import get_current_registry -- cgit v1.2.3 From 186c2b8b9f2c259ccb264982b2433081ca26e3bf Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:17:17 +0200 Subject: remove test that explicitly sets a registry on the request outside tests the router puts the registry on the request, but in tests it sometimes needs to exist as well. however, it doesn't make sense to test something that's only done in tests anyway --- pyramid/tests/test_i18n.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index e43c642be..58af96493 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -248,15 +248,6 @@ class Test_get_localizer(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, dummy) - def test_with_registry_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = DummyRequest() - request.localizer = '123' - request.registry = registry - result = self._callFUT(request) - self.assertEqual(result, '123') - def test_locale_from_registry(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer -- cgit v1.2.3 From 0064eb70d5b30507b65c05271fe12a2697f88d05 Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:21:50 +0200 Subject: don't use the default locale when testing custom localizer also, use an object as a dummy localizer for better readability --- pyramid/tests/test_i18n.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index 58af96493..b583d1468 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -252,12 +252,12 @@ class Test_get_localizer(unittest.TestCase): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer registry = get_current_registry() - locale = 'abc' - registry.registerUtility(locale, ILocalizer, name='en') + dummy = object() + registry.registerUtility(dummy, ILocalizer, name='ie') request = DummyRequest() - request.locale_name = 'en' + request.locale_name = 'ie' result = self._callFUT(request) - self.assertEqual(result, 'abc') + self.assertEqual(result, dummy) def test_locale_from_mo(self): from pyramid.threadlocal import get_current_registry -- cgit v1.2.3 From b3e9da039ddc3661874e815512475268b8a88ded Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:24:56 +0200 Subject: clean up test names --- pyramid/tests/test_i18n.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyramid/tests/test_i18n.py b/pyramid/tests/test_i18n.py index b583d1468..336e51b6a 100644 --- a/pyramid/tests/test_i18n.py +++ b/pyramid/tests/test_i18n.py @@ -238,7 +238,7 @@ class Test_get_localizer(unittest.TestCase): self.assertEqual(result.__class__, Localizer) self.assertEqual(result.locale_name, 'en') - def test_custom_localizer(self): + def test_custom_localizer_for_default_locale(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer registry = get_current_registry() @@ -248,7 +248,7 @@ class Test_get_localizer(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, dummy) - def test_locale_from_registry(self): + def test_custom_localizer_for_custom_locale(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ILocalizer registry = get_current_registry() @@ -259,7 +259,7 @@ class Test_get_localizer(unittest.TestCase): result = self._callFUT(request) self.assertEqual(result, dummy) - def test_locale_from_mo(self): + def test_localizer_from_mo(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ITranslationDirectories from pyramid.i18n import Localizer @@ -275,7 +275,7 @@ class Test_get_localizer(unittest.TestCase): self.assertEqual(result.translate('Approve'), 'Approve') self.assertTrue(hasattr(result, 'pluralize')) - def test_locale_from_mo_bad_mo(self): + def test_localizer_from_mo_bad_mo(self): from pyramid.threadlocal import get_current_registry from pyramid.interfaces import ITranslationDirectories from pyramid.i18n import Localizer -- cgit v1.2.3 From c70dcb392b07859c7c75ce20ddedc16b961692ea Mon Sep 17 00:00:00 2001 From: Andreas Zeidler Date: Sat, 17 Aug 2013 12:32:04 +0200 Subject: done :) --- TODO.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/TODO.txt b/TODO.txt index 7a3561494..46eb33b82 100644 --- a/TODO.txt +++ b/TODO.txt @@ -56,9 +56,6 @@ Nice-to-Have app1" and "domain app1.localhost = app1"), ProxyPreserveHost and the nginx equivalent, preserving HTTPS URLs. -- Make "localizer" a property of request (instead of requiring - "get_localizer(request)"? - - Alias the stupid long default session factory name. - Debug option to print view matching decision (e.g. debug_viewlookup or so). -- cgit v1.2.3 From 68d2a8cf14b940ffac796be663baeb0782640310 Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Sat, 17 Aug 2013 16:08:43 +0200 Subject: provide the tox url when mentioning it first. --- HACKING.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/HACKING.txt b/HACKING.txt index 563903f2f..2e444e781 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -23,7 +23,8 @@ checkout. Since pyramid is a framework and not an application, it can be convenient to work against a sample application, preferably in its own virtualenv. A quick way to achieve this is to (ab-)use ``tox`` -with a custom configuration file that's part of the checkout:: +(http://codespeak.net/~hpk/tox/) with a custom configuration file that's part of +the checkout:: tox -c hacking-tox.ini -- cgit v1.2.3 From 98b383ef54d16c977561101dde1addd34ba34240 Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Sat, 17 Aug 2013 16:09:58 +0200 Subject: adjust the checkout path to the new value set above in a previous commit --- HACKING.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING.txt b/HACKING.txt index 2e444e781..d664d6bfc 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -126,7 +126,7 @@ Running Tests example:: $ /usr/bin/easy_install tox - $ cd ~/hack-on-pyramid/pyramid + $ cd ~/hack-on-pyramid/ $ /usr/bin/tox Test Coverage -- cgit v1.2.3 From 50f23dd4fb2ea8690893ac2cf20a0f0483b32a0d Mon Sep 17 00:00:00 2001 From: Tom Lazar Date: Sat, 17 Aug 2013 16:10:45 +0200 Subject: include and mention the `nose-selecttests `_ plugin --- HACKING.txt | 10 +++++++--- setup.py | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/HACKING.txt b/HACKING.txt index d664d6bfc..0d28905b6 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -112,9 +112,13 @@ Coding Style Running Tests -------------- -- To run tests for Pyramid on a single Python version, run ``python setup.py - test`` against the Python interpreter from virtualenv into which - you've ``setup.py develop``-ed Pyramid. +- To run all tests for Pyramid on a single Python version, run ``nosetests`` from + your development virtualenv (See *Using a Development Checkout* above). + +- To run individual tests (i.e. during development) you can use a regular + expression with the ``-t`` parameter courtesy of the `nose-selecttests + `_ plugin that's been installed (along with nose itself) via ``python setup.py dev``. The easiest usage is to + simply provide the verbatim name of the test you're working on. - To run the full set of Pyramid tests on all platforms, install ``tox`` (http://codespeak.net/~hpk/tox/) into a system Python. The ``tox`` console diff --git a/setup.py b/setup.py index 60b20b069..64e63956e 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,7 @@ docs_extras = [ testing_extras = tests_require + [ 'nose', + 'nose-selecttests', 'coverage', 'virtualenv', # for scaffolding tests ] -- cgit v1.2.3 From ffdc8cbde4fa77d55f159c4c085e0b51f8029674 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 18 Aug 2013 15:02:23 -0700 Subject: no HTML smartypants! Fix https://github.com/Pylons/pyramid/issues/669 --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 3a8076cdf..b6ddacea9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -221,7 +221,7 @@ html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +html_use_smartypants = False # Custom sidebar templates, maps document names to template names. #html_sidebars = {} -- cgit v1.2.3 From 4aec433291dc7b0c08d27fe6352ecf7585052e73 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Aug 2013 00:45:10 +0200 Subject: explain --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index b6ddacea9..a7a4a441a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -221,7 +221,7 @@ html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -html_use_smartypants = False +html_use_smartypants = False # people use cutnpaste in some places # Custom sidebar templates, maps document names to template names. #html_sidebars = {} -- cgit v1.2.3 From e64e71523d70261b551ba41f13f389ebf1324f1b Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 19 Aug 2013 23:30:49 -0500 Subject: remove mention of unused http status code --- pyramid/httpexceptions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyramid/httpexceptions.py b/pyramid/httpexceptions.py index c21a717f8..d8832570b 100644 --- a/pyramid/httpexceptions.py +++ b/pyramid/httpexceptions.py @@ -28,7 +28,6 @@ Exception * 303 - HTTPSeeOther * 304 - HTTPNotModified * 305 - HTTPUseProxy - * 306 - Unused (not implemented, obviously) * 307 - HTTPTemporaryRedirect HTTPError HTTPClientError -- cgit v1.2.3