Pyxer 0.5.1
Yet another Python Framework
(C)opyright by Dirk Holtwick, Germany
dirk.holtwick@gmail.com
http://www.pyxer.net
The Pyxer Server is a very simple Python Web Framework that aims to makes starting a new project as easy as it can be. It still works respecting the MVC concept but the files can be mixed in one directory. For a high end solution you should consider using Pylons, TurboGears, Django and similar.
This work is inspired by <http://pythonpaste.org/webob/do-it-yourself.html>.
The Google App Engine (GAE) in version 1.1 offers a very restricted Python environment and the developer as to ship arround a lot of problems. Pyxer helps on this point by also providing solutions that work with the great WSGI Framework Paster by Ian Bicking. So you get the best from both sides: GAE and Paster. To achieve this some other great third party tools are used like WebOb and VirtualEnv (also by Ian Bicking) and for templating the html5lib is used.
Install Pyxer using easy_install:
$ easy_install pyxer
All required packages (webob, html5lib, beaker) should be installed automatically if needed.
If you want to use Google AppEngine install it separately too.
At first set up a new Pyxer project using the Pyxer command line tool like this:
$ pyxer init myexample
In the newly created directory "myexample" you will find a directory structure like this one (under Windows "bin" will be called "Scripts"):
bin/ public/ lib/
Place your files in the "public" directory.
To start the server you may choose between the Paster-Engine:
$ xpaster serve
or the GAE-Engine:
$ xgae serve
Or use Pyxer command line tool again to use the default engine (which is WSGI from Python standard lib):
$ pyxer serve
But you may also use Pyxer without using the command line tools e.g. like this:
$ paster serve development.ini
For a simple "Hello World" just put an "index.html" file into the "public" directory with the following content:
Hello World
This works just like a static server. To use a controller put a file "__init__.py" into that directory with the following content:
@controller def index(): return "Hello World"
Controller, templates and static files are placed in the same
directory (usually "public"). First Pyxer looks for a matching controller. A controller is defined in the
"__init__.py" file and decorated by using @controller
which is defined in pyxer.base
.
from pyxer.base import * @controller def index(): return "Hello World"
This example can be called like /
or /index
.
To use a Pyxer template with this file you may use the render()
function or just return None
(that is the same as not
returning anything) and the matching template will be used, in this
case index.html
. The available object in the template
are the same as used by Pylons: c
= context, g
= globals and h
= helpers.
from pyxer.base import * @controller def index(): c.title = "Hello World"
By default the Kid templating language is used and output is specified as "xhtml-strict". You may want to change that for certain documents e.g. to render a plain text:
from pyxer.base import * @controller(output="plain") def index(): c.title = "Hello World"
Or use another template:
from pyxer.base import * @controller(template="test.html", output="html") def index(): c.title = "Hello World"
Or use your own renderer:
from pyxer.base import * def myrender(): result = request.result return "The result is: " + repr(result) @controller(render=myrender) def index(): return 9 + 9
To return data as JSON just return a dict or list object from your controller:
from pyxer.base import *
@controller
def index():
return dict(success=True, msg="Everything ok")
Session are realized using the Beaker package. You may use the variable session
to set and get values. To store the session data use session.save()
. Here is a simple example of a counter:
from pyxer.base import *
@controller
def index():
c.ctr = session.get("ctr", 0)
session["ctr"] = c.ctr + 1
session.save()
??? XXX
#Looks for a controller (foo/bar/__init__py:bar)
If the controller returns a dictionary this will be applied to template (step 2)
To publish your project to GAE you may also use the Pyxer command line tool. First check if your "app.yaml" file contains the right informations like the project name and version infos. Then just do like this:
$ xgae upload
Be aware that Pyxer first needs to fix the paths to be relative instead of absolute to make them work on the GAE environment. If you choose not to use Pyxer for uploading you have to do this fix up explicitly before you upload your applikation, like this:
$ xgae fix
XXX Kid or how to configure
DEPRECATED:
Pyxer offers yet another templating language that is very close to Genshi and Kid. As the former did not work with Google AppEngine at the moment of birth of Pyxer the new templating tools had been implemented. It is based on html5lib.
The default templating works similar to most known other
templating languages. Variables and expressions are realized like $<varname>
(where <varname>
may
contain dots!) and ${<expression>}
:
Hello ${name.capitalize()}, you won $price. $item.amount times $item.name.
Commands are the same as used by Python. The only difference is,
that you have to tell that a block ends by calling the command end
(not needed for else
and elif
):
<% def address(name): %> ABCDEF Company <% if name: %> Your contact: $name <% else: %> Unknown contact! <% end %> <% end %> <% for name in ['Tom', 'Fred']: %> ${ address(name) } <% end %>
You can insert content of other templates by using “include”:
<% include(filename) %>
More sophisticated is the extension of a file.
<% extends('b.html') %> <% def content(): %> Here goes the content <% end %>File “a.html”
<% content() %>File “b.html”
These are also known form many templating languages like Genshi. They are used like this:
<div py:if=”name.startswith('tom ')”>Welcome $name</div>
xxx
<div py:for=”name in sorted(c.listOfNames)”>Welcome $name</div>
xxx
To make deployment of GAE projects easy a virtual environment (VM) is created. If you start GAE via xgae
or paster via xpaster
these virtual environments will automatically be used. Pyxer determines the root of the VM by looking for the app.yaml
file. If you have to enter the VM for installing packages or for other reasons you may to it like this:
$ pyxer vm (vm)$ easy_install html5lib (vm)$ exit
You may also use the usual functions as described in virtualenv by Ian Bicking <http://pypi.python.org/pypi/virtualenv/>.
$ Scripts\activate.bat
$ easy_install SomePackageName $ deactivate
And for other Unix like system like this:
$ source bin/activate $ easy_install SomePackageName $ deactivate
If you decide to develop Pyxer you may run into the following problem: each project comes with an own virtual machine (VM)and its own installation of Pyxer in it. So if you change the development version it will have no effect on your installation. Therefore a command "pyxer" is added that synchronizes the Pyxer installation in the VM with the development version:
$ pyxer pyxer
BTW: To install the development version using SetupTools do like this:
$ cd <Path_to_development_version_of_Pyxer> $ python setup.py develop
You will have to repeat this each time the version of Pyxer changes, because otherwise the command line tools do not work.
Since a Pyxer project is based in Paster writing test cases is quite the same. The most simple test looks like this. (We asume that the test file to be placed in the root of the project. For normal testing you have do add root to sys.path
and modify the loadapp
argument.):
from paste.deploy import loadapp from paste.fixture import TestApp import os.path app = TestApp(loadapp('config:%s' % os.path.abspath('development.ini'))) res = app.get("/") assert ('<body' in res)
For more informations look here <http://pythonpaste.org/testing-applications.html>.
xxx
xxx
XXX
Pyxer uses support different so called "engines" to publish a project. Most of them need own configurations and a well prepare environment to work fine. These are very specific to each of these engines and Pyxer tries to make the setup as easy as possible
$ xpaster serve --reload
$ xgae serve
Some usfull links: