api docs
- web.application
- web.contrib.template
- web.db
- web.debugerror
- web.form
- web.http
- web.httpserver
- web.net
- web.session
- web.template
- web.utils
- web.webapi
- web.webopenid
- web.wsgi
module web.application
Web application (from web.py)
class application(self, mapping=(), fvars={}, autoreload=None)
Application to delegate requests based on path.
>>> urls = ("/hello", "hello")
>>> app = application(urls, globals())
>>> class hello:
... def GET(self): return "hello"
>>>
>>> app.request("/hello").data
'hello'
method add_mapping(self, pattern, classname)
method add_processor(self, processor)
Adds a processor to the application.
>>> urls = ("/(.*)", "echo")
>>> app = application(urls, globals())
>>> class echo:
... def GET(self, name): return name
...
>>>
>>> def hello(handler): return "hello, " + handler()
...
>>> app.add_processor(hello)
>>> app.request("/web.py").data
'hello, web.py'
method browser(self)
method cgirun(self, *middleware)
Return a CGI handler. This is mostly useful with Google App Engine. There you can just do:
main = app.cgirun()
method gaerun(self, *middleware)
Starts the program in a way that will work with Google app engine, no matter which version you are using (2.5 / 2.7)
If it is 2.5, just normally start it with app.gaerun()
If it is 2.7, make sure to change the app.yaml handler to point to the global variable that contains the result of app.gaerun()
For example:
in app.yaml (where code.py is where the main code is located)
handlers:
- url: /.*
script: code.app
Make sure that the app variable is globally accessible
method get_parent_app(self)
method handle(self)
method handle_with_processors(self)
method init_mapping(self, mapping)
method internalerror(self)
Returns HTTPError with '500 internal error' message
method load(self, env)
Initializes ctx using env.
method notfound(self)
Returns HTTPError with '404 not found' message
method request(self, localpart='/', method='GET', data=None, host='0.0.0.0:8080', headers=None, https=False, **kw)
Makes request to this application for the specified path and method. Response will be a storage object with data, status and headers.
>>> urls = ("/hello", "hello")
>>> app = application(urls, globals())
>>> class hello:
... def GET(self):
... web.header('Content-Type', 'text/plain')
... return "hello"
...
>>> response = app.request("/hello")
>>> response.data
'hello'
>>> response.status
'200 OK'
>>> response.headers['Content-Type']
'text/plain'
To use https, use https=True.
>>> urls = ("/redirect", "redirect")
>>> app = application(urls, globals())
>>> class redirect:
... def GET(self): raise web.seeother("/foo")
...
>>> response = app.request("/redirect")
>>> response.headers['Location']
'http://0.0.0.0:8080/foo'
>>> response = app.request("/redirect", https=True)
>>> response.headers['Location']
'https://0.0.0.0:8080/foo'
The headers argument specifies HTTP headers as a mapping object such as a dict.
>>> urls = ('/ua', 'uaprinter')
>>> class uaprinter:
... def GET(self):
... return 'your user-agent is ' + web.ctx.env['HTTP_USER_AGENT']
...
>>> app = application(urls, globals())
>>> app.request('/ua', headers = {
... 'User-Agent': 'a small jumping bean/1.0 (compatible)'
... }).data
'your user-agent is a small jumping bean/1.0 (compatible)'
method run(self, *middleware)
Starts handling requests. If called in a CGI or FastCGI context, it will follow that protocol. If called from the command line, it will start an HTTP server on the port named in the first command line argument, or, if there is no argument, on port 8080.
middleware
is a list of WSGI middleware which is applied to the resulting WSGI
function.
method stop(self)
Stops the http server started by run.
method wsgifunc(self, *middleware)
Returns a WSGI-compatible function for this application.
class auto_application(self)
Application similar to application
but urls are constructed
automatically using metaclass.
>>> app = auto_application()
>>> class hello(app.page):
... def GET(self): return "hello, world"
...
>>> class foo(app.page):
... path = '/foo/.*'
... def GET(self): return "foo"
>>> app.request("/hello").data
'hello, world'
>>> app.request('/foo/bar').data
'foo'
method add_mapping(self, pattern, classname)
method add_processor(self, processor)
Adds a processor to the application.
>>> urls = ("/(.*)", "echo")
>>> app = application(urls, globals())
>>> class echo:
... def GET(self, name): return name
...
>>>
>>> def hello(handler): return "hello, " + handler()
...
>>> app.add_processor(hello)
>>> app.request("/web.py").data
'hello, web.py'
method browser(self)
method cgirun(self, *middleware)
Return a CGI handler. This is mostly useful with Google App Engine. There you can just do:
main = app.cgirun()
method gaerun(self, *middleware)
Starts the program in a way that will work with Google app engine, no matter which version you are using (2.5 / 2.7)
If it is 2.5, just normally start it with app.gaerun()
If it is 2.7, make sure to change the app.yaml handler to point to the global variable that contains the result of app.gaerun()
For example:
in app.yaml (where code.py is where the main code is located)
handlers:
- url: /.*
script: code.app
Make sure that the app variable is globally accessible
method get_parent_app(self)
method handle(self)
method handle_with_processors(self)
method init_mapping(self, mapping)
method internalerror(self)
Returns HTTPError with '500 internal error' message
method load(self, env)
Initializes ctx using env.
method notfound(self)
Returns HTTPError with '404 not found' message
method request(self, localpart='/', method='GET', data=None, host='0.0.0.0:8080', headers=None, https=False, **kw)
Makes request to this application for the specified path and method. Response will be a storage object with data, status and headers.
>>> urls = ("/hello", "hello")
>>> app = application(urls, globals())
>>> class hello:
... def GET(self):
... web.header('Content-Type', 'text/plain')
... return "hello"
...
>>> response = app.request("/hello")
>>> response.data
'hello'
>>> response.status
'200 OK'
>>> response.headers['Content-Type']
'text/plain'
To use https, use https=True.
>>> urls = ("/redirect", "redirect")
>>> app = application(urls, globals())
>>> class redirect:
... def GET(self): raise web.seeother("/foo")
...
>>> response = app.request("/redirect")
>>> response.headers['Location']
'http://0.0.0.0:8080/foo'
>>> response = app.request("/redirect", https=True)
>>> response.headers['Location']
'https://0.0.0.0:8080/foo'
The headers argument specifies HTTP headers as a mapping object such as a dict.
>>> urls = ('/ua', 'uaprinter')
>>> class uaprinter:
... def GET(self):
... return 'your user-agent is ' + web.ctx.env['HTTP_USER_AGENT']
...
>>> app = application(urls, globals())
>>> app.request('/ua', headers = {
... 'User-Agent': 'a small jumping bean/1.0 (compatible)'
... }).data
'your user-agent is a small jumping bean/1.0 (compatible)'
method run(self, *middleware)
Starts handling requests. If called in a CGI or FastCGI context, it will follow that protocol. If called from the command line, it will start an HTTP server on the port named in the first command line argument, or, if there is no argument, on port 8080.
middleware
is a list of WSGI middleware which is applied to the resulting WSGI
function.
method stop(self)
Stops the http server started by run.
method wsgifunc(self, *middleware)
Returns a WSGI-compatible function for this application.
class subdir_application(self, mapping=(), fvars={}, autoreload=None)
Application to delegate requests based on path.
>>> urls = ("/hello", "hello")
>>> app = application(urls, globals())
>>> class hello:
... def GET(self): return "hello"
>>>
>>> app.request("/hello").data
'hello'
method add_mapping(self, pattern, classname)
method add_processor(self, processor)
Adds a processor to the application.
>>> urls = ("/(.*)", "echo")
>>> app = application(urls, globals())
>>> class echo:
... def GET(self, name): return name
...
>>>
>>> def hello(handler): return "hello, " + handler()
...
>>> app.add_processor(hello)
>>> app.request("/web.py").data
'hello, web.py'
method browser(self)
method cgirun(self, *middleware)
Return a CGI handler. This is mostly useful with Google App Engine. There you can just do:
main = app.cgirun()
method gaerun(self, *middleware)
Starts the program in a way that will work with Google app engine, no matter which version you are using (2.5 / 2.7)
If it is 2.5, just normally start it with app.gaerun()
If it is 2.7, make sure to change the app.yaml handler to point to the global variable that contains the result of app.gaerun()
For example:
in app.yaml (where code.py is where the main code is located)
handlers:
- url: /.*
script: code.app
Make sure that the app variable is globally accessible
method get_parent_app(self)
method handle(self)
method handle_with_processors(self)
method init_mapping(self, mapping)
method internalerror(self)
Returns HTTPError with '500 internal error' message
method load(self, env)
Initializes ctx using env.
method notfound(self)
Returns HTTPError with '404 not found' message
method request(self, localpart='/', method='GET', data=None, host='0.0.0.0:8080', headers=None, https=False, **kw)
Makes request to this application for the specified path and method. Response will be a storage object with data, status and headers.
>>> urls = ("/hello", "hello")
>>> app = application(urls, globals())
>>> class hello:
... def GET(self):
... web.header('Content-Type', 'text/plain')
... return "hello"
...
>>> response = app.request("/hello")
>>> response.data
'hello'
>>> response.status
'200 OK'
>>> response.headers['Content-Type']
'text/plain'
To use https, use https=True.
>>> urls = ("/redirect", "redirect")
>>> app = application(urls, globals())
>>> class redirect:
... def GET(self): raise web.seeother("/foo")
...
>>> response = app.request("/redirect")
>>> response.headers['Location']
'http://0.0.0.0:8080/foo'
>>> response = app.request("/redirect", https=True)
>>> response.headers['Location']
'https://0.0.0.0:8080/foo'
The headers argument specifies HTTP headers as a mapping object such as a dict.
>>> urls = ('/ua', 'uaprinter')
>>> class uaprinter:
... def GET(self):
... return 'your user-agent is ' + web.ctx.env['HTTP_USER_AGENT']
...
>>> app = application(urls, globals())
>>> app.request('/ua', headers = {
... 'User-Agent': 'a small jumping bean/1.0 (compatible)'
... }).data
'your user-agent is a small jumping bean/1.0 (compatible)'
method run(self, *middleware)
Starts handling requests. If called in a CGI or FastCGI context, it will follow that protocol. If called from the command line, it will start an HTTP server on the port named in the first command line argument, or, if there is no argument, on port 8080.
middleware
is a list of WSGI middleware which is applied to the resulting WSGI
function.
method stop(self)
Stops the http server started by run.
method wsgifunc(self, *middleware)
Returns a WSGI-compatible function for this application.
class subdomain_application(self, mapping=(), fvars={}, autoreload=None)
Application to delegate requests based on the host.
>>> urls = ("/hello", "hello")
>>> app = application(urls, globals())
>>> class hello:
... def GET(self): return "hello"
>>>
>>> mapping = (r"hello\.example\.com", app)
>>> app2 = subdomain_application(mapping)
>>> app2.request("/hello", host="hello.example.com").data
'hello'
>>> response = app2.request("/hello", host="something.example.com")
>>> response.status
'404 Not Found'
>>> response.data
'not found'
method add_mapping(self, pattern, classname)
method add_processor(self, processor)
Adds a processor to the application.
>>> urls = ("/(.*)", "echo")
>>> app = application(urls, globals())
>>> class echo:
... def GET(self, name): return name
...
>>>
>>> def hello(handler): return "hello, " + handler()
...
>>> app.add_processor(hello)
>>> app.request("/web.py").data
'hello, web.py'
method browser(self)
method cgirun(self, *middleware)
Return a CGI handler. This is mostly useful with Google App Engine. There you can just do:
main = app.cgirun()
method gaerun(self, *middleware)
Starts the program in a way that will work with Google app engine, no matter which version you are using (2.5 / 2.7)
If it is 2.5, just normally start it with app.gaerun()
If it is 2.7, make sure to change the app.yaml handler to point to the global variable that contains the result of app.gaerun()
For example:
in app.yaml (where code.py is where the main code is located)
handlers:
- url: /.*
script: code.app
Make sure that the app variable is globally accessible
method get_parent_app(self)
method handle(self)
method handle_with_processors(self)
method init_mapping(self, mapping)
method internalerror(self)
Returns HTTPError with '500 internal error' message
method load(self, env)
Initializes ctx using env.
method notfound(self)
Returns HTTPError with '404 not found' message
method request(self, localpart='/', method='GET', data=None, host='0.0.0.0:8080', headers=None, https=False, **kw)
Makes request to this application for the specified path and method. Response will be a storage object with data, status and headers.
>>> urls = ("/hello", "hello")
>>> app = application(urls, globals())
>>> class hello:
... def GET(self):
... web.header('Content-Type', 'text/plain')
... return "hello"
...
>>> response = app.request("/hello")
>>> response.data
'hello'
>>> response.status
'200 OK'
>>> response.headers['Content-Type']
'text/plain'
To use https, use https=True.
>>> urls = ("/redirect", "redirect")
>>> app = application(urls, globals())
>>> class redirect:
... def GET(self): raise web.seeother("/foo")
...
>>> response = app.request("/redirect")
>>> response.headers['Location']
'http://0.0.0.0:8080/foo'
>>> response = app.request("/redirect", https=True)
>>> response.headers['Location']
'https://0.0.0.0:8080/foo'
The headers argument specifies HTTP headers as a mapping object such as a dict.
>>> urls = ('/ua', 'uaprinter')
>>> class uaprinter:
... def GET(self):
... return 'your user-agent is ' + web.ctx.env['HTTP_USER_AGENT']
...
>>> app = application(urls, globals())
>>> app.request('/ua', headers = {
... 'User-Agent': 'a small jumping bean/1.0 (compatible)'
... }).data
'your user-agent is a small jumping bean/1.0 (compatible)'
method run(self, *middleware)
Starts handling requests. If called in a CGI or FastCGI context, it will follow that protocol. If called from the command line, it will start an HTTP server on the port named in the first command line argument, or, if there is no argument, on port 8080.
middleware
is a list of WSGI middleware which is applied to the resulting WSGI
function.
method stop(self)
Stops the http server started by run.
method wsgifunc(self, *middleware)
Returns a WSGI-compatible function for this application.
function loadhook(h)
Converts a load hook into an application processor.
>>> app = auto_application()
>>> def f(): "something done before handling request"
...
>>> app.add_processor(loadhook(f))
function unloadhook(h)
Converts an unload hook into an application processor.
>>> app = auto_application()
>>> def f(): "something done after handling request"
...
>>> app.add_processor(unloadhook(f))
function autodelegate(prefix='')
Returns a method that takes one argument and calls the method named prefix+arg,
calling notfound()
if there isn't one. Example:
urls = ('/prefs/(.*)', 'prefs')
class prefs:
GET = autodelegate('GET_')
def GET_password(self): pass
def GET_privacy(self): pass
GET_password
would get called for /prefs/password
while GET_privacy
for
GET_privacy
gets called for /prefs/privacy
.
If a user visits /prefs/password/change
then GET_password(self, '/change')
is called.
module web.contrib.template
Interface to various templating engines.
class render_cheetah(self, path)
Rendering interface to Cheetah Templates.
Example:
render = render_cheetah('templates')
render.hello(name="cheetah")
class render_genshi(self, *a, **kwargs)
Rendering interface genshi templates. Example:
for xml/html templates.
render = render_genshi(['templates/'])
render.hello(name='genshi')
For text templates:
render = render_genshi(['templates/'], type='text')
render.hello(name='genshi')
class render_mako(self, *a, **kwargs)
Rendering interface to Mako Templates.
Example:
render = render_mako(directories=['templates'])
render.hello(name="mako")
class cache(self, render)
Cache for any rendering interface.
Example:
render = cache(render_cheetah("templates/"))
render.hello(name='cache')
module web.db
Database API (part of web.py)
type UnknownParamstyle
raised for unsupported db paramstyles
(currently supported: qmark, numeric, format, pyformat)
type UnknownDB
raised for unsupported dbms
type TransactionError
function sqllist(lst)
Converts the arguments for use in something like a WHERE clause.
>>> sqllist(['a', 'b'])
'a, b'
>>> sqllist('a')
'a'
>>> sqllist(u'abc')
u'abc'
function sqlors(left, lst)
left is a SQL clause like
tablename.arg = `
and lst
is a list of values. Returns a reparam-style
pair featuring the SQL that ORs together the clause
for each item in the lst.
>>> sqlors('foo = ', [])
<sql: '1=2'>
>>> sqlors('foo = ', [1])
<sql: 'foo = 1'>
>>> sqlors('foo = ', 1)
<sql: 'foo = 1'>
>>> sqlors('foo = ', [1,2,3])
<sql: '(foo = 1 OR foo = 2 OR foo = 3 OR 1=2)'>
function reparam(string_, dictionary)
Takes a string and a dictionary and interpolates the string
using values from the dictionary. Returns an SQLQuery
for the result.
>>> reparam("s = $s", dict(s=True))
<sql: "s = 't'">
>>> reparam("s IN $s", dict(s=[1, 2]))
<sql: 's IN (1, 2)'>
function sqlquote(a)
Ensures a
is quoted properly for use in a SQL query.
>>> 'WHERE x = ' + sqlquote(True) + ' AND y = ' + sqlquote(3)
<sql: "WHERE x = 't' AND y = 3">
>>> 'WHERE x = ' + sqlquote(True) + ' AND y IN ' + sqlquote([2, 3])
<sql: "WHERE x = 't' AND y IN (2, 3)">
type SQLQuery(self, items=None)
You can pass this sort of thing as a clause in any db function.
Otherwise, you can pass a dictionary to the keyword argument vars
and the function will call reparam for you.
Internally, consists of items
, which is a list of strings and
SQLParams, which get concatenated to produce the actual query.
method append(self, value)
function join(items, sep=' ', prefix=None, suffix=None, target=None)
Joins multiple queries.
SQLQuery.join(['a', 'b'], ', ') <sql: 'a, b'>
Optinally, prefix and suffix arguments can be provided.
SQLQuery.join(['a', 'b'], ', ', prefix='(', suffix=')') <sql: '(a, b)'>
If target argument is provided, the items are appended to target instead of creating a new SQLQuery.
method query(self, paramstyle=None)
Returns the query part of the sql query.
q = SQLQuery(["SELECT * FROM test WHERE name=", SQLParam('joe')]) q.query() 'SELECT * FROM test WHERE name=%s' q.query(paramstyle='qmark') 'SELECT * FROM test WHERE name=?'
method values(self)
Returns the values of the parameters used in the sql query.
q = SQLQuery(["SELECT * FROM test WHERE name=", SQLParam('joe')]) q.values() ['joe']
type SQLParam(self, value)
Parameter in SQLQuery.
>>> q = SQLQuery(["SELECT * FROM test WHERE name=", SQLParam("joe")])
>>> q
<sql: "SELECT * FROM test WHERE name='joe'">
>>> q.query()
'SELECT * FROM test WHERE name=%s'
>>> q.values()
['joe']
method get_marker(self, paramstyle='pyformat')
method sqlquery(self)
type sqlparam(self, value)
Parameter in SQLQuery.
>>> q = SQLQuery(["SELECT * FROM test WHERE name=", SQLParam("joe")])
>>> q
<sql: "SELECT * FROM test WHERE name='joe'">
>>> q.query()
'SELECT * FROM test WHERE name=%s'
>>> q.values()
['joe']
method get_marker(self, paramstyle='pyformat')
method sqlquery(self)
class SQLLiteral(self, v)
Protects a string from sqlquote
.
>>> sqlquote('NOW()')
<sql: "'NOW()'">
>>> sqlquote(SQLLiteral('NOW()'))
<sql: 'NOW()'>
class sqlliteral(self, v)
Protects a string from sqlquote
.
>>> sqlquote('NOW()')
<sql: "'NOW()'">
>>> sqlquote(SQLLiteral('NOW()'))
<sql: 'NOW()'>
function database(dburl=None, **params)
Creates appropriate database using params.
Pooling will be enabled if DBUtils module is available. Pooling can be disabled by passing pooling=False in params.
class DB(self, db_module, keywords)
Database
property ctx
method delete(self, table, where, using=None, vars=None, _test=False)
Deletes from table
with clauses where
and using
.
>>> db = DB(None, {})
>>> name = 'Joe'
>>> db.delete('foo', where='name = $name', vars=locals(), _test=True)
<sql: "DELETE FROM foo WHERE name = 'Joe'">
method gen_clause(self, sql, val, vars)
method insert(self, tablename, seqname=None, _test=False, **values)
Inserts values
into tablename
. Returns current sequence ID.
Set seqname
to the ID if it's not the default, or to False
if there isn't one.
>>> db = DB(None, {})
>>> q = db.insert('foo', name='bob', age=2, created=SQLLiteral('NOW()'), _test=True)
>>> q
<sql: "INSERT INTO foo (age, name, created) VALUES (2, 'bob', NOW())">
>>> q.query()
'INSERT INTO foo (age, name, created) VALUES (%s, %s, NOW())'
>>> q.values()
[2, 'bob']
method multiple_insert(self, tablename, values, seqname=None, _test=False)
Inserts multiple rows into tablename
. The values
must be a list of dictioanries,
one for each row to be inserted, each with the same set of keys.
Returns the list of ids of the inserted rows.
Set seqname
to the ID if it's not the default, or to False
if there isn't one.
>>> db = DB(None, {})
>>> db.supports_multiple_insert = True
>>> values = [{"name": "foo", "email": "foo@example.com"}, {"name": "bar", "email": "bar@example.com"}]
>>> db.multiple_insert('person', values=values, _test=True)
<sql: "INSERT INTO person (name, email) VALUES ('foo', 'foo@example.com'), ('bar', 'bar@example.com')">
method query(self, sql_query, vars=None, processed=False, _test=False)
Execute SQL query sql_query
using dictionary vars
to interpolate it.
If processed=True
, vars
is a reparam
-style list to use
instead of interpolating.
>>> db = DB(None, {})
>>> db.query("SELECT * FROM foo", _test=True)
<sql: 'SELECT * FROM foo'>
>>> db.query("SELECT * FROM foo WHERE x = $x", vars=dict(x='f'), _test=True)
<sql: "SELECT * FROM foo WHERE x = 'f'">
>>> db.query("SELECT * FROM foo WHERE x = " + sqlquote('f'), _test=True)
<sql: "SELECT * FROM foo WHERE x = 'f'">
method select(self, tables, vars=None, what='*', where=None, order=None, group=None, limit=None, offset=None, _test=False)
Selects what
from tables
with clauses where
, order
,
group
, limit
, and offset
. Uses vars to interpolate.
Otherwise, each clause can be a SQLQuery.
>>> db = DB(None, {})
>>> db.select('foo', _test=True)
<sql: 'SELECT * FROM foo'>
>>> db.select(['foo', 'bar'], where="foo.bar_id = bar.id", limit=5, _test=True)
<sql: 'SELECT * FROM foo, bar WHERE foo.bar_id = bar.id LIMIT 5'>
>>> db.select('foo', where={'id': 5}, _test=True)
<sql: 'SELECT * FROM foo WHERE id = 5'>
method sql_clauses(self, what, tables, where, group, order, limit, offset)
method transaction(self)
Start a transaction.
method update(self, tables, where, vars=None, _test=False, **values)
Update tables
with clause where
(interpolated using vars
)
and setting values
.
>>> db = DB(None, {})
>>> name = 'Joseph'
>>> q = db.update('foo', where='name = $name', name='bob', age=2,
... created=SQLLiteral('NOW()'), vars=locals(), _test=True)
>>> q
<sql: "UPDATE foo SET age = 2, name = 'bob', created = NOW() WHERE name = 'Joseph'">
>>> q.query()
'UPDATE foo SET age = %s, name = %s, created = NOW() WHERE name = %s'
>>> q.values()
[2, 'bob', 'Joseph']
method where(self, table, what='*', order=None, group=None, limit=None, offset=None, _test=False, **kwargs)
Selects from table
where keys are equal to values in kwargs
.
>>> db = DB(None, {})
>>> db.where('foo', bar_id=3, _test=True)
<sql: 'SELECT * FROM foo WHERE bar_id = 3'>
>>> db.where('foo', source=2, crust='dewey', _test=True)
<sql: "SELECT * FROM foo WHERE source = 2 AND crust = 'dewey'">
>>> db.where('foo', _test=True)
<sql: 'SELECT * FROM foo'>
module web.debugerror
pretty debug errors (part of web.py)
portions adapted from Django function A replacement for (Based on the beautiful 500 page from Django,
designed by Wilson Miner.) function function Wraps the old Emails contain a normal text traceback as well as an
attachment containing the nice module HTML forms
(part of web.py) debugerror()
internalerror
that presents a nice page with lots
of debug information for the programmer. djangoerror()
emailerrors(to_address, olderror, from_address=None)
internalerror
handler (pass as olderror
) to
additionally email all errors to to_address
, to aid in
debugging production websites.debugerror
page. web.form
type AttributeList
List of atributes of input.
a = AttributeList(type='text', name='x', value=20) a <attrs: 'type="text" name="x" value="20"'>
method copy(self)
type Button(self, name, *validators, **attrs)
HTML Button.
Button("save").render() u'' Button("action", value="save", html="Save Changes").render() u''
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Checkbox(self, name, *validators, **attrs)
Checkbox input.
Checkbox('foo', value='bar', checked=True).render() u'' Checkbox('foo', value='bar').render() u'' c = Checkbox('foo', value='bar') c.validate('on') True c.render() u''
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Dropdown(self, name, args, *validators, **attrs)
Dropdown/select input.
Dropdown(name='foo', args=['a', 'b', 'c'], value='b').render() u'\n' Dropdown(name='foo', args=[('a', 'aa'), ('b', 'bb'), ('c', 'cc')], value='b').render() u'\n'
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type File(self, name, *validators, **attrs)
File input.
File(name='f').render() u''
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Form(self, *inputs, **kw)
HTML form.
>>> f = Form(Textbox("x"))
>>> f.render()
u'<table>\n <tr><th><label for="x">x</label></th><td><input type="text" id="x" name="x"/></td></tr>\n</table>'
method fill(self, source=None, **kw)
method get(self, i, default=None)
method render(self)
method render_css(self)
method rendernote(self, note)
method validates(self, source=None, _validate=True, **kw)
type GroupedDropdown(self, name, args, *validators, **attrs)
Grouped Dropdown/select input.
GroupedDropdown(name='cartype', args=(('Swedish Cars', ('Volvo', 'Saab')), ('German Cars', ('Mercedes', 'Audi'))), value='Audi').render() u'\n' GroupedDropdown(name='cartype', args=(('Swedish Cars', (('v', 'Volvo'), ('s', 'Saab'))), ('German Cars', (('m', 'Mercedes'), ('a', 'Audi')))), value='a').render() u'\n'
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Hidden(self, name, *validators, **attrs)
Hidden Input.
Hidden(name='foo', value='bar').render() u''
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Input(self, name, *validators, **attrs)
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Password(self, name, *validators, **attrs)
Password input.
Password(name='password', value='secret').render() u''
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Radio(self, name, args, *validators, **attrs)
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Textarea(self, name, *validators, **attrs)
Textarea input.
Textarea(name='foo', value='bar').render() u''
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
type Textbox(self, name, *validators, **attrs)
Textbox input.
Textbox(name='foo', value='bar').render() u'' Textbox(name='foo', value=0).render() u''
method addatts(self)
method get_default_id(self)
method get_type(self)
method get_value(self)
method is_hidden(self)
method render(self)
method rendernote(self, note)
method set_value(self, value)
method validate(self, value)
class Validator(self, msg, test, jstest=None)
method valid(self, value)
function attrget(obj, attr, value=None)
class regexp(self, rexp, msg)
method valid(self, value)
module web.http
HTTP Utilities (from web.py)
function expires(delta)
Outputs an Expires
header for delta
from now.
delta
is a timedelta
object or a number of seconds.
function lastmodified(date_obj)
Outputs a Last-Modified
header for datetime
.
function prefixurl(base='')
Sorry, this function is really difficult to explain. Maybe some other time.
function modified(date=None, etag=None)
Checks to see if the page has been modified since the version in the requester's cache.
When you publish pages, you can include Last-Modified
and ETag
with the date the page was last modified and an opaque token for
the particular version, respectively. When readers reload the page,
the browser sends along the modification date and etag value for
the version it has in its cache. If the page hasn't changed,
the server can just return 304 Not Modified
and not have to
send the whole page again.
This function takes the last-modified date date
and the ETag etag
and checks the headers to see if they match. If they do, it returns
True
, or otherwise it raises NotModified error. It also sets
Last-Modified
and ETag
output headers.
function changequery(query=None, **kw)
Imagine you're at /foo?a=1&b=2
. Then changequery(a=3)
will return
/foo?a=3&b=2
-- the same URL but with the arguments you requested
changed.
function url(path=None, doseq=False, **kw)
Makes url by concatenating web.ctx.homepath and path and the query string created using the arguments.
function profiler(app)
Outputs basic profiling information at the bottom of each response.
module web.httpserver
function runsimple(func, server_address=('0.0.0.0', 8080))
Runs CherryPy WSGI server hosting WSGI app func
.
The directory static/
is hosted statically.
module web.net
Network Utilities (from web.py)
function validipaddr(address)
Returns True if address
is a valid IPv4 address.
>>> validipaddr('192.168.1.1')
True
>>> validipaddr('192.168.1.800')
False
>>> validipaddr('192.168.1')
False
function validip6addr(address)
Returns True if address
is a valid IPv6 address.
>>> validip6addr('::')
True
>>> validip6addr('aaaa:bbbb:cccc:dddd::1')
True
>>> validip6addr('1:2:3:4:5:6:7:8:9:10')
False
>>> validip6addr('12:10')
False
function validipport(port)
Returns True if port
is a valid IPv4 port.
>>> validipport('9000')
True
>>> validipport('foo')
False
>>> validipport('1000000')
False
function validip(ip, defaultaddr='0.0.0.0', defaultport=8080)
Returns (ip_address, port)
from string ip_addr_port
validip('1.2.3.4') ('1.2.3.4', 8080) validip('80') ('0.0.0.0', 80) validip('192.168.0.1:85') ('192.168.0.1', 85) validip('::') ('::', 8080) validip('[::]:88') ('::', 88) validip('[::1]:80') ('::1', 80)
function validaddr(string_)
Returns either (ipaddress, port) or "/path/to/socket" from string
>>> validaddr('/path/to/socket')
'/path/to/socket'
>>> validaddr('8000')
('0.0.0.0', 8000)
>>> validaddr('127.0.0.1')
('127.0.0.1', 8080)
>>> validaddr('127.0.0.1:8000')
('127.0.0.1', 8000)
>>> validip('[::1]:80')
('::1', 80)
>>> validaddr('fff')
Traceback (most recent call last):
...
ValueError: fff is not a valid IP address/port
function urlquote(val)
Quotes a string for use in a URL.
>>> urlquote('://?f=1&j=1')
'%3A//%3Ff%3D1%26j%3D1'
>>> urlquote(None)
''
>>> urlquote(u'\u203d')
'%E2%80%BD'
function httpdate(date_obj)
Formats a datetime object for use in HTTP headers.
>>> import datetime
>>> httpdate(datetime.datetime(1970, 1, 1, 1, 1, 1))
'Thu, 01 Jan 1970 01:01:01 GMT'
function parsehttpdate(string_)
Parses an HTTP date into a datetime object.
>>> parsehttpdate('Thu, 01 Jan 1970 01:01:01 GMT')
datetime.datetime(1970, 1, 1, 1, 1, 1)
function htmlquote(text)
Encodes text
for raw use in HTML.
>>> htmlquote(u"<'&\">")
u'<'&">'
function htmlunquote(text)
Decodes text
that's HTML quoted.
>>> htmlunquote(u'<'&">')
u'<\'&">'
function websafe(val)
Converts val
so that it is safe for use in Unicode HTML.
websafe("<'&\">") u'<'&">' websafe(None) u'' websafe(u'\u203d') u'\u203d' websafe('\xe2\x80\xbd') u'\u203d'
module web.session
Session Management (from web.py)
type Session(self, app, store, initializer=None)
Session management for web.py
method expired(self)
Called when an expired session is atime
method kill(self)
Kill the session, make it no longer available
type SessionExpired(self, message)
class Store(self)
Base class for session stores
method cleanup(self, timeout)
removes all the expired sessions
method decode(self, session_data)
decodes the data to get back the session dict
method encode(self, session_dict)
encodes session dict as a string
class DiskStore(self, root)
Store for saving a session on disk.
>>> import tempfile
>>> root = tempfile.mkdtemp()
>>> s = DiskStore(root)
>>> s['a'] = 'foo'
>>> s['a']
'foo'
>>> time.sleep(0.01)
>>> s.cleanup(0.01)
>>> s['a']
Traceback (most recent call last):
...
KeyError: 'a'
method cleanup(self, timeout)
method decode(self, session_data)
decodes the data to get back the session dict
method encode(self, session_dict)
encodes session dict as a string
class DBStore(self, db, table_name)
Store for saving a session in database Needs a table with the following columns:
session_id CHAR(128) UNIQUE NOT NULL,
atime DATETIME NOT NULL default current_timestamp,
data TEXT
method cleanup(self, timeout)
method decode(self, session_data)
decodes the data to get back the session dict
method encode(self, session_dict)
encodes session dict as a string
module web.template
simple, elegant templating (part of web.py)
Template design:
Template string is split into tokens and the tokens are combined into nodes. Parse tree is a nodelist. TextNode and ExpressionNode are simple nodes and for-loop, if-loop etc are block nodes, which contain multiple child nodes.
Each node can emit some python string. python string emitted by the root node is validated for safeeval and executed using python in the given environment.
Enough care is taken to make sure the generated code and the template has line to line match, so that the error messages can point to exact line number in template. (It doesn't work in some cases still.)
Grammar:
template -> defwith sections
defwith -> '$def with (' arguments ')' | ''
sections -> section*
section -> block | assignment | line
assignment -> '$ ' <assignment expression>
line -> (text|expr)*
text -> <any characters other than $>
expr -> '$' pyexpr | '$(' pyexpr ')' | '${' pyexpr '}'
pyexpr -> <python expression>
class Template(self, text, filename='<template>', filter=None, globals=None, builtins=None, extensions=None)
method compile_template(self, template_string, filename)
method create_parser(self)
function generate_code(text, filename, parser=None)
method make_env(self, globals, builtins)
function normalize_text(text)
Normalizes template text by correcting , tabs and BOM chars.
class Render(self, loc='templates', cache=None, base=None, **keywords)
The most preferred way of using templates.
render = web.template.render('templates')
print render.foo()
Optional parameter base
can be used to pass output of
every template through the base template.
render = web.template.render('templates', base='layout')
class render(self, loc='templates', cache=None, base=None, **keywords)
The most preferred way of using templates.
render = web.template.render('templates')
print render.foo()
Optional parameter base
can be used to pass output of
every template through the base template.
render = web.template.render('templates', base='layout')
function frender(path, **keywords)
Creates a template from the given file path.
type ParseError
type SecurityError
The template seems to be trying to do something naughty.
function test()
Doctest for testing template module.
Define a utility function to run template test.
>>> class TestResult:
... def __init__(self, t): self.t = t
... def __getattr__(self, name): return getattr(self.t, name)
... def __repr__(self): return repr(unicode(self))
...
>>> def t(code, **keywords):
... tmpl = Template(code, **keywords)
... return lambda *a, **kw: TestResult(tmpl(*a, **kw))
...
Simple tests.
>>> t('1')()
u'1\n'
>>> t('$def with ()\n1')()
u'1\n'
>>> t('$def with (a)\n$a')(1)
u'1\n'
>>> t('$def with (a=0)\n$a')(1)
u'1\n'
>>> t('$def with (a=0)\n$a')(a=1)
u'1\n'
Test complicated expressions.
>>> t('$def with (x)\n$x.upper()')('hello')
u'HELLO\n'
>>> t('$(2 * 3 + 4 * 5)')()
u'26\n'
>>> t('${2 * 3 + 4 * 5}')()
u'26\n'
>>> t('$def with (limit)\nkeep $(limit)ing.')('go')
u'keep going.\n'
>>> t('$def with (a)\n$a.b[0]')(storage(b=[1]))
u'1\n'
Test html escaping.
>>> t('$def with (x)\n$x', filename='a.html')('<html>')
u'<html>\n'
>>> t('$def with (x)\n$x', filename='a.txt')('<html>')
u'<html>\n'
Test if, for and while.
>>> t('$if 1: 1')()
u'1\n'
>>> t('$if 1:\n 1')()
u'1\n'
>>> t('$if 1:\n 1\\')()
u'1'
>>> t('$if 0: 0\n$elif 1: 1')()
u'1\n'
>>> t('$if 0: 0\n$elif None: 0\n$else: 1')()
u'1\n'
>>> t('$if 0 < 1 and 1 < 2: 1')()
u'1\n'
>>> t('$for x in [1, 2, 3]: $x')()
u'1\n2\n3\n'
>>> t('$def with (d)\n$for k, v in d.iteritems(): $k')({1: 1})
u'1\n'
>>> t('$for x in [1, 2, 3]:\n\t$x')()
u' 1\n 2\n 3\n'
>>> t('$def with (a)\n$while a and a.pop():1')([1, 2, 3])
u'1\n1\n1\n'
The space after : must be ignored.
>>> t('$if True: foo')()
u'foo\n'
Test loop.xxx.
>>> t("$for i in range(5):$loop.index, $loop.parity")()
u'1, odd\n2, even\n3, odd\n4, even\n5, odd\n'
>>> t("$for i in range(2):\n $for j in range(2):$loop.parent.parity $loop.parity")()
u'odd odd\nodd even\neven odd\neven even\n'
Test assignment.
>>> t('$ a = 1\n$a')()
u'1\n'
>>> t('$ a = [1]\n$a[0]')()
u'1\n'
>>> t('$ a = {1: 1}\n$a.keys()[0]')()
u'1\n'
>>> t('$ a = []\n$if not a: 1')()
u'1\n'
>>> t('$ a = {}\n$if not a: 1')()
u'1\n'
>>> t('$ a = -1\n$a')()
u'-1\n'
>>> t('$ a = "1"\n$a')()
u'1\n'
Test comments.
>>> t('$# 0')()
u'\n'
>>> t('hello$#comment1\nhello$#comment2')()
u'hello\nhello\n'
>>> t('$#comment0\nhello$#comment1\nhello$#comment2')()
u'\nhello\nhello\n'
Test unicode.
>>> t('$def with (a)\n$a')(u'\u203d')
u'\u203d\n'
>>> t('$def with (a)\n$a')(u'\u203d'.encode('utf-8'))
u'\u203d\n'
>>> t(u'$def with (a)\n$a $:a')(u'\u203d')
u'\u203d \u203d\n'
>>> t(u'$def with ()\nfoo')()
u'foo\n'
>>> def f(x): return x
...
>>> t(u'$def with (f)\n$:f("x")')(f)
u'x\n'
>>> t('$def with (f)\n$:f("x")')(f)
u'x\n'
Test dollar escaping.
>>> t("Stop, $$money isn't evaluated.")()
u"Stop, $money isn't evaluated.\n"
>>> t("Stop, \$money isn't evaluated.")()
u"Stop, $money isn't evaluated.\n"
Test space sensitivity.
>>> t('$def with (x)\n$x')(1)
u'1\n'
>>> t('$def with(x ,y)\n$x')(1, 1)
u'1\n'
>>> t('$(1 + 2*3 + 4)')()
u'11\n'
Make sure globals are working.
>>> t('$x')()
Traceback (most recent call last):
...
NameError: global name 'x' is not defined
>>> t('$x', globals={'x': 1})()
u'1\n'
Can't change globals.
>>> t('$ x = 2\n$x', globals={'x': 1})()
u'2\n'
>>> t('$ x = x + 1\n$x', globals={'x': 1})()
Traceback (most recent call last):
...
UnboundLocalError: local variable 'x' referenced before assignment
Make sure builtins are customizable.
>>> t('$min(1, 2)')()
u'1\n'
>>> t('$min(1, 2)', builtins={})()
Traceback (most recent call last):
...
NameError: global name 'min' is not defined
Test vars.
>>> x = t('$var x: 1')()
>>> x.x
u'1'
>>> x = t('$var x = 1')()
>>> x.x
1
>>> x = t('$var x: \n foo\n bar')()
>>> x.x
u'foo\nbar\n'
Test BOM chars.
>>> t('\xef\xbb\xbf$def with(x)\n$x')('foo')
u'foo\n'
Test for with weird cases.
>>> t('$for i in range(10)[1:5]:\n $i')()
u'1\n2\n3\n4\n'
>>> t("$for k, v in {'a': 1, 'b': 2}.items():\n $k $v")()
u'a 1\nb 2\n'
>>> t("$for k, v in ({'a': 1, 'b': 2}.items():\n $k $v")()
Traceback (most recent call last):
...
SyntaxError: invalid syntax
Test datetime.
>>> import datetime
>>> t("$def with (date)\n$date.strftime('%m %Y')")(datetime.datetime(2009, 1, 1))
u'01 2009\n'
module web.utils
General Utilities (part of web.py)
type Storage
A Storage object is like a dictionary except obj.foo
can be used
in addition to obj['foo']
.
>>> o = storage(a=1)
>>> o.a
1
>>> o['a']
1
>>> o.a = 2
>>> o['a']
2
>>> del o.a
>>> o.a
Traceback (most recent call last):
...
AttributeError: 'a'
function storify(mapping, *requireds, **defaults)
Creates a storage
object from dictionary mapping
, raising KeyError
if
d doesn't have all of the keys in requireds
and using the default
values for keys found in defaults
.
For example, storify({'a':1, 'c':3}, b=2, c=0)
will return the equivalent of
storage({'a':1, 'b':2, 'c':3})
.
If a storify
value is a list (e.g. multiple values in a form submission),
storify
returns the last element of the list, unless the key appears in
defaults
as a list. Thus:
>>> storify({'a':[1, 2]}).a
2
>>> storify({'a':[1, 2]}, a=[]).a
[1, 2]
>>> storify({'a':1}, a=[]).a
[1]
>>> storify({}, a=[]).a
[]
Similarly, if the value has a value
attribute, `storify will return its
value, unless the key appears in defaults
as a dictionary.
>>> storify({'a':storage(value=1)}).a
1
>>> storify({'a':storage(value=1)}, a={}).a
<Storage {'value': 1}>
>>> storify({}, a={}).a
{}
Optionally, keyword parameter _unicode
can be passed to convert all values to unicode.
>>> storify({'x': 'a'}, _unicode=True)
<Storage {'x': u'a'}>
>>> storify({'x': storage(value='a')}, x={}, _unicode=True)
<Storage {'x': <Storage {'value': 'a'}>}>
>>> storify({'x': storage(value='a')}, _unicode=True)
<Storage {'x': u'a'}>
type Counter
Keeps count of how many times something is added.
c = counter() c.add('x') c.add('x') c.add('x') c.add('x') c.add('x') c.add('y') c <Counter {'y': 1, 'x': 5}> c.most() ['x']
method add(self, n)
method least(self)
Returns the keys with mininum count.
method most(self)
Returns the keys with maximum count.
method percent(self, key)
Returns what percentage a certain key is of all entries.
c = counter() c.add('x') c.add('x') c.add('x') c.add('y') c.percent('x') 0.75 c.percent('y') 0.25
method sorted_items(self)
Returns items sorted by value.
c = counter() c.add('x') c.add('x') c.add('y') c.sorted_items() [('x', 2), ('y', 1)]
method sorted_keys(self)
Returns keys sorted by value.
c = counter() c.add('x') c.add('x') c.add('y') c.sorted_keys() ['x', 'y']
method sorted_values(self)
Returns values sorted by value.
c = counter() c.add('x') c.add('x') c.add('y') c.sorted_values() [2, 1]
type counter
Keeps count of how many times something is added.
c = counter() c.add('x') c.add('x') c.add('x') c.add('x') c.add('x') c.add('y') c <Counter {'y': 1, 'x': 5}> c.most() ['x']
method add(self, n)
method least(self)
Returns the keys with mininum count.
method most(self)
Returns the keys with maximum count.
method percent(self, key)
Returns what percentage a certain key is of all entries.
c = counter() c.add('x') c.add('x') c.add('x') c.add('y') c.percent('x') 0.75 c.percent('y') 0.25
method sorted_items(self)
Returns items sorted by value.
c = counter() c.add('x') c.add('x') c.add('y') c.sorted_items() [('x', 2), ('y', 1)]
method sorted_keys(self)
Returns keys sorted by value.
c = counter() c.add('x') c.add('x') c.add('y') c.sorted_keys() ['x', 'y']
method sorted_values(self)
Returns values sorted by value.
c = counter() c.add('x') c.add('x') c.add('y') c.sorted_values() [2, 1]
function rstrips(text, remove)
removes the string remove
from the right of text
>>> rstrips("foobar", "bar")
'foo'
function lstrips(text, remove)
removes the string remove
from the left of text
>>> lstrips("foobar", "foo")
'bar'
>>> lstrips('http://foo.org/', ['http://', 'https://'])
'foo.org/'
>>> lstrips('FOOBARBAZ', ['FOO', 'BAR'])
'BAZ'
>>> lstrips('FOOBARBAZ', ['BAR', 'FOO'])
'BARBAZ'
function strips(text, remove)
removes the string remove
from the both sides of text
>>> strips("foobarfoo", "foo")
'bar'
function safeunicode(obj, encoding='utf-8')
Converts any given object to unicode string.
>>> safeunicode('hello')
u'hello'
>>> safeunicode(2)
u'2'
>>> safeunicode('\xe1\x88\xb4')
u'\u1234'
function safestr(obj, encoding='utf-8')
Converts any given object to utf-8 encoded string.
>>> safestr('hello')
'hello'
>>> safestr(u'\u1234')
'\xe1\x88\xb4'
>>> safestr(2)
'2'
function utf8(obj, encoding='utf-8')
Converts any given object to utf-8 encoded string.
>>> safestr('hello')
'hello'
>>> safestr(u'\u1234')
'\xe1\x88\xb4'
>>> safestr(2)
'2'
type TimeoutError
function timelimit(timeout)
A decorator to limit a function to timeout
seconds, raising TimeoutError
if it takes longer.
>>> import time
>>> def meaningoflife():
... time.sleep(.2)
... return 42
>>>
>>> timelimit(.1)(meaningoflife)()
Traceback (most recent call last):
...
TimeoutError: took too long
>>> timelimit(1)(meaningoflife)()
42
Caveat: The function isn't stopped after timeout
seconds but continues
executing in a separate thread. (There seems to be no way to kill a thread.)
inspired by http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473878
class Memoize(self, func, expires=None, background=True)
'Memoizes' a function, caching its return values for each input.
If expires
is specified, values are recalculated after expires
seconds.
If background
is specified, values are recalculated in a separate thread.
>>> calls = 0
>>> def howmanytimeshaveibeencalled():
... global calls
... calls += 1
... return calls
>>> fastcalls = memoize(howmanytimeshaveibeencalled)
>>> howmanytimeshaveibeencalled()
1
>>> howmanytimeshaveibeencalled()
2
>>> fastcalls()
3
>>> fastcalls()
3
>>> import time
>>> fastcalls = memoize(howmanytimeshaveibeencalled, .1, background=False)
>>> fastcalls()
4
>>> fastcalls()
4
>>> time.sleep(.2)
>>> fastcalls()
5
>>> def slowfunc():
... time.sleep(.1)
... return howmanytimeshaveibeencalled()
>>> fastcalls = memoize(slowfunc, .2, background=True)
>>> fastcalls()
6
>>> timelimit(.05)(fastcalls)()
6
>>> time.sleep(.2)
>>> timelimit(.05)(fastcalls)()
6
>>> timelimit(.05)(fastcalls)()
6
>>> time.sleep(.2)
>>> timelimit(.05)(fastcalls)()
7
>>> fastcalls = memoize(slowfunc, None, background=True)
>>> threading.Thread(target=fastcalls).start()
>>> time.sleep(.01)
>>> fastcalls()
9
function re_subm(pat, repl, string)
Like re.sub, but returns the replacement and the match object.
>>> t, m = re_subm('g(oo+)fball', r'f\1lish', 'goooooofball')
>>> t
'foooooolish'
>>> m.groups()
('oooooo',)
function group(seq, size)
Returns an iterator over a series of lists of length size from iterable.
>>> list(group([1,2,3,4], 2))
[[1, 2], [3, 4]]
>>> list(group([1,2,3,4,5], 2))
[[1, 2], [3, 4], [5]]
function uniq(seq, key=None)
Removes duplicate elements from a list while preserving the order of the rest.
>>> uniq([9,0,2,1,0])
[9, 0, 2, 1]
The value of the optional key
parameter should be a function that
takes a single argument and returns a key to test the uniqueness.
>>> uniq(["Foo", "foo", "bar"], key=lambda s: s.lower())
['Foo', 'bar']
function iterview(x)
Takes an iterable x
and returns an iterator over it
which prints its progress to stderr as it iterates through.
class IterBetter(self, iterator)
Returns an object that can be used as an iterator
but can also be used via getitem (although it
cannot go backwards -- that is, you cannot request
iterbetter[0]
after requesting iterbetter[1]
).
>>> import itertools
>>> c = iterbetter(itertools.count())
>>> c[1]
1
>>> c[5]
5
>>> c[3]
Traceback (most recent call last):
...
IndexError: already passed 3
It is also possible to get the first value of the iterator or None.
>>> c = iterbetter(iter([3, 4, 5]))
>>> print c.first()
3
>>> c = iterbetter(iter([]))
>>> print c.first()
None
For boolean test, IterBetter peeps at first value in the itertor without effecting the iteration.
>>> c = iterbetter(iter(range(5)))
>>> bool(c)
True
>>> list(c)
[0, 1, 2, 3, 4]
>>> c = iterbetter(iter([]))
>>> bool(c)
False
>>> list(c)
[]
method first(self, default=None)
Returns the first element of the iterator or None when there are no elements.
If the optional argument default is specified, that is returned instead of None when there are no elements.
function safeiter(it, cleanup=None, ignore_errors=True)
Makes an iterator safe by ignoring the exceptions occured during the iteration.
function safewrite(filename, content)
Writes the content to a temp file and then moves the temp file to given filename to avoid overwriting the existing file in case of errors.
function dictreverse(mapping)
Returns a new dictionary with keys and values swapped.
>>> dictreverse({1: 2, 3: 4})
{2: 1, 4: 3}
function dictfind(dictionary, element)
Returns a key whose value in dictionary
is element
or, if none exists, None.
>>> d = {1:2, 3:4}
>>> dictfind(d, 4)
3
>>> dictfind(d, 5)
function dictfindall(dictionary, element)
Returns the keys whose values in dictionary
are element
or, if none exists, [].
>>> d = {1:4, 3:4}
>>> dictfindall(d, 4)
[1, 3]
>>> dictfindall(d, 5)
[]
function dictincr(dictionary, element)
Increments element
in dictionary
,
setting it to one if it doesn't exist.
>>> d = {1:2, 3:4}
>>> dictincr(d, 1)
3
>>> d[1]
3
>>> dictincr(d, 5)
1
>>> d[5]
1
function dictadd(*dicts)
Returns a dictionary consisting of the keys in the argument dictionaries. If they share a key, the value from the last argument is used.
>>> dictadd({1: 0, 2: 0}, {2: 1, 3: 1})
{1: 0, 2: 1, 3: 1}
function requeue(queue, index=-1)
Returns the element at index after moving it to the beginning of the queue.
x = [1, 2, 3, 4] requeue(x) 4 x [4, 1, 2, 3]
function restack(stack, index=0)
Returns the element at index after moving it to the top of stack.
x = [1, 2, 3, 4] restack(x) 1 x [2, 3, 4, 1]
function listget(lst, ind, default=None)
Returns lst[ind]
if it exists, default
otherwise.
>>> listget(['a'], 0)
'a'
>>> listget(['a'], 1)
>>> listget(['a'], 1, 'b')
'b'
function intget(integer, default=None)
Returns integer
as an int or default
if it can't.
>>> intget('3')
3
>>> intget('3a')
>>> intget('3a', 0)
0
function datestr(then, now=None)
Converts a (UTC) datetime object to a nice string representation.
>>> from datetime import datetime, timedelta
>>> d = datetime(1970, 5, 1)
>>> datestr(d, now=d)
'0 microseconds ago'
>>> for t, v in {
... timedelta(microseconds=1): '1 microsecond ago',
... timedelta(microseconds=2): '2 microseconds ago',
... -timedelta(microseconds=1): '1 microsecond from now',
... -timedelta(microseconds=2): '2 microseconds from now',
... timedelta(microseconds=2000): '2 milliseconds ago',
... timedelta(seconds=2): '2 seconds ago',
... timedelta(seconds=2*60): '2 minutes ago',
... timedelta(seconds=2*60*60): '2 hours ago',
... timedelta(days=2): '2 days ago',
... }.iteritems():
... assert datestr(d, now=d+t) == v
>>> datestr(datetime(1970, 1, 1), now=d)
'January 1'
>>> datestr(datetime(1969, 1, 1), now=d)
'January 1, 1969'
>>> datestr(datetime(1970, 6, 1), now=d)
'June 1, 1970'
>>> datestr(None)
''
function numify(string)
Removes all non-digit characters from string
.
>>> numify('800-555-1212')
'8005551212'
>>> numify('800.555.1212')
'8005551212'
function denumify(string, pattern)
Formats string
according to pattern
, where the letter X gets replaced
by characters from string
.
>>> denumify("8005551212", "(XXX) XXX-XXXX")
'(800) 555-1212'
function commify(n)
Add commas to an integer n
.
>>> commify(1)
'1'
>>> commify(123)
'123'
>>> commify(1234)
'1,234'
>>> commify(1234567890)
'1,234,567,890'
>>> commify(123.0)
'123.0'
>>> commify(1234.5)
'1,234.5'
>>> commify(1234.56789)
'1,234.56789'
>>> commify('%.2f' % 1234.5)
'1,234.50'
>>> commify(None)
>>>
function dateify(datestring)
Formats a numified datestring
properly.
function nthstr(n)
Formats an ordinal. Doesn't handle negative numbers.
>>> nthstr(1)
'1st'
>>> nthstr(0)
'0th'
>>> [nthstr(x) for x in [2, 3, 4, 5, 10, 11, 12, 13, 14, 15]]
['2nd', '3rd', '4th', '5th', '10th', '11th', '12th', '13th', '14th', '15th']
>>> [nthstr(x) for x in [91, 92, 93, 94, 99, 100, 101, 102]]
['91st', '92nd', '93rd', '94th', '99th', '100th', '101st', '102nd']
>>> [nthstr(x) for x in [111, 112, 113, 114, 115]]
['111th', '112th', '113th', '114th', '115th']
function cond(predicate, consequence, alternative=None)
Function replacement for if-else to use in expressions.
>>> x = 2
>>> cond(x % 2 == 0, "even", "odd")
'even'
>>> cond(x % 2 == 0, "even", "odd") + '_row'
'even_row'
class CaptureStdout(self, func)
Captures everything func
prints to stdout and returns it instead.
>>> def idiot():
... print "foo"
>>> capturestdout(idiot)()
'foo\n'
WARNING: Not threadsafe!
class capturestdout(self, func)
Captures everything func
prints to stdout and returns it instead.
>>> def idiot():
... print "foo"
>>> capturestdout(idiot)()
'foo\n'
WARNING: Not threadsafe!
class Profile(self, func)
Profiles func
and returns a tuple containing its output
and a string with human-readable profiling information.
>>> import time
>>> out, inf = profile(time.sleep)(.001)
>>> out
>>> inf[:10].strip()
'took 0.0'
function tryall(context, prefix=None)
Tries a series of functions and prints their results.
context
is a dictionary mapping names to values;
the value will only be tried if it's callable.
>>> tryall(dict(j=lambda: True))
j: True
----------------------------------------
results:
True: 1
For example, you might have a file test/stuff.py
with a series of functions testing various things in it.
At the bottom, have a line:
if __name__ == "__main__": tryall(globals())
Then you can run python test/stuff.py
and get the results of
all the tests.
type ThreadedDict(self)
Thread local storage.
>>> d = ThreadedDict()
>>> d.x = 1
>>> d.x
1
>>> import threading
>>> def f(): d.x = 2
...
>>> t = threading.Thread(target=f)
>>> t.start()
>>> t.join()
>>> d.x
1
method clear(self)
function clear_all()
Clears all ThreadedDict instances.
method copy(self)
method get(self, key, default=None)
method has_key(self, key)
method items(self)
method iter(self)
method iteritems(self)
method iterkeys(self)
method itervalues(self)
method keys(self)
method pop(self, key, *args)
method popitem(self)
method setdefault(self, key, default=None)
method update(self, *args, **kwargs)
method values(self)
function autoassign(self, locals)
Automatically assigns local variables to self
.
>>> self = storage()
>>> autoassign(self, dict(a=1, b=2))
>>> self
<Storage {'a': 1, 'b': 2}>
Generally used in __init__
methods, as in:
def __init__(self, foo, bar, baz=1): autoassign(self, locals())
function to36(q)
Converts an integer to base 36 (a useful scheme for human-sayable IDs).
>>> to36(35)
'z'
>>> to36(119292)
'2k1o'
>>> int(to36(939387374), 36)
939387374
>>> to36(0)
'0'
>>> to36(-393)
Traceback (most recent call last):
...
ValueError: must supply a positive integer
function safemarkdown(text)
Converts text to HTML following the rules of Markdown, but blocking any outside HTML input, so that only the things supported by Markdown can be used. Also converts raw URLs to links.
(requires markdown.py)
function sendmail(from_address, to_address, subject, message, headers=None, **kw)
Sends the email message message
with mail and envelope headers
for from from_address_
to to_address
with subject
.
Additional email headers can be specified with the dictionary
`headers.
Optionally cc, bcc and attachments can be specified as keyword arguments. Attachments must be an iterable and each attachment can be either a filename or a file object or a dictionary with filename, content and optionally content_type keys.
If web.config.smtp_server
is set, it will send the message
to that SMTP server. Otherwise it will look for
/usr/sbin/sendmail
, the typical location for the sendmail-style
binary. To use sendmail from a different path, set web.config.sendmail_path
.
module web.webapi
Web API (wrapper around WSGI) (from web.py)
function header(hdr, value, unique=False)
Adds the header hdr: value
with the response.
If unique
is True and a header with that name already exists,
it doesn't add a new one.
function debug(*args)
Prints a prettyprinted version of args
to stderr.
function write(x)
function input(*requireds, **defaults)
Returns a storage
object with the GET and POST arguments.
See storify
for how requireds
and defaults
work.
function data()
Returns the data sent with the request.
function setcookie(name, value, expires='', domain=None, secure=False, httponly=False, path=None)
Sets a cookie.
function cookies(*requireds, **defaults)
Returns a storage
object with all the request cookies in it.
See storify
for how requireds
and defaults
work.
This is forgiving on bad HTTP_COOKIE input, it tries to parse at least the cookies it can.
The values are converted to unicode if _unicode=True is passed.
type HTTPError(self, status, headers={}, data='')
type OK(self, data='', headers={})
200 OK
status
type Created(self, data='Created', headers={})
201 Created
status
type Accepted(self, data='Accepted', headers={})
202 Accepted
status
type NoContent(self, data='No Content', headers={})
204 No Content
status
type ok(self, data='', headers={})
200 OK
status
type created(self, data='Created', headers={})
201 Created
status
type accepted(self, data='Accepted', headers={})
202 Accepted
status
type nocontent(self, data='No Content', headers={})
204 No Content
status
type Redirect(self, url, status='301 Moved Permanently', absolute=False)
A 301 Moved Permanently
redirect.
type Found(self, url, absolute=False)
A 302 Found
redirect.
type SeeOther(self, url, absolute=False)
A 303 See Other
redirect.
type NotModified(self)
A 304 Not Modified
status.
type TempRedirect(self, url, absolute=False)
A 307 Temporary Redirect
redirect.
type redirect(self, url, status='301 Moved Permanently', absolute=False)
A 301 Moved Permanently
redirect.
type found(self, url, absolute=False)
A 302 Found
redirect.
type seeother(self, url, absolute=False)
A 303 See Other
redirect.
type notmodified(self)
A 304 Not Modified
status.
type tempredirect(self, url, absolute=False)
A 307 Temporary Redirect
redirect.
type BadRequest(self, message=None)
400 Bad Request
error.
type Unauthorized(self, message=None)
401 Unauthorized
error.
type Forbidden(self, message=None)
403 Forbidden
error.
function NotFound(message=None)
Returns HTTPError with '404 Not Found' error from the active application.
type NoMethod(self, cls=None)
A 405 Method Not Allowed
error.
type NotAcceptable(self, message=None)
406 Not Acceptable
error.
type Conflict(self, message=None)
409 Conflict
error.
type Gone(self, message=None)
410 Gone
error.
type PreconditionFailed(self, message=None)
412 Precondition Failed
error.
type UnsupportedMediaType(self, message=None)
415 Unsupported Media Type
error.
function UnavailableForLegalReasons(message=None)
Returns HTTPError with '415 Unavailable For Legal Reasons' error from the active application.
type badrequest(self, message=None)
400 Bad Request
error.
type unauthorized(self, message=None)
401 Unauthorized
error.
type forbidden(self, message=None)
403 Forbidden
error.
function notfound(message=None)
Returns HTTPError with '404 Not Found' error from the active application.
type nomethod(self, cls=None)
A 405 Method Not Allowed
error.
type notacceptable(self, message=None)
406 Not Acceptable
error.
type conflict(self, message=None)
409 Conflict
error.
type gone(self, message=None)
410 Gone
error.
type preconditionfailed(self, message=None)
412 Precondition Failed
error.
type unsupportedmediatype(self, message=None)
415 Unsupported Media Type
error.
function unavailableforlegalreasons(message=None)
Returns HTTPError with '415 Unavailable For Legal Reasons' error from the active application.
function InternalError(message=None)
Returns HTTPError with '500 internal error' error from the active application.
function internalerror(message=None)
Returns HTTPError with '500 internal error' error from the active application.
module web.webopenid
openid.py: an openid library for web.py
Notes:
This will create a file called .openidsecretkey in the current directory with your secret key in it. If someone has access to this file they can log in as any user. And if the app can't find this file for any reason (e.g. you moved the app somewhere else) then each currently logged in user will get logged out.
State must be maintained through the entire auth process -- this means that if you have multiple web.py processes serving one set of URLs or if you restart your app often then log ins will fail. You have to replace sessions and store for things to work.
We set cookies starting with "openid_".
function form(openid_loc)
class host(self)
method GET(self)
method POST(self)
function logout()
function status()
module web.wsgi
WSGI Utilities (from web.py)
function intget(integer, default=None)
Returns integer
as an int or default
if it can't.
>>> intget('3')
3
>>> intget('3a')
>>> intget('3a', 0)
0
function listget(lst, ind, default=None)
Returns lst[ind]
if it exists, default
otherwise.
>>> listget(['a'], 0)
'a'
>>> listget(['a'], 1)
>>> listget(['a'], 1, 'b')
'b'
function runfcgi(func, addr=('localhost', 8000))
Runs a WSGI function as a FastCGI server.
function runscgi(func, addr=('localhost', 4000))
Runs a WSGI function as an SCGI server.
function runwsgi(func)
Runs a WSGI-compatible func
using FCGI, SCGI, or a simple web server,
as appropriate based on context and sys.argv
.
function validaddr(string_)
Returns either (ipaddress, port) or "/path/to/socket" from string
>>> validaddr('/path/to/socket')
'/path/to/socket'
>>> validaddr('8000')
('0.0.0.0', 8000)
>>> validaddr('127.0.0.1')
('127.0.0.1', 8080)
>>> validaddr('127.0.0.1:8000')
('127.0.0.1', 8000)
>>> validip('[::1]:80')
('::1', 80)
>>> validaddr('fff')
Traceback (most recent call last):
...
ValueError: fff is not a valid IP address/port
function validip(ip, defaultaddr='0.0.0.0', defaultport=8080)
Returns (ip_address, port)
from string ip_addr_port
validip('1.2.3.4') ('1.2.3.4', 8080) validip('80') ('0.0.0.0', 80) validip('192.168.0.1:85') ('192.168.0.1', 85) validip('::') ('::', 8080) validip('[::]:88') ('::', 88) validip('[::1]:80') ('::1', 80)