源自:http://docs.dotcloud.com/services/python/#internals
Python

The python service can host any Python web application compatible with the WSGI standard.

That includes all modern Python web frameworks: Django, Pyramid, web.py, web2py, etc.

Note

For the impatient…

Your WSGI callable should be named “application”, be located in a “wsgi.py” file, itself located at the top directory of the service.

Your dependencies should be specified in a PIP-style “requirements.txt” file.

But read on for a guided tour of the service!
Basic Use

Let’s assume that you are building a DotCloud application called “ramen”. For the sake of simplicity, we will also assume that everything related to this application is located in a directory called “ramen-on-dotcloud”.

Let’s setup our environment:

$ dotcloud create ramen
Created application “ramen”
$ mkdir ramen-on-dotcloud

A DotCloud application is described by a Build Files, which is a simple YAML file named “dotcloud.yml” located in our “ramen-on-dotcloud” directory. To add a new service to our app, we just add the following lines to “ramen-on-dotcloud/dotcloud.yml”:

www:
type: python
approot: hellopython

This Build File instructs the platform to use the code in the directory “hellopython” for our service. Let’s create it:

$ mkdir ramen-on-dotcloud/hellopython

As said above, the python service expects you to provide it with a WSGI app. So let’s write a very minimal one. Create the file “ramen-on-dotcloud/hellopython/wsgi.py” with the following content:

def application(environ, start_response):
status = ‘200 OK’
response_headers = [(‘Content-type’, ‘text/plain’)]
start_response(status, response_headers)
return [‘Hello world!
‘] + [‘{0}={1}
‘.format(k,environ[k])
for k in sorted(environ)]

This will not only display a “Hello world!” message, but also dump the whole WSGI environment for informative purposes.

We can now push our application to DotCloud:

$ dotcloud push ramen ramen-on-dotcloud/
# upload /home/…/ramen-on-dotcloud/ ssh://dotcloud@uploader.dotcloud.com:21122/ramen
# rsync
[…]
sent 8.11K bytes received 352 bytes 995.06 bytes/sec
total size is 14.78K speedup is 1.75
Deployment for “ramen” triggered. Will be available in a few seconds.
2011-06-28 04:27:34 [api] Waiting for the build. (It may take a few minutes)
2011-06-28 04:27:48 [www.0] service booted
2011-06-28 04:27:48 [www.0] The build started
2011-06-28 04:27:48 [www.0] Fetched code revision rsync-1309235251.44
2011-06-28 04:27:51 [www.0] Reloading nginx configuration: nginx.
2011-06-28 04:27:51 [www.0] The build finished successfully
2011-06-28 04:27:51 [api] Deploy finished

Deployment finished successfully. Your application is available at the following URLs
www: http://d07c100d.dotcloud.com/

A random URL has been generated for each web service in your application (it won’t be http://d07c100d.dotcloud.com/ for your app, but something else). Point your browser to this URL to see your new service in action!

If you want to attach a better URL to your application, read the Custom Domains documentation.
Internals

DotCloud python runs with Nginx as the HTTP frontend. All URLs starting with /static will be served as static files from the “static” subdirectory in your application (if it exists). Everything else will be handed to your WSGI app through uWSGI. The uWSGI workers are managed by Supervisor.

Your code dependencies are automatically handled with pip if your app ships an optional “requirements.txt” file.
Adapting your application

DotCloud relies on well-established tools and conventions to build your app. It should be trivial to adapt any application to run on DotCloud.
Expose a WSGI application

If you wrote a WSGI application from scratch, all you have to do is to make sure that the callable is named “application” and in the “wsgi.py” file.

If you are using a framework like Django, Pylons, Web2py, and lots of others, you will want to use the WSGI handler provided by the framework.

Here are a few examples of wsgi.py files for some common frameworks:

Django
Tornado
web2py

import os
os.environ[‘DJANGO_SETTINGS_MODULE’] = ‘.’
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Static files

Move all static files (images, css, javascript…) to a directory called static/ at the root of your application. You can also create a symbolic link if you don’t want to change your directory layout too much.

Your static files will be served at http:///static/. You should:

either update your app settings so links to static assets will point there (for Django, see http://docs.djangoproject.com/en/1.2/howto/static-files/);
or drop a custom Nginx configuration snippet to use a different path.

For example, if your static assets are in the “media” subdirectory of your application, and your code expects them to be found on the “/media” URI, you can create the following “nginx.conf” file in your approot:

location /media { root /home/dotcloud/current; }

Note

The “root” should be /home/dotcloud/current, not /home/dotcloud/current/media, because the location (/media) will be appended when looking for files.
Code dependencies

You can specify external requirements in a file called requirements.txt. A typical requirements file looks like this:

Django==1.1.2
Pil
http://jsonschema.googlecode.com/files/jsonschema-0.2a.tar.gz

This is not specific to DotCloud at all: more and more Python projects are using this style of files for their dependencies. If you want to install those dependencies in your local environment, just run “pip install -r requirements.txt”. You might also want to check “pip freeze”, which can output a requirements.txt file for you, containing the exact version numbers of all Python packages currently installed. This is very convenient to make sure that you will get the very same set of packages on different servers (e.g. DotCloud and your local development environment).

For more information on pip and the format of requirements.txt, see pip’s documentation (http://pip.openplans.org/).
Custom Nginx Configuration

You can specify custom rewrite rules (and actually almost any nginx setting) by creating a file named nginx.conf at the top of your app.

This file will be included by nginx.

Note

You should not include a whole nginx configuration: just the snippets that you need!

A typical example would be:

rewrite ^/search/(.*) /engine/?q=$1 ;

Check out the Nginx wiki to see all available options.

Note

Already have some Apache mod_rewrite RewriteRule statements? All of them can be converted to nginx configuration.
Custom uWSGI Configuration

You can define additional uwsgi parameters in a uwsgi.conf file at the root of your application. For example:

uwsgi_param ENVIRONMENT prod;

You can also modify the following uwsgi options in the config section of “dotcloud.yml”:

uwsgi_memory_report: if set to true this will log each request with informations about the memory usage (the default is false);
uwsgi_buffer_size: set (in bytes) the size of the buffer used to parse uwsgi packets. The default value is 4096 but you will need to increase it if you have requests with a lot of headers;
uwsgi_harakiri: every request that will take longer than the seconds specified in the harakiri timeout will be dropped and the corresponding worker recycled.

For example:

www:
type: python
config:
uwsgi_buffer_size: 8192

Warning

The config dictionnary of a service is applied when your Service is launched for the first time. If you change you it, you will need to destroy the concerned service and push your application again to apply the changes.
Other documentations

You might be interested by the following DotCloud tutorials:

- EOF -