126
The Swiss-Army Knife for Python Web Developers Armin Ronacher — http://lucumr.pocoo.org/

The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Embed Size (px)

Citation preview

Page 1: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

The Swiss-Army Knife for Python Web DevelopersArmin Ronacher — http://lucumr.pocoo.org/

Page 2: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

About Me

Page 3: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

About Me

• Name: Armin Ronacher

• Werkzeug, Jinja, Pygments, ubuntuusers.de

• Python since 2005

• WSGI warrior since the very beginning (well, not quite)

Page 4: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Why Python?

Page 5: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Why Python?

• agile

• active community

• countless modules

• powerful introspection functionality

• WSGI

Page 6: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

WSGI

Page 7: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

WSGI

• Web Server Gateway Interface

• lowlevel interface between application and server

• allows to reuse code between applications

• CGI / FastCGI / SCGI / AJP / mod_python / mod_wsgi / twisted / standalone

• simple and fast

Page 8: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Hello World

Page 9: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Hello World

def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [ '<!DOCTYPE HTML>\n<title>Hello World</title>\n' '<h1>Hello World!</h1>' ]

Page 10: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Hello World

def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [ '<!DOCTYPE HTML>\n<title>Hello World</title>\n' '<h1>Hello World!</h1>' ]

Request

Page 11: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Hello World

