Getting started

Design Principles and Goals

  • KISS Keept it simple, stupid.
  • Convention over configuration But don’t take it too far.
  • Reusablity I will not repeat myself.
  • Don’t try to please everyone

Note

Rückenwind is in alpha stage of development, backwards compatibility will break. And actually did: 0.3.x and 0.4.x are quite different.

Install

Use pip:

virtualenv my_playground
. ./my_playground/bin/activate
pip install rueckenwind

Quick start

It is highly recommended to develop and deploy within a virtualenv. Always. So this documentation just assumes you do without further mentioning it. After installing rückenwind you got a new command at your disposal: rw. You can use it to generate a new rückendwind project skeleton:

rw skel --name my_new_project

To start your new project:

rw serv my_new_project.http

Go and visit 127.0.0.1:8000 to grab your hello world while it is hot.

Modules

The most basic entity in rückenwind is a module. A rückenwind module is a normal python module with some added convention.

The basic structure:

module/
        __init__.py
        http.py
        static/
        templates/
        locale/

The obvious: all your static files go into the static/ folder and your jinja2 templates into the templates/ folder.

The http.py must contain a Module named root. It is the entry point for all http requests to your app.

Note

Rückenwind does not try to be a framework for everyone and everything. As one of the consequences only a single templating engine is supported. This keeps rückendwind code KISS. Don’t like jinja? Sorry, rückenwind is not for you, switch to one of the many other frameworks.

Routing

At the heart of rückenwind there is routing of http requests. It draws inspiration from several other projects, like Flask .

Note

  • HTTP methods are strictly seperated. You cannot have one python function answering GET and POST.

An example RequestHandler

import time

import rw.http
import rw.gen


registration = rw.http.Module('my_playground')


@registration.get('/')
def register(handler):
    handler.render_template(template='register.html')


@registration.post('/')
def register_post(handler):
    u = User(email=handler.get_argument('email'),
             username=handler.get_argument('password'))
    handler.redirect(url_for(main))


root = rw.http.Module('my_playground')


@root.get('/')
def main(handler):
    handler['time'] = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
    root.render_template('index.html')


@root.get('/entry/<id>')
@rw.gen.coroutine
def entry(self, id):
    self['entries'] = yield get_entry_from_id(id)
    self.finish(template='my_playground/main.html')


root.mount('/register', registration)

For details see: Basic HTTP and Services

Templates

For documentation about the Jinja templating engine please look at its beautiful online documentation .

Assigning variables:

@root.get('/')
def main(handler):
    handler['time'] = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
    root.finish(template='my_playground/index.html')

Within the template:

The current time is {{ time }}.

If you refer to another resource there are two helper functions for creating URIs. For static files use:

{{ static('main.css') }}

This will insert an URI to your main.css, assuming there is one in your modules static folder.

If you want to link to another page there is:

{{ url_for(handler.login) }}

Same routes as before:

class Main(RequestHandler):
    @get('/')
    def main(self):
        # ...

    @get('/register')
    def register(self):
        # ...

    @get('/entry/<id>')
    def entry(self, id):
        # ...
command result
url_for(handler.login) /
url_for(handler.register) /register
url_for(handler.entry, id=1) /entry/1