Más contenido relacionado La actualidad más candente (20) Similar a Pyramid Lighter/Faster/Better web apps (20) Pyramid Lighter/Faster/Better web apps2. From the mind of Chris McDonough As seen in bearded of PyCon 2009 http://www.flickr.com/photos/termie/3392894269/ 3. Pyramid Family Tree Zope formally Principia (1996-) Zope2 (1998-) BlueBream formally Zope3 (2004-) ZTK (2009-) Repoze.bfg (2008 – 2010) Pylons (2005-2010) Pylons Project (2010-) Pyramid formally repoze.bfg ( Dec 2010 -) TurboGears (2005-) RoR (2004-) Django (2005-) 12. From the minds on PretaWeb... PloneFactory Web installer for the worlds favourite Python CMS Coming 2011... 16. Simpler and faster Pyramid Django Plone Not Opinionated Opinionated Structured (CMS) Very Simple Simple Complex No DB ORM Content Types Little Reuse Some Reuse Easy Reuse 19. Install $ virtualenv -- no-site-packages -- distribute newproject $ cd newproject $ bin/pip install pyramid 20. Hello World from paste.httpserver import serve from pyramid.configuration import Configurator from pyramid.response import Response def hello_world(context, request): return Response('Hello world!') if __name__ == '__main__': config = Configurator() config.begin() config.add_view(hello_world) config.end() app = config.make_wsgi_app() serve(app, host='0.0.0.0') 22. View Callables from pyramid.response import Response def hello_world(request): return Response('Hello world!') from pyramid.httpexceptions import HTTPFound class MyView(object): def __init__(self, request): self.request = request def __call__(self): raise HTTPFound(location='http://example.com') 23. Request / prefix/foo/bar?pref=red&pref=blue; def hello_world(request): assert 'blue' == request.params['pref'] assert ['red,'blue] == request.params.getall('pref') assert ['foo','bar'] == request.matchdict.values() return Response('Hello world!') 24. Renderers from pyramid.view import view_config @view_config(renderer='json') def hello_world(request): return {'content':'Hello!'} @view_config(renderer='string') def hello_world(request): return {'content':'Hello!'} @ view_config(renderer='mypackage:templates/foo.mak') Add your own - config.add_renderer('.jinja2', 'mypackage.MyJinja2Renderer') 25. Templates from pyramid.renderers import render_to_response def sample_view(request): return render_to_response('templates/foo.pt', {' foo':1, 'bar':2}, request=request) 26. Templates from pyramid.renderers import render_to_response def sample_view(request): return render_to_response('templates/foo.pt', {' foo':1, 'bar':2}, request=request) 27. BYO Templating from mako.template import Template from pyramid.response import Response def make_view(request): template = Template(filename='/templates/template.mak') result = template.render(name=request.params['name']) response = Response(result) return response 30. .pt files <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> < html xmlns="http://www.w3.org/1999/xhtml" xmlns:tal="http://xml.zope.org/namespaces/tal"> < head> < meta http-equiv="content-type" content="text/html; charset=utf-8" /> < title>${project} Application</title> </ head> < body> < h1 class="title">Welcome to <code>${project}</code>, an application generated by the <a Href=”http://..." tal:attributes=”href mylink” > pyramid</a> web application framework.</h1> < ul > <li tal:repeat=”row rows”>${row}</li></ul> </ body> </ html> 31. Static Assets config.add_static_view(name='static', path='/var/www/static') / static/main.css -> /var/www/static/main.css config.add_static_view(name='static', path='some_package:a/b/c/static') / static/foo.jpg -> ./src/some_package/a/b/c/static/foo.jpg 33. Traversal (Resource Location) Pattern allowing transitive and indirect view loockup Simplifies view code for complex apps Great for content centric URLS config.add_view(photo_edit, context=Photo, name='edit') Class User(dict): pass Class Folder(dict): pass Class Photo(dict): pass def photo_edit(request): Return Response('editing %s', request.context.Ttile) 34. Inside Traversal / joeschmoe/photos/photo1/edit psuedo code: context = get_root()['joeschmoe']['photos']['photo1'] view_callable = get_view(context,'edit') request.context = context view_callable(request) 46. Security - Protecting Authentication Policy – Extract principals from request Authorization Policy – Access based on Context, Principals and View's permissions config.add_view(myview, name='add_entry.html', context='mypackage.resources.Blog', permission='add') 47. Security Configuration def auth(userid, request): return ['user:bob','group:editors'] if userid == 'bob' else None from pyramid.config import Configurator from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy authentication_policy = AuthTktAuthenticationPolicy('seekrit', callback=auth) authorization_policy = ACLAuthorizationPolicy() config = Configurator(authentication_policy=authentication_policy, authorization_policy=authorization_policy) 48. Security - Context from pyramid.security import Everyone from pyramid.security import Allow class Blog(object): pass blog = Blog() blog.__acl__ = [ (Allow, Everyone, 'view'), (Allow, 'group:editors', 'add'), (Allow, 'group:editors', 'edit'), ] 49. Scaffolding $ bin/paster create -t pyramid_starter MyProject $ cd myproj $ ../ bin/python setup.py develop $ ../ bin/paster serve development.ini Starting server in PID 16601. serving on 0.0.0.0:6543 view at http://127.0.0.1:6543 MyProject/ |-- CHANGES.txt |-- development.ini |-- MANIFEST.in |-- myproject | |-- __init__.py | |-- resources.py | |-- static | | |-- favicon.ico | | |-- logo.png | | `-- pylons.css | |-- templates | | `-- mytemplate.pt | |-- tests.py | `-- views.py |-- production.ini |-- README.txt |-- setup.cfg `-- setup.py $ bin/paster create -t pyramid_zodb $ bin/paster create -t pyramid_routesalchemy $ bin/paster create -t pyramid_alchemy 54. Customizing Example def configure_views(config): config.add_view('orig_app.views.theview', name='theview') from pyramid.config import Configurator from orig_app import configure_views if __name == '__main__': config = Configurator() config.include(configure_views) config.add_view('override_app.views.theview', name='theview') 55. pyramid_socketio config.add_route('socket_io', 'socket.io/*remaining') config.add_view(socketio_service, route_name='socket_io') from pyramid.response import Response from pyramid_socketio.io import SocketIOContext, socketio_manage class ConnectIOContext(SocketIOContext): # self.io is the Socket.IO socket # self.request is the request def msg_connect(self, msg): print "Connect message received", msg self.msg("connected", hello="world") def socketio_service(request): return Response( socketio_manage(ConnectIOContext(request)) )