def application(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return [ '<!DOCTYPE HTML>\n<title>Hello World</title>\n' '<h1>Hello World!</h1>' ]

Request Response #1

Response #2

Page 12: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Deployment

Page 13: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Deployment

lighttpd Apache

Page 14: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Deployment

lighttpd

mod_fastcgi / mod_scgi

Apache

mod_wsgi

Page 15: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Deployment

lighttpd

mod_fastcgi / mod_scgi

flup

Apache

mod_wsgi

Page 16: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Deployment

lighttpd

mod_fastcgi / mod_scgi

flup

WSGI Anwendung

Apache

mod_wsgi

WSGI Anwendung

Page 17: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Deployment

lighttpd

mod_fastcgi / mod_scgi

flup

WSGI Anwendung

Apache

mod_wsgi

WSGI Anwendung

wsgiref

WSGI Anwendung

Page 18: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Middlewares

Page 19: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Middlewares

• middlewares work between server and application

Page 20: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Middlewares

• middlewares work between server and application

• can manipulate incoming and outgoing data

Page 21: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Middlewares

• middlewares work between server and application

• can manipulate incoming and outgoing data

• useful to …

• … log errors

• … fix broken server data

• … combine multiple applications

Page 22: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

But....

Page 23: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

But....

...an application shouldn’t depend on an middleware

Page 24: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

But....

...an application shouldn’t depend on an middleware

http://dirtsimple.org/2007/02/wsgi-middleware-considered-harmful.html

Page 25: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

But....

...an application shouldn’t depend on an middleware

http://dirtsimple.org/2007/02/wsgi-middleware-considered-harmful.html

Page 26: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Setup

Page 27: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Setup• central „runner” file:

Page 28: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Setup• central „runner” file:

• application.fcgi … mod_fastcgi

Page 29: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Setup• central „runner” file:

• application.fcgi … mod_fastcgi

• application.wsgi … mod_wsgi

Page 30: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Setup• central „runner” file:

• application.fcgi … mod_fastcgi

• application.wsgi … mod_wsgi

• run-application.py … standalone / wsgiref

Page 31: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Setup• central „runner” file:

• application.fcgi … mod_fastcgi

• application.wsgi … mod_wsgi

• run-application.py … standalone / wsgiref

• imports application and middlewares

Page 32: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Setup• central „runner” file:

• application.fcgi … mod_fastcgi

• application.wsgi … mod_wsgi

• run-application.py … standalone / wsgiref

• imports application and middlewares

• combines it and creates and application object or calls the gateway

Page 33: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Setup

from yourapplication import Applicationfrom yourmiddleware import YourMiddlewarefrom vendormiddleware import VendorMiddleware

application = Application(configuration=here)application = YourMiddleware(application, configuration=here)application = VendorMiddleware(application)

• central „runner” file:• application.fcgi … mod_fastcgi

• application.wsgi … mod_wsgi

• run-application.py … standalone / wsgiref

• imports application and middlewares

• combines it and creates and application object or calls the gateway

Page 34: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Summary

Page 35: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Summary

• application: callable object

Page 36: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Summary

• application: callable object• environ … incoming data

Page 37: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Summary

• application: callable object• environ … incoming data• start_response … starts the response

Page 38: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Summary

• application: callable object• environ … incoming data• start_response … starts the response• app_iter … an iterator, each iteration sends

data to the client

Page 39: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Summary

• application: callable object• environ … incoming data• start_response … starts the response• app_iter … an iterator, each iteration sends

data to the client

• middleware: between application and gateway

Page 40: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Summary

• application: callable object• environ … incoming data• start_response … starts the response• app_iter … an iterator, each iteration sends

data to the client

• middleware: between application and gateway

• gateway: translates WSGI to CGI etc.

Page 41: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Werkzeug

Page 42: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Werkzeug

• unicode handling

Page 43: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Werkzeug

• unicode handling

• form data / file uploads / url parameter parsing

Page 44: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Werkzeug

• unicode handling

• form data / file uploads / url parameter parsing

• URL dispatching

Page 45: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Werkzeug

• unicode handling

• form data / file uploads / url parameter parsing

• URL dispatching

• HTTP parsing

Page 46: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Werkzeug

• unicode handling

• form data / file uploads / url parameter parsing

• URL dispatching

• HTTP parsing

• development server

Page 47: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Werkzeug

• unicode handling

• form data / file uploads / url parameter parsing

• URL dispatching

• HTTP parsing

• development server

• autoreloader

Page 48: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Werkzeug

• unicode handling

• form data / file uploads / url parameter parsing

• URL dispatching

• HTTP parsing

• development server

• autoreloader

• countless small helpers

Page 49: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What is it not?

Page 50: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What is it not?

• ORM

Page 51: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What is it not?

• ORM

• template engine

Page 52: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What is it not?

• ORM

• template engine

• form-validation

Page 53: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What is it not?

• ORM

• template engine

• form-validation

• i18n / l10n

Page 54: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What is it not?

• ORM

• template engine

• form-validation

• i18n / l10n

• component architecture

Page 55: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What is it not?

• ORM

• template engine

• form-validation

• i18n / l10n

• component architecture

• a framework

Page 56: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Why not?

Page 57: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Why not?

• such things exist already

Page 58: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Why not?

• such things exist already

• you can combine them

Page 59: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Why not?

• such things exist already

• you can combine them

• everybody wants something else

Page 60: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Why not?

• such things exist already

• you can combine them

• everybody wants something else

• cherry picking!

Page 61: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What does it look like?

Page 62: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What does it look like?

>>> from werkzeug import Request, create_environ>>> environ = create_environ('/index.html?foo=bar&foo=baz&blah=42')>>> request = Request(environ)>>> request.args['foo']u'bar'>>> request.args.getlist('foo')[u'bar', u'baz']>>> request.args.get('blah', type=int)42>>> request.pathu'/index.html'>>> request.method'GET'

Page 63: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule
Page 64: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

DumpIt!a pastebin in 15 minutes

Page 65: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

Page 66: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

Page 67: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

• Jinja

Page 68: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

• Jinja

• sqlite3

Page 69: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

• Jinja

• sqlite3

• Pygments

Page 70: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

• Jinja

• sqlite3

• Pygments

WSGI

Page 71: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

• Jinja

• sqlite3

• Pygments

WSGITemplates

Page 72: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

• Jinja

• sqlite3

• Pygments

WSGITemplatesDatabase

Page 73: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

• Jinja

• sqlite3

• Pygments

WSGITemplatesDatabaseCode Highlighting

Page 74: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

What do we use?

• Werkzeug

• Jinja

• sqlite3

• Pygments

WSGITemplatesDatabaseCode Highlighting

easy_install Werkzeugeasy_install Jinjaeasy_install Pygments

Page 75: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#0: Database

Page 76: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#0: Database

CREATE TABLE pastes ( id INTEGER NOT NULL, code TEXT, lang VARCHAR(40), PRIMARY KEY (id));

schema.sql

Page 77: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#1: Imports

Page 78: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#1: Imports

import sqlite3from os import pathfrom werkzeug import Request, Response, redirectfrom werkzeug.exceptions import HTTPException, NotFoundfrom werkzeug.routing import Map, Rulefrom jinja import Environment, FileSystemLoaderfrom pygments import highlightfrom pygments.lexers import get_lexer_by_name, TextLexerfrom pygments.formatters import HtmlFormatter

Page 79: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#2: Configuration

Page 80: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#2: Configuration

DATABASE = '/path/to/dumpit.db'PYGMENTS_STYLE = 'pastie'LANGUAGES = [ ('text', 'No Highlighting'), ('python', 'Python'), ('c', 'C')]TEMPLATES = path.join(path.dirname(__file__), 'templates')

jinja_env = Environment(loader=FileSystemLoader(TEMPLATES))pygments_formatter = HtmlFormatter(style=PYGMENTS_STYLE)

def render_template(template_name, **context): template = jinja_env.get_template(template_name) return template.render(context)

Page 81: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatching

Page 82: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 83: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 84: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 85: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 86: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 87: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 88: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

http://localhost:5000/http://localhost:5000/42http://localhost:5000/42/rawhttp://localhost:5000/pygments.css

Page 89: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 90: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 91: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 92: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 93: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 94: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 95: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 96: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 97: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 98: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 99: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 100: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#3: Dispatchingurl_map = Map([ Rule('/', endpoint='new_paste'), Rule('/<int:id>', endpoint='show_paste'), Rule('/<int:id>/raw', endpoint='download_paste'), Rule('/pygments.css', endpoint='pygments_style')])

def application(environ, start_response): request = Request(environ) request.db = sqlite3.connect(DATABASE) url_adapter = url_map.bind_to_environ(environ) try: endpoint, values = url_adapter.match() response = globals()[endpoint](request, **values) if isinstance(response, basestring): response = Response(response, mimetype='text/html') except HTTPException, error: response = error return response(environ, start_response)

Page 101: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#4: „Views“

Page 102: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#4: „Views“def new_paste(request): if request.method == 'POST': code = request.form.get('code') lang = request.form.get('lang') if code and lang: paste = Paste(lang, code) paste.save(request.db) return redirect(str(paste.id)) return render_template('new_paste.html', languages=LANGUAGES)

Page 103: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#4: „Views“def new_paste(request): if request.method == 'POST': code = request.form.get('code') lang = request.form.get('lang') if code and lang: paste = Paste(lang, code) paste.save(request.db) return redirect(str(paste.id)) return render_template('new_paste.html', languages=LANGUAGES)

def show_paste(request, id): paste = Paste.get(request.db, id) if paste is None: raise NotFound() return render_template('show_paste.html', paste=paste)

Page 104: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#4: „Views“def new_paste(request): if request.method == 'POST': code = request.form.get('code') lang = request.form.get('lang') if code and lang: paste = Paste(lang, code) paste.save(request.db) return redirect(str(paste.id)) return render_template('new_paste.html', languages=LANGUAGES)

def show_paste(request, id): paste = Paste.get(request.db, id) if paste is None: raise NotFound() return render_template('show_paste.html', paste=paste)

def download_paste(request, id): paste = Paste.get(request.db, id) if paste is None: raise NotFound() return Response(paste.code)

Page 105: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#4: „Views“def new_paste(request): if request.method == 'POST': code = request.form.get('code') lang = request.form.get('lang') if code and lang: paste = Paste(lang, code) paste.save(request.db) return redirect(str(paste.id)) return render_template('new_paste.html', languages=LANGUAGES)

def show_paste(request, id): paste = Paste.get(request.db, id) if paste is None: raise NotFound() return render_template('show_paste.html', paste=paste)

def download_paste(request, id): paste = Paste.get(request.db, id) if paste is None: raise NotFound() return Response(paste.code)

def pygments_style(request): return Response(pygments_formatter.get_style_defs(), mimetype='text/css')

Page 106: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#5: Model

Page 107: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

class Paste(object):

def __init__(self, lang, code, id=None): self.lang = lang self.code = code self.id = id @property def highlighted_code(self): try: lexer = get_lexer_by_name(self.lang) except ValueError: lexer = TextLexer return highlight(self.code, lexer, pygments_formatter)

@classmethod def get(cls, con, id): cur = con.cursor() cur.execute('select lang, code, id from pastes where id = ?', [id]) row = cur.fetchone() if row: return cls(*row)

def save(self, con): cur = con.cursor() if self.id is None: cur.execute('insert into pastes (lang, code) values (?, ?)', [self.lang, self.code]) self.id = cur.lastrowid else: cur.execute('update pastes set lang = ?, code = ? where ' 'id = ?', [self.lang, self.code, self.id]) con.commit()

#5: Model

Page 108: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

class Paste(object):

def __init__(self, lang, code, id=None): self.lang = lang self.code = code self.id = id @property def highlighted_code(self): try: lexer = get_lexer_by_name(self.lang) except ValueError: lexer = TextLexer return highlight(self.code, lexer, pygments_formatter)

@classmethod def get(cls, con, id): cur = con.cursor() cur.execute('select lang, code, id from pastes where id = ?', [id]) row = cur.fetchone() if row: return cls(*row)

def save(self, con): cur = con.cursor() if self.id is None: cur.execute('insert into pastes (lang, code) values (?, ?)', [self.lang, self.code]) self.id = cur.lastrowid else: cur.execute('update pastes set lang = ?, code = ? where ' 'id = ?', [self.lang, self.code, self.id]) con.commit()

#5: Model

Page 109: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#6: Templates

Page 110: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#6: Templates<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html> <head> <title>Dump It!</title> <link rel="stylesheet" href="/static/style.css" type="text/css"> <link rel="stylesheet" href="/pygments.css" type="text/css"> </head> <body> <div id="header"> <h1>Dump It!</h1> </div> <div id="page"> {% block body %}{% endblock %} </div> </body></html>

layout.html

Page 111: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#6: Templates<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html> <head> <title>Dump It!</title> <link rel="stylesheet" href="/static/style.css" type="text/css"> <link rel="stylesheet" href="/pygments.css" type="text/css"> </head> <body> <div id="header"> <h1>Dump It!</h1> </div> <div id="page"> {% block body %}{% endblock %} </div> </body></html>

{% extends "layout.html" %}{% block body %} <h2>New Paste</h2> <form action="" method="post"> <p><textarea name="code" rows="8" cols="50"></textarea></p> <p><select name="lang"> {% for code, name in languages %} <option value="{{ code }}">{{ name }}</option> {% endfor %} </select><input type="submit" value="Paste"></p> </form>{% endblock %}

layout.html

new_paste.html

Page 112: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

#6: Templates<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html> <head> <title>Dump It!</title> <link rel="stylesheet" href="/static/style.css" type="text/css"> <link rel="stylesheet" href="/pygments.css" type="text/css"> </head> <body> <div id="header"> <h1>Dump It!</h1> </div> <div id="page"> {% block body %}{% endblock %} </div> </body></html>

{% extends "layout.html" %}{% block body %} <h2>New Paste</h2> <form action="" method="post"> <p><textarea name="code" rows="8" cols="50"></textarea></p> <p><select name="lang"> {% for code, name in languages %} <option value="{{ code }}">{{ name }}</option> {% endfor %} </select><input type="submit" value="Paste"></p> </form>{% endblock %}

{% extends "layout.html" %}{% block body %} <h2>Paste #{{ paste.id }}</h2> <div class="paste"> {{ paste.highlighted_code }} </div>{% endblock %}

layout.html

new_paste.html

show_paste.html

Page 113: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Development Server

Page 114: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Development Server

if __name__ == '__main__': from werkzeug import run_simple, SharedDataMiddleware application = SharedDataMiddleware(application, { '/static': path.join(path.dirname(__file__), 'static') }) run_simple('localhost', 4000, application)

Page 115: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

Development Server

mitsuhiko@nausicaa:~/DumpIt$ sqlite3 /path/to/dumpit.db < schema.sql mitsuhiko@nausicaa:~/DumpIt$ python dumpit.py runserver * Running on http://localhost:4000/

if __name__ == '__main__': from werkzeug import run_simple, SharedDataMiddleware application = SharedDataMiddleware(application, { '/static': path.join(path.dirname(__file__), 'static') }) run_simple('localhost', 4000, application)

Page 116: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

„Dump It!“ In Action

Page 117: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

„Dump It!“ In Action

Page 118: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

„Dump It!“ In Action

Page 119: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

More Than One Way

Page 120: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

More Than One Way

• Templates: XML / Text-based / Sandbox

Page 121: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

More Than One Way

• Templates: XML / Text-based / Sandbox

• Daten: SQL / CouchDB / Filesystem

Page 122: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

More Than One Way

• Templates: XML / Text-based / Sandbox

• Daten: SQL / CouchDB / Filesystem

• AJAX: JSON / XML / HTML Fragments

Page 123: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

More Than One Way

• Templates: XML / Text-based / Sandbox

• Daten: SQL / CouchDB / Filesystem

• AJAX: JSON / XML / HTML Fragments

• URLs: Regular Expressions / Werkzeug Routing / Routes / Objekt-basierend / Query Parameters

Page 124: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

More Than One Way

• Templates: XML / Text-based / Sandbox

• Daten: SQL / CouchDB / Filesystem

• AJAX: JSON / XML / HTML Fragments

• URLs: Regular Expressions / Werkzeug Routing / Routes / Objekt-basierend / Query Parameters

• Dispatching: Controller / View-Functions

Page 125: The Swiss-Army Knife for Python Web Developersmitsuhiko/werkzeug_en.pdf · The Swiss-Army Knife for Python Web Developers ... • everybody wants something else. Why not? ... Rule

More Than One Way

• Templates: XML / Text-based / Sandbox

• Daten: SQL / CouchDB / Filesystem

• AJAX: JSON / XML / HTML Fragments

• URLs: Regular Expressions / Werkzeug Routing / Routes / Objekt-basierend / Query Parameters

• Dispatching: Controller / View-Functions

• Auth: Apache / LDAP / OpenID