This chapter narrates you to create a web application project using BlueBream. If you complete this chapter, you should be able to:
Before proceeding further, let’s have an overview of the sections.
This document assumes that user has already installed Python 2.4, 2.5 or 2.6 and Distribute (or Setuptools). If Distribute (or Setuptools) is installed, the user will get an easy_install command which can be used to install the bluebream distribution. Another way of installing bluebream is by using PIP, a replacement for easy_install which is meant to improve on it. Among advantages, you will be able to uninstall packages.
The user can also install BlueBream inside an isolated Python environment created using Virtualenv. Although, virtualenv is not required when working on the application itself, because Buildout is available by default in the application created. Buildout is the recommended approach to create repeatable, isolated working environments. Buildout is a declarative, configuration-driven build system created by Jim Fulton.
It is recommended to use a custom-built Python for working with BlueBream. The user is required to install a C compiler (gcc) in his system, and to have internet access to PyPI to perform installation of the bluebream distribution, to bootstrap the buildout, and to build the application using Buildout. Internet access is not required for deployment if zc.sourcerelease package is used.
# easy_install bluebream
$ sudo easy_install bluebream
Try to avoid running “easy_install” commands as root or with sudo for larger installation because it can lead to conflicts with the packaging system of your OS. Installing the bluebream template like this is ok, because it does not pull a lot of dependencies.
As mentioned earlier, Internet access to PyPI is required to perform installation of the bluebream distribution. If the user is behind a proxy, it’s up to him to make sure it works. The easy_install will look for the environment variable named http_proxy on a GNU/Linux platforms. The user can set it like this:
$ export http_proxy="http://username:password@PROXY-IP-ADDRESS:PORT"
Apart from the bluebream distribution, easy_install will download and install a few dependencies. The dependencies are:
Installing the bluebream template package is a one time process. Once the project package is ready, the user does not need the bluebream template package anymore because the package user is about to create will be self-bootstrappable.
The bluebream distribution provides a project template based on PasteScript templates. Once BlueBream is installed, run the paster command to create the project directory structure. The create sub-command provided by paster will show a command-line wizard to create the project directory structure.
$ paster create -t bluebream
This will bring a wizard asking details about the new project. The user can choose the package name and version number in the wizard itself. These details can also be modified later. Now, the user gets a working application with the project name as the name of the egg. The project name can be a dotted name, if the user wants his project to be part of a namespace. Any number of namespace levels can be used. The project can be called ‘sample’, ‘sample.main’ or ‘sample.app.main’ or anything deeper if necessary. The subfolder structure will be created accordingly.
Here is a screenshot of sample project creation:
The project name and other parameters can be given as a command line argument:
$ paster create -t bluebream sampleproject $ paster create -t bluebream sampleproject version=0.1
The user does not get asked by the wizard for the options whose values are already passed through command line. Other variables can also be given values from the command line, if required:
Recommended use of Wizard
It is recommended to provide the details in the wizard itself but user can choose to provide the details at a later stage by simply pressing Enter/Return key.
As mentioned earlier, the generated package is bundled with a Buildout configuration (buildout.cfg) and a bootstrap script (bootstrap.py). First, the user needs to bootstrap the buildout itself:
$ cd sampleproject $ python bootstrap.py
The bootstrap script will download and install the zc.buildout and distribute packages. Also, it will create the basic directory structure.
Here is a screenshot of bootstrapping the buildout:
The next step is building the application. To build the application, run the buildout:
Here is a screenshot of the application being built:
The buildout script will download all dependencies and setup the environment to run your application. This can take some time because many packages are downloaded. If you don’t want these packages to be downloaded again the next time you create a project, you can set a shared directory in your personal buildout configuration: create a file ~/.buildout/default.cfg (and the .buildout folder if needed), with the following contents:
[buildout] newest = false unzip = true download-cache = /opt/buildout-download-cache
You can choose any value for the download-cache, buildout will create it for you.
If you set the newest = false option, buildout will not look for new version of packages in package server by default. The unzip = true makes Buildout to unzip all eggs irrespective of whether it is Zip safe or not. The download-cache is the directory where Buildoout keeps a cached copy the source eggs downloaded.
The next section will show the basic usage.
The most common thing a user needs while developing an application is running the server. BlueBream uses the paster command provided by PasteScript to run the WSGI server. To run the server, the user can pass the PasteDeploy configuration file as the argument to the serve sub-command as given here:
$ ./bin/paster serve debug.ini
After starting the server, the user can access the site from his browser on this URL: http://localhost:8080/ . The port number (8080) can be changed in PasteDeploy configuration file (debug.ini) to user choice.
When the user opens the browser, it will look like as shown in this screenshot:
The second most common thing that should be run are the unit tests. BlueBream creates a testrunner using the zc.recipe.testrunner Buildout recipe. The user can see a test command inside the bin directory. To run the test cases, the following command is used:
Sometimes the user may want to get the debug shell. BlueBream provides a Python prompt with your application object. You can invoke the debug shell in the following way:
$ ./bin/paster shell debug.ini
More details about the test runner and debug shell are explained in the BlueBream Manual.
The default directory structure created by the bluebream paster project template is as shown:
myproject/ |-- bootstrap.py |-- buildout.cfg |-- debug.ini |-- deploy.ini |-- etc | |-- site.zcml | |-- zope.conf | `-- zope-debug.conf |-- setup.py |-- src | |-- myproject | | |-- __init__.py | | |-- configure.zcml | | |-- debug.py | | |-- securitypolicy.zcml | | |-- startup.py | | |-- tests | | | |-- __init__.py | | | |-- ftesting.zcml | | | `-- tests.py | | `-- welcome | | |-- __init__.py | | |-- app.py | | |-- configure.zcml | | |-- ftests.txt | | |-- index.pt | | |-- interfaces.py | | |-- static | | | |-- logo.png | | | `-- style.css | | `-- views.py | `-- myproject.egg-info | |-- PKG-INFO | |-- SOURCES.txt | |-- dependency_links.txt | |-- entry_points.txt | |-- not-zip-safe | |-- requires.txt | `-- top_level.txt `-- var |-- filestorage | `-- README.txt `-- log `-- README.txt
The name of the top-level directory will always be the project name as given in the wizard. The name of the egg will also be the same as the package name by default. The user can change it to something else from setup.py. Here are the details about the other files in the project.
The next few sections will explain how to create a hello world applications.
You can watch the video creating hello world application here:
To create a web page which displays Hello World!, you need to create a view class and register it using the browser:page ZCML directive. In BlueBream, this is called a Browser Page. Sometimes more generic term, Browser View is used instead of Browser Page which can be used to refer to HTTP, XMLRPC, REST and other views. By default, the page which you are getting when you access: http://localhost:8080 is a page registered like this. You can see the registration inside configure.zcml, the name of the view will be index. You can access the default page by explicitly mentioning the page name in the URL like this: http://localhost:8080/@@index. You can refer the Default view for objects HOWTO for more details about how the default view for a container object is working.
First you need to create a Python file named myhello.py at src/myproject/myhello.py:
$ touch src/myproject/myhello.py
You can define your browser page inside this module. All browser pages should implement the zope.publisher.interfaces.browser.IBrowserView interface. An easy way to do this would be to inherit from zope.publisher.browser.BrowserView which is already implementing the IBrowserView interface.
The content of this file could be like this:
from zope.publisher.browser import BrowserView class HelloView(BrowserView): def __call__(self): return "Hello World!"
Now you can register this page for a particular interface. So that it will be available as a browser page for any object which implement that particular interface. Now you can register this for the root folder, which is implementing zope.site.interfaces.IRootFolder interface. So, the registration will be like this:
<browser:page for="zope.site.interfaces.IRootFolder" name="hello" permission="zope.Public" class=".myhello.HelloView" />
Since you are using the browser XML namespace, you need to advertise it in the configure directive:
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser">
You can add this configuration to: src/myproject/configure.zcml. Now you can access the view by visiting this URL: http://localhost:8080/@@hello
The @@ symbol for view
@@ is a shortcut for ++view++. (Mnemonically, it kinda looks like a pair of goggle-eyes)
To specify that you want to traverse to a view named bar of content object foo, you could (compactly) say .../foo/@@bar instead of .../foo/++view++bar.
Note that even the @@ is not necessary if container foo has no element named bar - it only serves to disambiguate between views of an object and things contained within the object.
In this example, you will create a hello world using a page template.
First you need to create a page template file inside your package. You can save it as src/myproject/helloworld.pt, with the following content:
<html> <head> <title>Hello World!</title> </head> <body> <div> Hello World! </div> </body> </html>
Update configure.zcml to add this new page registration.
<browser:page name="hello2" for="*" template="helloworld.pt" permission="zope.Public" />
This declaration means: there is a web page called hello2, available for any content, rendered by the template helloworld.pt, and this page is public. This kind of XML configuration is very common in BlueBream and you will need it for every page or component.
In the above example, instead of using zope.site.interfaces.IRootFolder interface, * is used. So, this view will be available for all objects.
Restart your application, then visit the following URL: http://127.0.0.1:8080/@@hello2
This section explain creating a dynamic hello world application.
In the src/myproject/hello.py file, add a few lines of Python code like this:
class Hello(object): def getText(self): name = self.request.get('name') if name: return "Hello %s !" % name else: return "Hello ! What's your name ?"
This class defines a browser view in charge of displaying some content.
Now you need a page template to render the page content in HTML. So let’s add a hello.pt in the src/myproject directory:
<html> <head> <title>hello world page</title> </head> <body> <div tal:content="view/getText"> fake content </div> </body> </html>
The tal:content directive tells BlueBream to replace the fake content of the tag with the output of the getText method of the view class.
The next step is to associate the view class, the template and the page name. This is done with a simple XML configuration language (ZCML). Edit the existing file called configure.zcml and add the following content before the final </configure>:
<browser:page name="hello3" for="*" class=".hello.Hello" template="hello.pt" permission="zope.Public" />
This declaration means: there is a web page called hello3, available for any content, managed by the view class Hello, rendered by the template hello.pt, and this page is public.
Since you are using the browser XML namespace, you need to declare it in the configure directive. Modify the first lines of the configure.zcml file so it looks like this (You can skip this step if the browser namespace is already there from the static hello world view):
<configure xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser">
Restart your application, then visit the following URL: http://127.0.0.1:8080/@@hello3
You should then see the following text in your browser:
Hello ! What's your name ?
You can pass a parameter to the Hello view class, by visiting the following URL: http://127.0.0.1:8080/@@hello3?name=World
You should then see the following text:
Hello World !
This chapter walked through the process of getting started with web application development with BlueBream. It also introduced a few simple Hello World example applications. The Tutorial — Part 1 chapter will go through a bigger application to introduce more concepts.blog comments powered by Disqus