web2py talk

47
web2py ideas we stole - ideas we had "Thanks Django, Rails, TG, Flask, Cherripy, Mako, web.py, ...." by Massimo Di Pierro @ DePaul University Thursday, July 14, 2011

Upload: massimo-di-pierro

Post on 11-Mar-2015

2.133 views

Category:

Documents


1 download

DESCRIPTION

This is a talk given at the San Francisco Python Meetup in July 2011

TRANSCRIPT

Page 1: web2py talk

web2pyideas we stole - ideas we had

"Thanks Django, Rails, TG, Flask, Cherripy, Mako, web.py, ...."

by Massimo Di Pierro @ DePaul University

Thursday, July 14, 2011

Page 2: web2py talk

web2py

Thursday, July 14, 2011

Page 3: web2py talk

Main features‣One Instance - Many Applications (hot plug and play)

‣Web based Integrated Development Environment‣Web based Database administration (for each app)‣Each application can connect to multiple Databases‣Writes SQL for you‣Strong on Security (no SQL Injections, XSS, CSRF, ..., audited)‣Built-in ticketing system (logs all errors)‣Runs everywhere (it is written in Python)‣Requires NO Installation (just download and unzip)‣Has no coniguration files and no third party dependencies‣Can run off a USB drive‣Always backward compatible (since 2007 and on...)‣50+ of developers already involved

Thursday, July 14, 2011

Page 4: web2py talk

Admin wizard

new app

upload appdownload app

edit app

Thursday, July 14, 2011

Page 5: web2py talk

Included APIs

‣generation and parsing: HTML / XML / RSS / JSON

‣web services: JSON / JSON-RPC / XML / XML-RPC / AMF

‣document generation WIKI, CSV, RTF, LATEX, PDF

‣10 different SQL dialects and Google App Engine

‣Role based access control with login plugins local, OpenID, OAuth 1 and 2, Janrain, LDAP Consumer + Provider Central Authentication Service

‣sending SMS, accepting Credit Card payments

‣internationalization, cron jobs, multi-tenancy, ...

Thursday, July 14, 2011

Page 6: web2py talk

web2py Architecture

python interpreter

rocket (ssl enabled web server) API for third party servers (Apache,...)

Core LibrariesHTTP request, HTTP response, session, cookies, internationalization,

cache, authentication, authorization, web forms, template language, helpers,database APIs, web services APIs, etc.

User Applications

welcome examples admin

Thursday, July 14, 2011

Page 7: web2py talk

web2py modules

web server (one file)

Thursday, July 14, 2011

Page 8: web2py talk

web2py modules

main wsgi app (one file)

Thursday, July 14, 2011

Page 9: web2py talk

web2py modules

DAL / ORM (one file)

Thursday, July 14, 2011

Page 10: web2py talk

web2py modules

template (one file)

Thursday, July 14, 2011

Page 11: web2py talk

web2py modules

helpers (one file)

Thursday, July 14, 2011

Page 12: web2py talk

web2py Architecture

python interpreter

rocket (ssl enabled web server) API for third party servers (Apache?)

Core LibrariesHTTP request, HTTP response, session, cookies, internationalization,

cache, authentication, authorization, web forms, template language, helpers,database APIs, web services APIs, etc.

User Applications

welcome examples admin user defined

...

ScaffoldingApplication

Thursday, July 14, 2011

Page 13: web2py talk

web2py Architecture

python interpreter

rocket (ssl enabled web server) API for third party servers (Apache?)

Core LibrariesHTTP request, HTTP response, session, cookies, internationalization,

cache, authentication, authorization, web forms, template language, helpers,database APIs, web services APIs, etc.

User Applications

welcome examples admin user defined

... uploaded

Applications can be downloaded and installed

remotely

Thursday, July 14, 2011

Page 14: web2py talk

web2py Architecture

python interpreter

rocket (ssl enabled web server) API for third party servers (Apache?)

Core LibrariesHTTP request, HTTP response, session, cookies, internationalization,

cache, authentication, authorization, web forms, template language, helpers,database APIs, web services APIs, etc.

