Merge remote-tracking branch 'origin/master'

This commit is contained in:
Jonathan LaCour
2011-09-02 12:59:12 -04:00
11 changed files with 163 additions and 188 deletions

View File

View File

@@ -26,7 +26,16 @@ By default, this module contains a special method, ``init_model``::
from pecan import conf
def init_model():
# Read and parse database bindings from pecan.conf
"""
This is a stub method which is called at application startup time.
If you need to bind to a parse database configuration, set up tables or
ORM classes, or perform any database initialization, this is the
recommended place to do it.
For more information working with databases, and some common recipes,
see http://pecan.readthedocs.org/en/latest/databases.html
"""
pass
The purpose of this method is to determine bindings from your configuration file and create
@@ -91,7 +100,7 @@ Binding Within the Application
There are several approaches that can be taken to wrap your application's requests with calls
to appropriate model function calls. One approach is WSGI middleware. We also recommend
Pecan :ref:`hooks`. Pecan comes with ``TransactionHook``, a hook which can
be used to wrap requests in transactions for you. To use it, simply include it in your
be used to wrap requests in database transactions for you. To use it, simply include it in your
project's ``app.py`` file and pass it a set of functions related to database binding::
from pecan import conf, make_app

View File

@@ -0,0 +1,4 @@
.. _deployment:
Deployment Recipes
=============

View File

@@ -63,10 +63,8 @@ tutorial on App Engine.
app_engine.rst
sessions.rst
celery.rst
databases.rst
deployment.rst
reporting.rst
API Documentation

View File

@@ -3,40 +3,40 @@
Installation
============
.. warning::
This section is out of date. Please do not refer to it directly.
Stable Version
------------------------------
We recommend installing Pecan with ``pip`` but you can also try with
``easy_install`` and ``virtualenv``. Creating a spot in your environment where
Pecan can be isolated from other packages is best practice.
To get started with an environment for Pecan, create a virtual environment for
it without any site-packages that might pollute::
To get started with an environment for Pecan, create a new
`virtual environment <http://www.virtualenv.org>`_::
virtualenv --no-site-packages pecan-env
cd pecan-env
source bin/activate
The above commands created a virtual environment and *activated* it. Those
actions will encapsulate anything that we do with the framework, making it
easier to debug problems if needed.
The above commands create a virtual environment and *activate* it. Those
actions will encapsulate any dependency installations for the framework,
making it easier to debug problems if needed.
But we do not have Pecan yet, so let's grab it from PYPI::
Next, let's install Pecan::
pip install pecan
After a lot of output, you should have Pecan successfully installed and ready
to use.
After a lot of output, you should have Pecan successfully installed.
Development (Unstable) Version
------------------------------
If you want to run the development version of Pecan you will
need GIT installed and clone the repo from github::
need to install git and clone the repo from github::
git clone https://github.com/pecan/pecan.git
If you are still in the *pecan-dev* virtual environment that we created before,
you should call ``setup.py`` to install::
If your virtual environment is still activated, call ``setup.py`` to install
the development version::
cd pecan
python setup.py develop

View File

