werkzeug en

Upload: wuyuntao

Post on 31-May-2018

226 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/14/2019 werkzeug en

    1/126

    The Swiss-Army Knife for Python Web Developers

    Armin Ronacher http://lucumr.pocoo.org/

    http://lucumr.pocoo.org/http://lucumr.pocoo.org/
  • 8/14/2019 werkzeug en

    2/126

    About Me

  • 8/14/2019 werkzeug en

    3/126

    About Me

    Name: Armin Ronacher Werkzeug, Jinja, Pygments, ubuntuusers.de

    Python since 2005

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

  • 8/14/2019 werkzeug en

    4/126

    Why Python?

  • 8/14/2019 werkzeug en

    5/126

    Why Python?

    agile

    active community

    countless modules

    powerful introspection functionality

    WSGI

  • 8/14/2019 werkzeug en

    6/126

    WSGI

  • 8/14/2019 werkzeug en

    7/126

    WSGI

    Web Server Gateway Interface

    lowlevel interface between application andserver

    allows to reuse code between applications

    CGI / FastCGI / SCGI / AJP / mod_python /

    mod_wsgi / twisted / standalone simple and fast

  • 8/14/2019 werkzeug en

    8/126

    Hello World

  • 8/14/2019 werkzeug en

    9/126

    Hello World

  • 8/14/2019 werkzeug en

    10/126

    Hello World

  • 8/14/2019 werkzeug en

    11/126

    Hello World

  • 8/14/2019 werkzeug en

    12/126

    Deployment

  • 8/14/2019 werkzeug en

    13/126

    Deployment

  • 8/14/2019 werkzeug en

    14/126

    Deployment

  • 8/14/2019 werkzeug en

    15/126

    Deployment

  • 8/14/2019 werkzeug en

    16/126

    Deployment

  • 8/14/2019 werkzeug en

    17/126

  • 8/14/2019 werkzeug en

    18/126

    Middlewares

  • 8/14/2019 werkzeug en

    19/126

    Middlewares

    middlewares work between server andapplication

  • 8/14/2019 werkzeug en

    20/126

    Middlewares

    middlewares work between server andapplication

    can manipulate incoming and outgoing data

  • 8/14/2019 werkzeug en

    21/126

    Middlewares

    middlewares work between server andapplication

    can manipulate incoming and outgoing data

    useful to

    log errors

    fix broken server data combine multiple applications

  • 8/14/2019 werkzeug en

    22/126

    But....

  • 8/14/2019 werkzeug en

    23/126

    But....

    ...an application shouldnt depend on anmiddleware

  • 8/14/2019 werkzeug en

    24/126

    But....

    ...an application shouldnt depend on anmiddleware

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

    http://dirtsimple.org/2007/02/wsgi-middleware-considered-harmful.htmlhttp://dirtsimple.org/2007/02/wsgi-middleware-considered-harmful.html
  • 8/14/2019 werkzeug en

    25/126

    But....

    ...an application shouldnt depend on anmiddleware

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

    http://dirtsimple.org/2007/02/wsgi-middleware-considered-harmful.htmlhttp://dirtsimple.org/2007/02/wsgi-middleware-considered-harmful.html
  • 8/14/2019 werkzeug en

    26/126

    Setup

  • 8/14/2019 werkzeug en

    27/126

    Setup central runner file:

  • 8/14/2019 werkzeug en

    28/126

    Setup central runner file:

    application.fcgi mod_fastcgi

  • 8/14/2019 werkzeug en

    29/126

    Setup central runner file:

    application.fcgi mod_fastcgi

    application.wsgi mod_wsgi

  • 8/14/2019 werkzeug en

    30/126

    Setup central runner file:

    application.fcgi mod_fastcgi

    application.wsgi mod_wsgi

    run-application.py standalone / wsgiref

  • 8/14/2019 werkzeug en

    31/126

    Setup central runner file:

    application.fcgi mod_fastcgi

    application.wsgi mod_wsgi

    run-application.py standalone / wsgiref

    imports application and middlewares

  • 8/14/2019 werkzeug en

    32/126

    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

  • 8/14/2019 werkzeug en

    33/126

    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

  • 8/14/2019 werkzeug en

    34/126

    Summary

  • 8/14/2019 werkzeug en

    35/126

    Summary

    application: callable object

  • 8/14/2019 werkzeug en

    36/126

    Summary

    application: callable object

    environ incoming data

  • 8/14/2019 werkzeug en

    37/126

    Summary

    application: callable object

    environ incoming data

    start_response starts the response

  • 8/14/2019 werkzeug en

    38/126

    Summary

    application: callable object

    environ incoming data

    start_response starts the response

    app_iter an iterator, each iteration sends

    data to the client

  • 8/14/2019 werkzeug en

    39/126

    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

  • 8/14/2019 werkzeug en

    40/126

    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.

  • 8/14/2019 werkzeug en

    41/126

  • 8/14/2019 werkzeug en

    42/126

    Werkzeug

    unicode handling

  • 8/14/2019 werkzeug en

    43/126

    Werkzeug

    unicode handling

    form data / file uploads / url parameter

    parsing

  • 8/14/2019 werkzeug en

    44/126

    Werkzeug

    unicode handling

    form data / file uploads / url parameter

    parsing URL dispatching

  • 8/14/2019 werkzeug en

    45/126

    Werkzeug

    unicode handling

    form data / file uploads / url parameter

    parsing URL dispatching

    HTTP parsing

  • 8/14/2019 werkzeug en

    46/126

    Werkzeug

    unicode handling

    form data / file uploads / url parameter

    parsing URL dispatching

    HTTP parsing

    development server

  • 8/14/2019 werkzeug en

    47/126

    Werkzeug

    unicode handling

    form data / file uploads / url parameter

    parsing URL dispatching

    HTTP parsing

    development server

    autoreloader

  • 8/14/2019 werkzeug en

    48/126

    Werkzeug

    unicode handling

    form data / file uploads / url parameter

    parsing URL dispatching

    HTTP parsing

    development server

    autoreloader

    countless small helpers

  • 8/14/2019 werkzeug en

    49/126

    What is it not?

  • 8/14/2019 werkzeug en

    50/126

    What is it not?

    ORM

  • 8/14/2019 werkzeug en

    51/126

    What is it not?

    ORM

    template engine

  • 8/14/2019 werkzeug en

    52/126

    What is it not?

    ORM

    template engine form-validation

  • 8/14/2019 werkzeug en

    53/126

    What is it not?

    ORM

    template engine form-validation

    i18n / l10n

  • 8/14/2019 werkzeug en

    54/126

    What is it not?

    ORM

    template engine form-validation

    i18n / l10n

    component architecture

  • 8/14/2019 werkzeug en

    55/126

    What is it not?

    ORM

    template engine form-validation

    i18n / l10n

    component architecture

    a framework

  • 8/14/2019 werkzeug en

    56/126

    Why not?

  • 8/14/2019 werkzeug en

    57/126

    Why not?

    such things exist already

  • 8/14/2019 werkzeug en

    58/126

    Why not?

    such things exist already you can combine them

  • 8/14/2019 werkzeug en

    59/126

    Why not?

    such things exist already you can combine them

    everybody wants something else

  • 8/14/2019 werkzeug en

    60/126

    Why not?

    such things exist already you can combine them

    everybody wants something else

    cherry picking!

  • 8/14/2019 werkzeug en

    61/126

  • 8/14/2019 werkzeug en

    62/126

    What does it look like?

  • 8/14/2019 werkzeug en

    63/126

  • 8/14/2019 werkzeug en

    64/126

    DumpIt!a pastebin in 15 minutes

  • 8/14/2019 werkzeug en

    65/126

    What do we use?

  • 8/14/2019 werkzeug en

    66/126

    What do we use?

    Werkzeug

  • 8/14/2019 werkzeug en

    67/126

    What do we use?

    Werkzeug

    Jinja

  • 8/14/2019 werkzeug en

    68/126

    What do we use?

    Werkzeug

    Jinja sqlite3

  • 8/14/2019 werkzeug en

    69/126

    What do we use?

    Werkzeug

    Jinja sqlite3

    Pygments

  • 8/14/2019 werkzeug en

    70/126

    What do we use?

    Werkzeug

    Jinja sqlite3

    Pygments

    WSGI

  • 8/14/2019 werkzeug en

    71/126

    What do we use?

    Werkzeug

    Jinja sqlite3

    Pygments

    WSGI

    Templates

  • 8/14/2019 werkzeug en

    72/126

    What do we use?

    Werkzeug

    Jinja sqlite3

    Pygments

    WSGI

    TemplatesDatabase

  • 8/14/2019 werkzeug en

    73/126

    What do we use?

    Werkzeug

    Jinja sqlite3

    Pygments

    WSGI

    TemplatesDatabase

    Code Highlighting

  • 8/14/2019 werkzeug en

    74/126

    What do we use?

    Werkzeug

    Jinja sqlite3

    Pygments

    WSGI

    TemplatesDatabase

    Code Highlighting

  • 8/14/2019 werkzeug en

    75/126

    #0: Database

  • 8/14/2019 werkzeug en

    76/126

    #0: Database

  • 8/14/2019 werkzeug en

    77/126

    #1: Imports

  • 8/14/2019 werkzeug en

    78/126

  • 8/14/2019 werkzeug en

    79/126

  • 8/14/2019 werkzeug en

    80/126

    #2: Configuration

  • 8/14/2019 werkzeug en

    81/126

    #3: Dispatching

  • 8/14/2019 werkzeug en

    82/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    83/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    84/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    85/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    86/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    87/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    88/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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/pygments.csshttp://localhost:5000/pygments.csshttp://localhost:5000/42/rawhttp://localhost:5000/42/rawhttp://localhost:5000/42http://localhost:5000/42http://localhost:5000/http://localhost:5000/
  • 8/14/2019 werkzeug en

    89/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    90/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    91/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    92/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

    Di hi

  • 8/14/2019 werkzeug en

    93/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

    3 Di hi

  • 8/14/2019 werkzeug en

    94/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

    #3 Di hi

  • 8/14/2019 werkzeug en

    95/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

    #3 Di hi

  • 8/14/2019 werkzeug en

    96/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

    #3 Di t hi

  • 8/14/2019 werkzeug en

    97/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

    #3 Di t hi

  • 8/14/2019 werkzeug en

    98/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

    #3 Di t hi

  • 8/14/2019 werkzeug en

    99/126

    #3: Dispatchingurl_map = Map([

    Rule('/', endpoint='new_paste'),Rule('/', endpoint='show_paste'),

    Rule('//raw', endpoint='download_paste'),Rule('/pygments.css', endpoint='pygments_style')

    ])

    defapplication(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)

  • 8/14/2019 werkzeug en

    100/126

    #4 Vi

  • 8/14/2019 werkzeug en

    101/126

    #4: Views

    #4 Vi

  • 8/14/2019 werkzeug en

    102/126

    #4: Views

    #4 Vi

  • 8/14/2019 werkzeug en

    103/126

    #4: Views

    #4 Vi

  • 8/14/2019 werkzeug en

    104/126

    #4: Views

    #4 Vi

  • 8/14/2019 werkzeug en

    105/126

    #4: Views

    #5 M d l

  • 8/14/2019 werkzeug en

    106/126

    #5: Model

    #5 M d l

  • 8/14/2019 werkzeug en

    107/126

    #5: Model

    #5 M d l

  • 8/14/2019 werkzeug en

    108/126

    #5: Model

    #6 Templates

  • 8/14/2019 werkzeug en

    109/126

    #6: Templates

    #6 Templates

  • 8/14/2019 werkzeug en

    110/126

    #6: Templates

    #6: Templates

    http://www.w3.org/TR/html4/strict.dtdhttp://www.w3.org/TR/html4/strict.dtd
  • 8/14/2019 werkzeug en

    111/126

    #6: Templates

    #6: Templates

    http://www.w3.org/TR/html4/strict.dtdhttp://www.w3.org/TR/html4/strict.dtd
  • 8/14/2019 werkzeug en

    112/126

    #6: Templates

    http://www.w3.org/TR/html4/strict.dtdhttp://www.w3.org/TR/html4/strict.dtd
  • 8/14/2019 werkzeug en

    113/126

    Development Server

  • 8/14/2019 werkzeug en

    114/126

    Development Server

  • 8/14/2019 werkzeug en

    115/126

    Dump It! In Action

  • 8/14/2019 werkzeug en

    116/126

    Dump It! In Action

    Dump It! In Action

  • 8/14/2019 werkzeug en

    117/126

    Dump It! In Action

    Dump It! In Action

  • 8/14/2019 werkzeug en

    118/126

    Dump It! In Action

  • 8/14/2019 werkzeug en

    119/126

    More Than One Way

  • 8/14/2019 werkzeug en

    120/126

    More Than One Way

    Templates: XML / Text-based / Sandbox

    More Than One Way

  • 8/14/2019 werkzeug en

    121/126

    More Than One Way

    Templates: XML / Text-based / Sandbox

    Daten: SQL / CouchDB / Filesystem

    More Than One Way

  • 8/14/2019 werkzeug en

    122/126

    More Than One Way

    Templates: XML / Text-based / Sandbox

    Daten: SQL / CouchDB / Filesystem

    AJAX: JSON / XML / HTML Fragments

    More Than One Way

  • 8/14/2019 werkzeug en

    123/126

    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

    More Than One Way

  • 8/14/2019 werkzeug en

    124/126

    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

    More Than One Way

  • 8/14/2019 werkzeug en

    125/126

    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

  • 8/14/2019 werkzeug en

    126/126

    http://werkzeug.pocoo.org/http://lucumr.pocoo.org/talks/ltgraz08/

    http://lucumr.pocoo.org/talks/ltgraz08/http://lucumr.pocoo.org/talks/ltgraz08/http://werkzeug.pocoo.org/http://werkzeug.pocoo.org/