User Applications

welcome examples admin user defined

uploaded

entire clone of officialweb site with running

examples

...

Thursday, July 14, 2011

Page 15: web2py talk

web2py Architecture

python interpreter

rocket (ssl enabled web server) API for third party servers (Apache?)

Core LibrariesHTTP request, HTTP response, session, cookies, internationalization,

cache, authentication, authorization, web forms, template language, helpers,database APIs, web services APIs, etc.

User Applications

welcome examples admin user defined

... uploaded

web basedIntegrated

DevelopmentEnvironment

Thursday, July 14, 2011

Page 16: web2py talk

web2py Architecture

python interpreter

rocket (ssl enabled web server) API for third party servers (Apache?)

Core LibrariesHTTP request, HTTP response, session, cookies, internationalization,

cache, authentication, authorization, web forms, template language, helpers,database APIs, web services APIs, etc.

User Applications

Thursday, July 14, 2011

Page 17: web2py talk

Admin - Design

plugin_wiki(CMS)

Thursday, July 14, 2011

Page 18: web2py talk

web2py applications

‣No metadata‣Can edit files using shell or web IDE

plug

ins

layoutsplugin_wiki

....Thursday, July 14, 2011

Page 19: web2py talk

Field types include: string, text, integer, double, date, datetime, time, boolean, password, upload, blob, reference, list:string, list:interger, list:reference

Architecture of ApplicationsUser Applications

user application

Models

Controllers

Views

Translations

Static Files (media)

Plugins

Data

appadmin

Description of data representationExample:

db.define_table('friend',Field('name'))

SQL to create and alter table is written automatically as needed.

Thursday, July 14, 2011

Page 20: web2py talk

Role Based Access Control API

db(query).select, db(...).update, db(...).count, db(...).delete, db.table.insert

crud.create, crud.update, crud.select, crud.search, ...

Architecture of ApplicationsUser Applications

user application

Models

Controllers

Views

Translations

Static Files (media)

Plugins

Data

appadmin

Description of application logicExample:

@auth.requires_login()def index(): # http://..../index form = crud.create(db.friend) friends = db(db.friend).select() return locals()

Thursday, July 14, 2011

Page 21: web2py talk

Architecture of ApplicationsUser Applications

user application

Models

Controllers

Views

Translations

Static Files (media)

Plugins

Data

appadmin

Description of data presentationExample:

{{extend 'layout.html'}}<h1>{{=T('My Friends')}}</h1><h2>New Friend</h2>{{=form}}<h2>Current Friends</h2>{{=friends}}

embeds and renders any object in the page full python allowed in {{...python...}} including loops and function definitions.

Thursday, July 14, 2011

Page 22: web2py talk

Architecture of ApplicationsUser Applications

user application

Models

Controllers

Views

Translations

Static Files (media)

Plugins

Data

appadmin

Translations for text in the application

- "my friends"- "i miei amici"- "mis amigos"- "meus amigos"- "mes amis"- "meine freunde"- ...- "marafiki zangu"

Thursday, July 14, 2011

Page 23: web2py talk

Architecture of ApplicationsUser Applications

user application

Models

Controllers

Views

Translations

Static Files (media)

Plugins

Data

appadmin

Static files distributed with the application and/or uplodaded by users:

imagesmoviesaudio filescss filesjs code (scaffold includes jQuery)....

Thursday, July 14, 2011

Page 24: web2py talk

Architecture of ApplicationsUser Applications

user application

Models

Controllers

Views

Translations

Static Files (media)

Plugins

Data

appadmin

Any subset of an application can be packaged and can be distributed. This is called a plugin. Often plugins define components, i.e. functional elements that can be embedded in pages.

Example:plugin_wiki adds a CMS to you appplugin_mobile makes it iphone look-alike

Thursday, July 14, 2011

Page 25: web2py talk

Architecture of ApplicationsUser Applications

user application

Models

Controllers

Views

Translations

Static Files (media)

Plugins

Data

appadmin

Includes:databases (SQlite, MySQL, PostgreSQL, Oracle, MSSQL, DB2, Firebird, MyBase, Informix, Google App Engine)metadata for automatic migrationscache

Thursday, July 14, 2011

Page 26: web2py talk

Architecture of ApplicationsUser Applications

user application

Models

Controllers

Views

Translations

Static Files (media)

Plugins

Data

appadmindefault web based interface to your data

Thursday, July 14, 2011

Page 27: web2py talk

Complete Application ("friends")

db.define_table('friend',Field('name'))

@auth.requires_login()def index(): form = crud.create(db.friend) friends = db(db.friend).select() return locals()

{{extend 'layout.html'}}<h1>{{=T('My Friends')}}</h1><h2>New Friend</h2>{{=form}}<h2>Current Friends</h2>{{=friends}}

File: "friends/models/db_friend.py"

File: "friends/controllers/main.py"

File: "friends/views/main/index.html"

web2py/ applications/ friends/ models/db_friends.py controllers/main.py views/main/index.html ... ...

Thursday, July 14, 2011

Page 28: web2py talk

cd /path/to/demowget -O web2py_src.zip http://web2py.com/examples/static/web2py_src.zipunzip -o -q web2py_src.zipcd web2pypython web2py.py -a hello -p 8000 &cd applicationsmkdir friendscp -r welcome/* friends/cd friends

echo "db.define_table('friend',Field('name'))" > models/db_friends.py

echo "@auth.requires_login()def index(): form = crud.create(db.friend) friends = db(db.friend).select() return locals()" > controllers/main.py

mkdir views/mainecho "{{extend 'layout.html'}}<h1>{{=T('My Friends')}}</h1><h2>New Friend</h2>{{=form}}<h2>Current Friends</h2>{{=friends}}" > views/main/index.html

Thursday, July 14, 2011

Page 29: web2py talk

Controllers

def index(request): entry_id = request.GET['entry_id'] entry = Entry.objects.get(pk=entry_id) output = entry.name return HttpResponse(output)

Django (view in MTV)

def index(): entry_id = request.get_vars.entry_id or redirect(URL('error')) entry = Entry(entry_id) output = entry.name return dict(output=output) # defaults to generic template

web2py (controller in MVC)

Thursday, July 14, 2011

Page 30: web2py talk

Routing (in, out, onerror)

urlpatterns = patterns('', (r'^articles/$', 'news.views.index'), (r'^articles/(\d{4})/$', 'news.views.read'),)

Django (urls.py)

routes_in = [ (r'articles/', '/news/default/index'), (r'articles/(\d{4})', '/news/default/read/\1'), (r'articles/$year', '/news/default/read/$year'), (r'127.0.0.*:http://domain.com articles/(\d{4})','/news2/default/read/\1')]

routes_out = [...]

routes_onerror = [ (r'init/400', r'/init/default/login'), (r'*/*', r'/init/static/fail.html')]

web2py (routes.py) - ALWAYS OPTIONAL

Thursday, July 14, 2011

Page 31: web2py talk

Templates

<%inherit file="base.html"/>

<%def name="makerow(k)"> <tr> <td>${k}</td> <td>${k*k}</td> </tr></%def>

<% numbers = range(0,10)%><table> % for k in numbers: ${makerow(k)} % endfor</table>

Mako (template in MTV)

{{extend "base.html}}

{{ def makerow(k): }} <tr> <td>{{=k}}</td> <td>{{=k*k}}</td> </tr>{{ return }}

{{ numbers = range(0,10)}}<table> {{ for k in numbers: }} {{ makerow(k) }} {{ pass }}</table>

‣In web2py, no indentation requirement ‣Django-like blocks, output always escaped

web2py (template or view in MVC)

Thursday, July 14, 2011

Page 32: web2py talk

App-Admin

‣Django "admin" designed for public access‣web2py "app-admin" designed for administrator access only‣CRUD components from appadmin can be embedded in apps‣web2py "app-admin" not to be confused with web2py's "admin"

Django web2py

Thursday, July 14, 2011

Page 33: web2py talk

Models

class Entry(models.Model): name = models.CharField(max_length=255,null=False) body = models.TextField() image = models.ImageField() pub_date = models.DateTimeField() rating = models.IntegerField()

Django (model)

Entry = db.define_table('entry', Field('name',length=255,notnull=True), Field('body','text'), Field('image','upload',requires=IS_IMAGE()), Field('pub_date','datetime'), Field('rating','integer')]

web2py (model)

Thursday, July 14, 2011

Page 34: web2py talk

Queries

q = Entry.objects.filter(headline__startswith="What")q = q.filter(pub_date__lte=datetime.now())q = q.exclude(body__icontains="food")print q

Django (model)

q = Entry.headline.startswith("What")q = q & (Entry.pub_date<datetime.now())q = q & (!Entry.body.contains("food"))print db(q).select()

web2py (model)

Thursday, July 14, 2011

Page 35: web2py talk

Thread Locals

from flask import request

with app.request_context(environ): assert request.method == 'POST'

Flask (proxies to objects that are local to a specific context)

from gluon import current

assert current.request.env.http_method == 'POST'

‣In Flask "request" is a proxy to a thread local object. In web2py "request" is a thread local object cotained into a "current"‣"gluon" is the library that contains web2py.

web2py (thread-locals)

Thursday, July 14, 2011

Page 36: web2py talk

Multi-version / No-conflicts

import multiversionmultiversion.require_version('mylib', '1.0')import mylib

https://github.com/mitsuhiko/multiversion

# app 1import mylib # from applications/app1/modules/

# app 2import mylib # from applications/app2/modules/

‣Each app ships with its own modules/ folder.‣Not added to sys.path‣No conflicts‣One web2py instance

web2py (each app can ship with its own version of libraries)

Thursday, July 14, 2011

Page 37: web2py talk

Role based Access Control

@auth.requires_login()@auth.requires_membership(role='secret agent')@auth.requires_permission('kill', 'bad_people', all)def test(): return 'done'

For any function

Thursday, July 14, 2011

Page 38: web2py talk

Web Services

@[email protected]@[email protected]@[email protected]('domain')def add(a,b): return a+b

For any function

Thursday, July 14, 2011

Page 39: web2py talk

Record Versioning

db._common_fields.append(auth.signature)crud.settings.update_onaccept(crud.archive)

Any method

‣Store all previous version of each record with names of the user who changed and timestamp of the change

Thursday, July 14, 2011

Page 40: web2py talk

Modularrity withDigintally Signed URLs

{{=LOAD('plugin','component',user_signature=True)}}

In page

‣web2py can sign all URLs (links, ajax callbacks, components) so the called action delegates security the caller

web page

componentcomponent

component

@auth.requires_signature()def component(): return 'component'

In controller

Thursday, July 14, 2011

Page 41: web2py talk

Federated Authentication

auth = Auth(db, cas_provider = 'http://.../one/default/user/cas')

Other apps

auth = Auth(db)

App "one"

‣Any application can be both a provider and a client for CAS 2.0‣Other federated authentication mechanism available as clients

Thursday, July 14, 2011

Page 42: web2py talk

Multi-tenancy

‣All records are filtered based on tenant ownship‣Tenant identified for example by domain name‣Tables can be shared between tenant or not‣http://domain1 or http://domain2 (same app, different data)

db._common_fields.append(Field('request_tenant',default=request.env.host_name))

Any model

Thursday, July 14, 2011

Page 43: web2py talk

GAE Deployment

upload to GAE

Thursday, July 14, 2011

Page 44: web2py talk

Web translation

english

italian

Thursday, July 14, 2011

Page 45: web2py talk

Error logging

error occurred 3 times

oops: 1/0

Thursday, July 14, 2011

Page 46: web2py talk

Who uses web2py?

3000 registered users

Thursday, July 14, 2011

Page 47: web2py talk

Conclusions

‣web2py has been abround for since 2007‣+50% was rewritten in 2010 while mantaining backward compatibility‣Some like it, some find it useful

‣Give it a try!

Thursday, July 14, 2011