@@ -3,69 +3,33 @@
Quick Start
===========
Here we will cover the basics for a small project in Pecan. More advanced
examples and methods are not covered here.
Let's create a small sample project with Pecan.
.. note::
We will not cover how to get Pecan installed here. If you need installation
details please go to :ref:`installation` which includes the recommended way
of setting up a proper development environment.
This guide does not cover the installation of Pecan. If you need
instructions for installing Pecan, go to :ref:`installation`.
Base Application Template
-------------------------
We include a basic template to have a good layout for a Pecan project. This is
accomplished by the ``pecan`` command line script bundled with the framework.
Invoking the command to create a project is trivial::
A basic template for getting started is included with Pecan. From
your shell, type::
$ pecan create -t base
$ pecan create
The above command will prompt you for a project name. I chose *test_project*,
but you can also provided as an argument at the end of the example command
above, like::
$ pecan create -t base test_project
$ pecan create test_project
This is how it looks like when we run the whole command::
Go ahead and change into your newly created project directory::
$ pecan create -t base
Selected and implied templates:
pecan#pecan-base Template for creating a basic Framework package
$ cd test_project
$ ls
Enter project name: test_project
Variables:
egg: test_project
package: test_project
project: test_project
Creating template pecan-base
Creating directory ./test_project
Recursing into +egg+
Creating ./test_project/test_project/
Copying __init__.py to ./test_project/test_project/__init__.py
Recursing into controllers
Creating ./test_project/test_project/controllers/
Copying __init__.py to ./test_project/test_project/controllers/__init__.py
Copying root.py to ./test_project/test_project/controllers/root.py
Recursing into model
Creating ./test_project/test_project/model/
Copying __init__.py to ./test_project/test_project/model/__init__.py
Recursing into templates
Creating ./test_project/test_project/templates/
Copying index.html to ./test_project/test_project/templates/index.html
Copying layout.html to ./test_project/test_project/templates/layout.html
Copying success.html to ./test_project/test_project/templates/success.html
Recursing into public
Creating ./test_project/public/
Recursing into css
Creating ./test_project/public/css/
Copying style.css to ./test_project/public/css/style.css
Recursing into javascript
Creating ./test_project/public/javascript/
Copying shared.js to ./test_project/public/javascript/shared.js
This is how the structure of your new project should look like::
This is how the layout of your new project should look::
├── MANIFEST.in
├── config.py
@@ -74,77 +38,67 @@ This is how the structure of your new project should look like::
│   │   └── style.css
│   └── javascript
│   └── shared.js
├── setup.cfg
├── setup.py
── test_project
   ├── __init__.py
   ├── app.py
   ├── controllers
   │   ├── __init__.py
   │   └── root.py
   ├── model
   │   └── __init__.py
   ├── templates
   │   ├── error.html
   │   ├── index.html
   │   ├── layout.html
   │   └── success.html
   └── tests
   ├── __init__.py
   ├── test_config.py
   └── test_root.py
└── test_project.egg-info
├── PKG-INFO
├── SOURCES.txt
├── dependency_links.txt
├── not-zip-safe
├── paster_plugins.txt
├── requires.txt
└── top_level.txt
── test_project
   ├── __init__.py
   ├── app.py
   ├── controllers
   │   ├── __init__.py
   │   └── root.py
   ├── model
   │   └── __init__.py
   ├── templates
   │   ├── error.html
   │   ├── index.html
   │   ├── layout.html
   │   └── success.html
   └── tests
   ├── __init__.py
   ├── test_config.py
   └── test_root.py
