Robusto, rápido, suporta SSL y HTTP 1.1
No es necesario hacer reverse proxy o algún otro servidor de frontal (mod_wsgi).
Fácil para iniciar a usarlo
No tiene dependencias externas
Arquitectura de extensiones muy poderosa
cherrypy.engine: Controla el manejo de procesos startup/teardown y manejo de eventos.
cherrypy.server: Configura y controla el servidor WSGI o HTTP.
cherrypy.tools: Caja de herramientas para el manejo de las peticiones HTTP. e.g. sesiones, json, autorización, etc
import cherrypy as cp
class Root:
@cp.expose
def index(self):
return "Hola Mundo!"
@cp.expose
def user(self, uid):
return "Información de usuario {}".format(uid)
if __name__ == "__main__":
cp.quickstart(Root())
class UserApp:
@cherrypy.expose
def sub_path(self):
return "Sub Path"
class App:
def __init__(self):
self.project = Project()
@cp.expose
def index(self):
return "Indice"
@cp.expose
def default(self, *args, **kwargs):
return "Catch all args: {}, " \
"kwargs: {}".format(args, kwargs)
@cp.expose
def tasks(self, tid, name, **datos):
return "Indice de tareas"
class Project:
@cp.expose
def index(self):
return "Indice de proyectos"
1
2
3
4
Composición de objetos/aplicaciones
Se asigna al path: "/"
Atrapa todo lo que no se define en el objeto
Se asigna al path:
/tareas/<tid>/<name>?datos
Donde datos representan los parámetros en la URL
Usando el dispatcher default
class Project:
exposed = True
def GET(self):
return "Indice de proyectos"
class Tasks:
exposed = True
def GET(self, tid=None):
if tid is None:
return "Indice de tareas"
return "Tarea {}".format(tid)
def DELETE(self, tid):
return "DELETED"
class App:
exposed = True
project = Project()
tasks = Tasks()
def GET(self):
return "Indice"
1
Usando MethodDispatcher
Los métodos se nombran como los verbos de HTTP
Al igual, se compone de sub-handers/objetos.
Se expone a nivel de recurso, no a nivel de método.
2
3
cherrypy.config: Determina el comportamiento de la aplicación en cada path
cherrypy.tree: Árbol de objetos que representa a la aplicación
cherrypy.request: Un objeto thread_local que representa a la petición HTTP
cherrypy.response: Un objeto thread_local que representa la respuesta a la petición HTTP
CherryPy uses Tools to change application behavior at various points in the http request lifecycle.
cherrypy.tools.TOOL_NAME.on = True enables a tool cherrypy.tools.TOOL_NAME.<parameter> = <value> sets Tool parameters.
Tools do not (typically) deepen the call stacks like decorators or middleware.
Session
XMLRPC
Auth
Caching
Allow
Proxy
ResponseHeaders
Logging
Error Handling
ETags
Encoding/Decoding
GZip
JSON
POST / HTTP/1.0
on_start_resource
Content-Type: application/x-www-form-urlencoded
Content-Length: 135
before_request_body
param1=one¶m2=two...
before_handler
<handler called>
before_finalize
Content-Type: text/html
...
<html>...</html>
on_end_resource
Connection closed.
on_end_request
* before_error_response
* after_error_response
class ScratchDB(plugins.SimplePlugin):
def start(self):
self.fname = 'myapp_%d.db' % os.getpid()
self.db = sqlite.connect(database=self.fname)
start.priority = 80
def stop(self):
self.db.close()
os.remove(self.fname)
cherrypy.engine.scratchdb = ScratchDB(cherrypy.engine)
cherrypy.engine.scratchdb.subscribe()
Aplicaciones web "stand alone" con ejecutables entregables
Extensión de una aplicación de escritorio
Sitios web y backend de RESTful APIs de volumen moderado
Donde la compatibilidad multi-plataforma sera muy relevante para la aplicación
Aplicaciones web de alta concurrencia
Creación de aplicaciones web grandes de patrones muy bien definidos. e.g. tiendas/CMS/
Cuando no se conocer nada de web o Python y se espera que el framework te delimite como construir tu aplicación
La inter-operabilidad entre SO es irrelevante
We are hiring!