Intro to Pyramid


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

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • -In this talk I'm going to give you a high level overview of Pyramid -Highlight some advantages and disadvantages vs. other frameworks -We'll walk through MongoDB integration with a simple blog app -II'll go over some pitfals i've encountered while learning pyramid -I'll point you at some resources that should help you get started -And finally we'll have plenty of questions - 1. peak your interest enough for you to try it out. 2. provide you with some examples of how to use it 3. Give you tips and point you in the right direction so you can create your own pyramid apps.
  • -Just a little background -I used to work as a software engineer at a financial services company -We had a very large legacy C++ (and some python) code base -It was very hard to maintain and test -You gain an appreciation for good design and tests. I'm sure many of you can relate -So when I decided to start building web apps for fun  about a year ago and while I was looking for a framework; extensible design and and testability were very high on my list. -I tried out django and other web frameworks, but the framework that ended up having the best balance for my needs was Pyramid -So, thats what I ended up running with 
  • -It's primary function is to make it easier to build and maintain web apps -Similar to Django, Rails,  and other web frameworks -But it focuses more on "maintenance" and "flexability" that other web frameworks  -It's general enough that it can be used to build a wide array of apps -Everything from Simple blogs, to intranets, to CMS, and Social platforms.
  • -Around 2004-2005 there was an explosion of web frameworks -Ruby on Rails in 2004, Pylons, TurboGears, Django around 2005 -Then came along Repoze.bfg around 2008, which was influenced by the Zope web frameworks -Then a couple years later Pylons, Repoze, and TG merge into the Pylons project -The Pylons project is a collection of we relaated python projects under a single umbrella (think Apache) -Pylons development was discontinued -Repoze.bfg was re-branded as Pyramid.  thank goodness, because you can't think of a worst name than Repoze.BFG -Now Pyramid is currently the main web framework under the Pylons project
  • -Wont go into too much technical detail, but here's how you would typically start a pyramid project -You would create your virtual environment -Virtualenv, for those of you that are unfamiliar, alows you to create isolated python environments.  Useful, because it prevent conflicts between globally installed and other development packages. -easy or pip install pyramid -Run this create command -It will generate a "scaffold" or template for you to build your app in
  • -Lets look at a very basic  pyramid application -This app will display the text "Hello World!" if you do to localhost:8080/hello/bob -we create a config object -add a route named "hello" that maps to a URL that matches this pattern: /hello/{name} -attach the route to a view callable -which is this function above -This view callable refferences the name variable, passed in via the url and it's appended to the response -When the app is ran, and we go to local host:8080/hello/world -we see hello world in the browser -if we go to localhost:8080/hello/mars Hello Mars is shown in the browser
  • -Not all web apps are equal, they each have different areas of focus -Pyramid focuses on excelling in these following 6 tenets
  • -Let's look into each one of these -Only pay for what you eat -You're not forced to use any particular technology -You add components as you see fit
  • -Pyramid has a relatively small code base -Out of the box it provides only core functionality -This tenet helps it stay fast and flexible, we'll go more into its performance soon
  • -You can see the docs, which include tutorials, cookbooks, etc here -Documentation isn't as abundant as django and other mature frameworks, but it's continuing to improve
  • -not only do the tests cover every line of code, but they are well written -If you want examples of how to write good tests, see the pyramid source code -Their moto is if it aint tested its broken
  • -Pyramid is of cource open souce -And the community is very active -Main developers... -There's also a growing library of pyramid related projects on github
  •   -How fast can we make requests and spit out the hello world string per second -More requests per second the better
  •   -The template test spits out Lorem Ipsum via a template (thus engaging the framework’s templating systems).  
  •   The template/db test: This test loads 5 rows of Lorem Ipsum from a SQLite DB (via the default ORM or a sqlite3 driver) and then prints them out through a template (thus engaging both the framework’s ORM/DB driver and the templating system).
  • Number of lines of profiler output generated by 1000 hits to a hello world application As you can see Pyramid makes significantly less function calls ----- -he "numlines" value above is the number of lines of profiler output generated by 1000 hits to a warm "hello world" application in each framework. This number was taken from the "Profile lines" data point in each "results.txt" of each subdirectory of the reporting data. This metric counts the number of lines output by the Python profiler after these 1000 hits.   -While a lower number doesn't necessarily always mean the system is faster or simpler on every axis, there is often a correlation between the number of profile lines output and the relative complexity and speed of the very core of the system being tested.    -good example of minimalism 
  • -So we've seen how well Pyramid can perform, how well does it do in terms of flexibility -bullet 1 -whatever you think best of breed is -Pyramid does allow you to start projects using scaffolds or pre-canned templates -for example you can use the SQLAlchemy scaffold if you want that ORM to handle your persistant store -New components come out frequently and you can see them being integrated into pyramid on github
  • -The official pymongo API is simple enough and flexible     
  • -Some of the things I spent way too much time wrestling with where routing methods and template engines
  • -Questlr (without the second e) is what I'm currently working on
  • 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='') </li></ul><ul><li>    </li></ul><ul><li>#serving on view at </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># </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>  * </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> </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>* </li></ul>
    16. 16. Performance Comparison: Templates <ul><li>* </li></ul>
    17. 17. Performance Comparison: Templates + DB Queries <ul><li>* </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>  * </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: </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> </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> : 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>  *   </li></ul><ul><li>* </li></ul>
    22. 22. Example: MongoDB Integration cont. <ul><ul><li>blog/ making calls to MongoDB </li></ul></ul><ul><li>@view_config( route_name = &quot;home&quot;, renderer = &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/ </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/ </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;;, 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> </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> </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>