9 directories, 25 files
The amount of files and directories may vary, but the above structure should
give you an idea of what you should expect.
The amount of files and directories may vary from time to time, but the above
structure should give you an idea of what you should expect.
A few things have been created for you, so let's review them one by one:
A few things have been set for you, let's review them one by one:
* **public**: All your public static files like CSS and Javascript are placed
here. If you have some images (this example app doesn't) it would make sense
to get them here as well.
* **public**: All your static files (like CSS and Javascript) live here. If you
have any images (this example app doesn't) they would live here too.
Inside the project name you chose you have a few directories, and for the
most part, it will contain your models, controllers and templates:
The remaining directories encompass your models, controllers and templates, and
tests:
* **controllers**: The container directory for your controller files.
* **templates**: All your templates would go in here.
* **model**: Container for your model files.
* **tests**: All your application test files.
* **test_project/controllers**: The container directory for your controller files.
* **test_project/templates**: All your templates go in here.
* **test_project/model**: Container for your model files.
* **test_project/tests**: All of the tests for your application.
To avoid unneeded dependencies and to remain as flexible as possible, Pecan doesn't impose any database or
ORM (Object Relational Mapper) out of the box. You may notice that **model/__init__.py** is mostly empty.
Its contents generally contain any code necessary to define tables, ORM definitions, and parse bindings from
your configuration file.
To avoid unneeded dependencies and to remain as flexible as possible, Pecan
doesn't impose any database or ORM (Object Relational Mapper) out of the box.
You may notice that **model/__init__.py** is mostly empty. You may wish to add
code here to define tables, ORM definitions, and parse bindings from your
configuration file.
.. note::
With your base project you also got some ready-to-run tests. Try running
``py.test`` (the recommended test runner for Pecan) and see them passing!
The base project contains some ready-to-run tests. Try running
``py.test`` (the recommended test runner for Pecan) and watch them pass!
.. _running_application:
Running the application
-----------------------
The most important file to run your application is your configuration file, the
base project template should have created one for you already and it should be
named ``config.py``.
Before starting up your Pecan app, you'll need a configuration file. The
base project template should have created one for you already, ``config.py``.
This file already contains the necessary information to run a Pecan app, like
ports, static paths and so forth.
If you just run ``pecan serve`` passing ``config.py`` as an argument for
configuration it will bring up the development server and serve the app::
If you just run ``pecan serve``, passing ``config.py`` as an argument for
configuration, it will bring up the development server and serve the app::
$ pecan serve config.py
Starting subprocess with file monitor
@@ -152,27 +106,15 @@ configuration it will bring up the development server and serve the app::
serving on 0.0.0.0:8080 view at http://127.0.0.1:8080
To get up and running in no time the template helps a lot!
.. note::
If you fail to pass an argument you will get a small error message asking
for a configuration file.
The location for the config file and the argument itself are very flexible. You
can pass an absolute path or just the name of the file without an extension,
like::
$ pecan serve config
The location for the config file and the argument itself are very flexible -
you can pass an absolute or relative path to the file.
Simple Configuration
--------------------
We mentioned that you get a Python file with some configurations. The only
Python syntax that you will see is the first line that imports the
RootController that is in turn placed as the application root. Everything else,
including possible custom configurations are set as Python dictionaries.
For ease of use, Pecan configuration files are pure Python.
This is how your default configuration file should look like::
This is how your default configuration file should look::
from test_project.controllers.root import RootController
@@ -188,8 +130,8 @@ This is how your default configuration file should look like::
app = {
'root' : RootController(),
'modules' : [test_project],
'static_root' : 'public',
'template_path' : 'test_project/templates',
'static_root' : '%(confdir)s/public',
'template_path' : '%(confdir)s/test_project/templates',
'reload': True,
'debug' : True,
'errors' : {
@@ -206,28 +148,21 @@ This is how your default configuration file should look like::
# pecan.conf
.. note::
If you named your project something other than *test_project*
you should see that same name above instead.
**Nothing** in the configuration file above is actually required for Pecan to
be able to run. If you fail to provide some values Pecan will fill in the
missing things it needs to run.
run. If you fail to provide some values, Pecan will fill in the missing things
it needs to run.
You also get the ability to set your own configurations as dictionaries and you
get a commented out example on how to do that.
You can also add your own configuration as dictionaries.
We are not going to explain much more about configuration here, if you need
more specific details, go to the :ref:`Configuration` section.
For more specific documentation on configuration, see the :ref:`Configuration`
section.
Root Controller
---------------
The Root Controller is the main point of contact between your application and
the framework.
The Root Controller is the root of your application.
This is how it looks from the project template::
This is how it looks in the project template::
from pecan import expose, request
from formencode import Schema, validators as v
@@ -259,35 +194,33 @@ This is how it looks from the project template::
Here you can specify other classes if you need to do so later on your project,
but for now we have an *index* method and a *handle_form* one.
You can specify additional classes if you need to do so, but for now we have an
*index* and *handle_form* method.
**index**: Is *exposed* via the decorator ``@expose`` (that in turn uses the
``index.html`` file) as the root of the application, so anything that hits
the root of you application will touch this method.
**index**: is *exposed* via the decorator ``@expose`` (which in turn uses the
``index.html`` template) at the root of the application (http://127.0.0.1:8080/),
so anything that hits the root of your application will touch this method.
What your index method returns is a dictionary that is received by the template
engine and translated into valid HTML.
Notice that the index method returns a dictionary - this dictionary is used as
a namespace to render the specified template (``index.html``) into HTML.
Since we are doing some validation and want to pass any errors we might get to
the template, we set ``errors`` to receive anything that
``request.validation_errors`` returns.
Since we are performing form validation and want to pass any errors we might
get to the template, we set ``errors`` to receive form validation errors that
may exist in ``request.validation_errors``.
**handle_form**: It receives 2 arguments (*name* and *age*) that are validated
through the *SampleForm* schema class.
**handle_form**: receives 2 arguments (*name* and *age*) that are validated
through the *SampleForm* schema.
The ``error_handler`` has been set to index, this means that when errors are raised
they will be sent to the index controller so it returns them to the template.
The ``error_handler`` has been set to index. This means that when errors are
raised, they will be sent to the index controller and rendered through its
template.
**error**: Finally, we have the error controller that allows you application to
custom display any possible errors that you might want to display.
**error**: Finally, we have the error controller that allows your application to
display custom pages for certain HTTP errors (404, etc...).
Application Interaction
-----------------------
If you still have your application running and you visit your browser, you should
see a nice page with some information about Pecan and a form so you can play a bit
with.
This is very basic but it will give you the grounds necessary to build your application
and understand some of the features the framework packs.
If you still have your application running and you visit it in your browser,
you should see a page with some information about Pecan and a form so you can
play a bit.

View File

@@ -0,0 +1,36 @@
.. _session:
Working with Sessions and User Authentication
=============
Out of the box, Pecan provides no opinionated support for managing user sessions,
but it's easy to hook into your session framework of choice with minimal
effort.
This article details best practices for integrating the popular session
framework, `Beaker <http://beaker.groovie.org>`_, into your Pecan project.
Setting up Session Management
----------------
There are several approaches that can be taken to set up session management.
One approach is WSGI middleware. Another is Pecan :ref:`hooks`.
Here's an example of wrapping your WSGI application with Beaker's
``SessionMiddleware`` in your project's `app.py`::
from pecan import conf, make_app
from beaker import SessionMiddleware
from test_project import model
app = make_app(
...
)
app = SessionMiddleware(app, conf.beaker)
...and a corresponding dictionary in your configuration file::
beaker = {
'session.key' : 'sessionkey',
'session.type' : 'cookie',
'session.validate_key' : '05d2175d1090e31f42fa36e63b8d2aad',
'__force_dict__' : True
}

View File

@@ -175,9 +175,6 @@ def import_module(conf):
:param conf: The string to the configuration. Automatically strips off ".py" file extensions.
'''
if conf.endswith('.py'):
conf = conf[:-3]
if '.' in conf:
parts = conf.split('.')
name = '.'.join(parts[:-1])
@@ -207,15 +204,12 @@ def initconf():
def set_config(name):
'''
Updates the global configuration from a path or filename.
Updates the global configuration a filename.
:param name: Path or filename, as a string.
:param name: filename, as a string.
'''
if '/' in name:
_runtime_conf.update(conf_from_file(name))
else:
_runtime_conf.update_with_module(name)
_runtime_conf.update(conf_from_file(name))
_runtime_conf = initconf()

View File

@@ -1,5 +1,14 @@
from pecan import conf
def init_model():
# Read and parse database bindings from pecan.conf
pass
"""
This is a stub method which is called at application startup time.
If you need to bind to a parse database configuration, set up tables or
ORM classes, or perform any database initialization, this is the
recommended place to do it.
For more information working with databases, and some common recipes,
see http://pecan.readthedocs.org/en/latest/databases.html
"""
pass

View File

@@ -108,14 +108,6 @@ class TestConf(TestCase):
configuration.set_config(path)
assert list(_runtime_conf.server) == list(configuration.initconf().server)
def test_config_set_from_module(self):
configuration.set_config('config')
self.assertEqual(_runtime_conf.server.host, '1.1.1.1')
def test_config_set_from_module_with_extension(self):
configuration.set_config('config.py')
self.assertEqual(_runtime_conf.server.host, '1.1.1.1')
def test_config_dir(self):
if sys.version_info >= (2, 6):
conf = configuration.Config({})