Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Intro to Pyramid

5,422 views

Published on

Introduction to Pyramid talk delivered at PyGotham 9/17/11. High level overview of the framework. Comparisons to other web frameworks. Walk through simple blog app with mongoDB. Highlight some pitfalls and tips while learning Pyramid.

Published in: Technology, Education
  • Be the first to comment

Intro to Pyramid

  1. 1. Intro to Pyramid Building Fast and Flexible Web Apps by Brian Cajes
  2. 2. Overview <ul><ul><li>What is Pyramid? </li></ul></ul><ul><ul><li>Pyramid vs. Other Frameworks </li></ul></ul><ul><ul><li>MongoDB Integration </li></ul></ul><ul><ul><li>Some Things I've Learned </li></ul></ul><ul><ul><li>The Community & Resources </li></ul></ul><ul><ul><li>Wrap up & Questions </li></ul></ul>
  3. 3. My Background <ul><ul><li>Worked as a Software Engineer at a Financial Services Company </li></ul></ul><ul><ul><ul><li>Large legacy C++ code base </li></ul></ul></ul><ul><ul><ul><li>Hard to maintain and test </li></ul></ul></ul><ul><ul><li>Web apps on the side </li></ul></ul><ul><ul><ul><li>Want flexibility and testability in my web framework </li></ul></ul></ul><ul><ul><ul><li>Pyramid! </li></ul></ul></ul><ul><ul><li>Recently quit the finance job </li></ul></ul><ul><ul><li>Turned side project into start-up  </li></ul></ul>
  4. 4. What is Pyramid? <ul><ul><li>An open source web framework </li></ul></ul><ul><ul><li>Easier to create arbitrary web apps </li></ul></ul><ul><ul><li>Can be used to build wide array of applications </li></ul></ul><ul><ul><ul><li>Simple Blogs </li></ul></ul></ul><ul><ul><ul><li>CMS </li></ul></ul></ul><ul><ul><ul><li>Social Web Apps </li></ul></ul></ul><ul><ul><ul><li>... </li></ul></ul></ul>
  5. 5. Brief History <ul><li>  </li></ul><ul><ul><li>Pylons,TurboGears, Django(2005-) </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Repoze.bfg (2008-2010)  </li></ul></ul><ul><ul><ul><li>Influenced by Zope* (1998?-) </li></ul></ul></ul><ul><ul><ul><li>Chris Mcdonough </li></ul></ul></ul><ul><ul><li>Pylons, Repoze.bfg, TG merge into The Pylons Project  (2010) </li></ul></ul><ul><ul><ul><li>A collection of web related Python projects under a single umbrella    </li></ul></ul></ul><ul><ul><ul><li>Pylons development discontinued </li></ul></ul></ul><ul><ul><ul><li>Repoze.bfg renamed to Pyramid </li></ul></ul></ul><ul><ul><ul><li>Pyramid currently the main web framework </li></ul></ul></ul>
  6. 6. Setting up Pyramid <ul><li>$ virtualenv --no-site-packages env  </li></ul><ul><li>$ cd env  </li></ul><ul><li>$ bin/easy_install pyramid </li></ul><ul><li>$ bin/paster create -t pyramid_starter </li></ul><ul><li>  </li></ul>
  7. 7. Hello World <ul><li>from paste.httpserver import serve  </li></ul><ul><li>from pyramid.config import Configurator  </li></ul><ul><li>from pyramid.response import Response   </li></ul><ul><li>def hello_world(request):  </li></ul><ul><li>     return Response('Hello %(name)s!' %request.matchdict) </li></ul><ul><li>if __name__ == '__main__':  </li></ul><ul><li>     config = Configurator()  </li></ul><ul><li>     config.add_route('hello', '/hello/{name}') </li></ul><ul><li>    config.add_view(hello_world, route_name='hello')  </li></ul><ul><li>    app =  config.make_wsgi_app()  </li></ul><ul><li>    serve(app, host='0.0.0.0') </li></ul><ul><li>    </li></ul><ul><li>#serving on 0.0.0.0:8080 view at http://127.0.0.1:8080 </li></ul><ul><li>#url localhost:8080/hello/bob  -> prints 'Hello Bob!' in the browser </li></ul><ul><li>#full documentation and tutorials:  </li></ul><ul><li>#https://docs.pylonsproject.org/projects/pyramid/1.2/ </li></ul>
  8. 8. Pyramid's Tenets <ul><ul><li>Simplicity </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Minimalism </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Documentation </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Reliability </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Openness </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Speed </li></ul></ul><ul><li>  *https://www.pylonsproject.org/projects/pyramid/about </li></ul>
  9. 9. Simplicity <ul><ul><li>&quot;Only pay for what you eat&quot; </li></ul></ul><ul><li>  </li></ul><ul><ul><li>  Not forced to user any particular technology </li></ul></ul><ul><ul><ul><li>No DB </li></ul></ul></ul><ul><ul><ul><li>SQL </li></ul></ul></ul><ul><ul><ul><li>MongoDB </li></ul></ul></ul><ul><ul><ul><li>All okay </li></ul></ul></ul><ul><ul><li>Easy to set up basic apps </li></ul></ul>
  10. 10. Minimalism <ul><ul><li>Relatively small code base (~5000 lines) </li></ul></ul><ul><ul><ul><li>Django ~60,000 lines </li></ul></ul></ul><ul><li>  </li></ul><ul><ul><li>Concentrates on common core activities: URL mapping, templating, security, and serving static assets </li></ul></ul>
  11. 11. Documentation <ul><ul><li>Every aspect of the framework is documented </li></ul></ul><ul><li>  </li></ul><ul><ul><li>  https://docs.pylonsproject.org/ </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Coverage is good, but sometimes lacks good examples </li></ul></ul><ul><ul><ul><li>Improving over time </li></ul></ul></ul><ul><li>  </li></ul>
  12. 12. Reliability <ul><ul><li>Tested exhaustively </li></ul></ul><ul><li>  </li></ul><ul><ul><li>100% code test coverage </li></ul></ul><ul><li>  </li></ul><ul><ul><li>&quot;If it ain’t tested, it’s broke&quot; </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Source code has good examples of well written tests </li></ul></ul><ul><li>  </li></ul>
  13. 13. Openness <ul><ul><li>&quot;As with Python, the Pyramid software is distributed under a permissive open source license .&quot; </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Active community </li></ul></ul><ul><ul><ul><li>Main developers Chris McDonough, Ben Bangert, and others respond to question frequently </li></ul></ul></ul><ul><ul><ul><li>Growing library of open source pyramid related projects </li></ul></ul></ul>
  14. 14. Speed <ul><ul><li>Core functionality is optimized for very fast execution </li></ul></ul><ul><ul><li>Hardware maybe cheap these days </li></ul></ul><ul><ul><li>The time and energy needed to manage all that hardware is not so cheap </li></ul></ul><ul><li>  </li></ul>
  15. 15. Performance Comparison: String Test <ul><li>*http://blog.curiasolutions.com/the-great-web-framework-shootout/ </li></ul>
  16. 16. Performance Comparison: Templates <ul><li>*http://blog.curiasolutions.com/the-great-web-framework-shootout/ </li></ul>
  17. 17. Performance Comparison: Templates + DB Queries <ul><li>*http://blog.curiasolutions.com/the-great-web-framework-shootout/ </li></ul>
  18. 18. Profiling Comparison <ul><li>Numlines System 22 Pyramid (1.0a9) 34 Bottle (0.8.1) 57 Django (1.02) 96 Flask (0.6) 96 Pylons (0.9.7rc4) 250 Zope2 (2.10 via repoze.zope2) 317 Grok (1.0a1) 398 TurboGears 2 (2.0.3) </li></ul><ul><li>  *http://plope.com/pyroptimization </li></ul>
  19. 19. Component Architecture <ul><ul><li>Advantages of an un-opinionated framework </li></ul></ul><ul><ul><ul><li>Simplicity </li></ul></ul></ul><ul><ul><ul><li>Speed out of the box </li></ul></ul></ul><ul><ul><ul><li>Bring in &quot;best of breed&quot; components as you see fit </li></ul></ul></ul><ul><ul><li>Start Pyramid projects with pre-canned scaffolds if you want (eg. SQLAlchemy + URL dispatch) </li></ul></ul><ul><ul><li>Can add components by simply installing python packages </li></ul></ul>
  20. 20. Example: MongoDB Integration <ul><ul><li>Let's build a simple blog using Pyramid and MongoDB as the persistent store  </li></ul></ul><ul><li>  </li></ul><ul><ul><li>Easy enough to wire up mongoDB manually </li></ul></ul><ul><ul><ul><li>start here: https://docs.pylonsproject.org/projects/pyramid_cookbook/dev/mongo.html </li></ul></ul></ul><ul><li>  </li></ul><ul><ul><li>Or start with existing pyramid_mongodb template (ie. scaffold) by Niall O’Higgins </li></ul></ul><ul><ul><ul><li>  https://github.com/niallo/pyramid_mongodb </li></ul></ul></ul><ul><ul><ul><li>  easy_install pyramid_mongodb </li></ul></ul></ul><ul><ul><ul><li>  $ paster create --list-templates          Available templates:                    pyramid_mongodb:        pyramid MongoDB </li></ul></ul></ul>
  21. 21. Example: MongoDB Integration <ul><ul><li>__init__.py : wiring MongoDB to Pyramid </li></ul></ul><ul><li>  </li></ul><ul><li>def main(global_config, **settings): </li></ul><ul><li>     &quot;&quot;&quot; This function returns a Pyramid WSGI application. </li></ul><ul><li>&quot;&quot;&quot; </li></ul><ul><li>... </li></ul><ul><li>     db_uri = settings['db_uri'] </li></ul><ul><li>     conn = pymongo.Connection(db_uri) </li></ul><ul><li>     config.registry.settings['db_conn'] = conn </li></ul><ul><li>     config.add_subscriber(add_mongo_db, NewRequest) </li></ul><ul><li>... </li></ul><ul><li>     return config.make_wsgi_app() </li></ul><ul><li>def add_mongo_db(event): </li></ul><ul><li>     settings = event.request.registry.settings </li></ul><ul><li>     db = settings['db_conn'][settings['db_name']] </li></ul><ul><li>     event.request.db = db </li></ul><ul><li>  </li></ul><ul><li>  * https://github.com/supr/Blog   </li></ul><ul><li>* </li></ul>
  22. 22. Example: MongoDB Integration cont. <ul><ul><li>blog/views.py: making calls to MongoDB </li></ul></ul><ul><li>@view_config( route_name = &quot;home&quot;, renderer = &quot;index.mk&quot; ) </li></ul><ul><li>def home (request): </li></ul><ul><li>     entries =  request . db . Entries . find({},sort = [(&quot;datetime&quot;,DESCENDING)]) . limit(4) </li></ul><ul><li>     return { 'entries':entries } </li></ul>
  23. 23. Example: MongoDB Integration cont. <ul><ul><li>snippet from blog/templates/index.mk </li></ul></ul><ul><li>%for entry in entries: </li></ul><ul><li><h2>${entry['title'] | h,trim,unicode }</h2> </li></ul><ul><li><p>Posted by ${entry['username'] | h} on ${entry['datetime'].strftime(&quot;%A, %d %B %Y at %I:%M %p&quot;)}</p> </li></ul><ul><li><p>${entry['content'] | h,trim,unicode }</p> </li></ul><ul><li><p>Tags:${&quot;,&quot;.join(entry['tags'])}</p> </li></ul><ul><li>%endfor </li></ul>
  24. 24. Example: MongoDB Integration cont. <ul><ul><li>blog/templates/new.mk </li></ul></ul><ul><li><html> </li></ul><ul><li>     <head> </li></ul><ul><li>         <title> New Blog Post </title> </li></ul><ul><li>     </head> </li></ul><ul><li>     <body> </li></ul><ul><li>         <h1> New Post </h1> </li></ul><ul><li>         <form method=&quot;POST&quot;> </li></ul><ul><li>         <input type=&quot;text&quot; name=&quot;title&quot;/> </li></ul><ul><li>         <textarea name=&quot;content&quot;></textarea> </li></ul><ul><li>         <input type=&quot;text&quot; name=&quot;tags&quot;/> </li></ul><ul><li>         <input type=&quot;submit&quot; value=&quot;Post&quot;             name=&quot;form.submitted&quot;/> </li></ul><ul><li>         </form> </li></ul><ul><li>     </body> </li></ul><ul><li></html> </li></ul>
  25. 25. Example: MongoDB Integration cont. <ul><li>@view_config( route_name = &quot;new&quot;, renderer = &quot;new.mk&quot;, permission = &quot;new&quot; ) </li></ul><ul><li>def new_entry (request): </li></ul><ul><li>     message = '' </li></ul><ul><li>     if 'form.submitted' in request . params: </li></ul><ul><li>         try : </li></ul><ul><li>             title = request . params['title'] </li></ul><ul><li>             content = request . params['content'] </li></ul><ul><li>             tags = [ x . strip() for x in request . params['tags'] . split(&quot;,&quot;) ] </li></ul><ul><li>             username = authenticated_userid(request) </li></ul><ul><li>             entry = dict( </li></ul><ul><li>                 title = title, </li></ul><ul><li>                 content = content, </li></ul><ul><li>                 tags = tags, </li></ul><ul><li>                 username = username, </li></ul><ul><li>                 datetime = datetime . now(), </li></ul><ul><li>                 ) </li></ul><ul><li>             request . db . Entries . insert(entry) </li></ul><ul><li>         except : </li></ul><ul><li>             message = 'Invalid forum parameters' </li></ul><ul><li>             return dict( </li></ul><ul><li>                 message = message </li></ul><ul><li>                 ) </li></ul><ul><li>     return {} </li></ul>
  26. 26. Things I've Learned Along the Way <ul><ul><li>MongoDB ORM wrappers aren't needed for most use-cases </li></ul></ul><ul><ul><ul><li>Pymongo is simple and flexible </li></ul></ul></ul><ul><ul><ul><li>Easy to use within Pyramid </li></ul></ul></ul><ul><li>  </li></ul><ul><ul><li>Nose + Webtest </li></ul></ul><ul><ul><ul><li>Nose -  python test manager </li></ul></ul></ul><ul><ul><ul><li>Webtest - utility that helps with testing python web apps </li></ul></ul></ul><ul><ul><ul><li>They integrate well with pyramid </li></ul></ul></ul><ul><li>  </li></ul>
  27. 27. Things I've Learned Along the Way <ul><ul><li>Pyramid does not force the Model-View-Controller pattern on you </li></ul></ul><ul><ul><ul><li>Difficult to internalize if you're used to MVC everywhere </li></ul></ul></ul><ul><ul><ul><li>Free yourself from MVC </li></ul></ul></ul><ul><ul><ul><li>It's not always the best architecture pattern </li></ul></ul></ul><ul><ul><li>Choices == power </li></ul></ul><ul><ul><ul><li>but it can sometimes be overwhelming for beginners </li></ul></ul></ul><ul><ul><ul><li>Tutorials, examples, and documentation improving </li></ul></ul></ul><ul><li>  </li></ul>
  28. 28. Things I've Learned Along the Way cont. <ul><ul><li>Two methods of routing requests </li></ul></ul><ul><ul><ul><li>URL Dispatch </li></ul></ul></ul><ul><ul><ul><ul><li>Simple pattern matching </li></ul></ul></ul></ul><ul><ul><ul><ul><li>  Maps a view function to a URL pattern </li></ul></ul></ul></ul><ul><ul><ul><li>Traversal </li></ul></ul></ul><ul><ul><ul><ul><li>Analogous to opening a file/directory in your OS's file system   </li></ul></ul></ul></ul><ul><ul><ul><li>Stick with URL Dispatch if you're a beginner </li></ul></ul></ul><ul><li>  </li></ul><ul><ul><li>Templating Engine </li></ul></ul><ul><ul><ul><li>Comes with Chameleon and Mako support </li></ul></ul></ul><ul><ul><ul><li>I prefer Mako's syntax </li></ul></ul></ul><ul><li>  </li></ul>
  29. 29. Community <ul><ul><li>Community Contributions  </li></ul></ul><ul><ul><ul><li>Pyramid projects on Github </li></ul></ul></ul><ul><ul><ul><ul><li>Best way to learn (other than documentation)  </li></ul></ul></ul></ul><ul><ul><ul><li>Many pyramid_* packages and continuing to grow </li></ul></ul></ul><ul><li>  </li></ul><ul><ul><li>Google Groups </li></ul></ul><ul><ul><ul><li>http://groups.google.com/group/pylons-discuss </li></ul></ul></ul><ul><li>  </li></ul><ul><ul><li>IRC: #pylons on Freenode </li></ul></ul>
  30. 30. Summary <ul><ul><li>Pyramid is a fast and flexible web framework </li></ul></ul><ul><ul><li>Beats similar web frameworks in many performance metrics </li></ul></ul><ul><ul><li>Component Architecture </li></ul></ul><ul><ul><li>More choices and flexibility can be good in the long run, but maybe overwhelming for beginners at first </li></ul></ul><ul><ul><li>Learn from and contribute back to the Pylons Community </li></ul></ul>
  31. 31. Thanks for listening! <ul><ul><li>Twitter: bcajes </li></ul></ul><ul><ul><li>Questlr.com </li></ul></ul><ul><ul><ul><li>Connecting people and real life quests. Share goals, challenges, and stories while inspring others. </li></ul></ul></ul><ul><ul><ul><li>Beta signups  </li></ul></ul></ul><ul><li>  </li></ul><ul><li>  </li></ul><ul><li>  </li></ul><ul><li>  </li></ul><ul><li>Questions? </li></ul>

×