intro to pyramid

31
tro to Pyramid Building Fast and Flexible Web Apps by Brian Cajes

Upload: brian-cajes

Post on 17-Jan-2015

4.417 views

Category:

Technology


0 download

DESCRIPTION

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.

TRANSCRIPT

Page 1: Intro to Pyramid

Intro to Pyramid

Building Fast and Flexible Web Apps

byBrian Cajes

Page 2: Intro to Pyramid

Overview

• What is Pyramid?• Pyramid vs. Other Frameworks• MongoDB Integration• Some Things I've Learned• The Community & Resources• Wrap up & Questions

Page 3: Intro to Pyramid

My Background

• Worked as a Software Engineer at a Financial Services Companyo Large legacy C++ code baseo Hard to maintain and test

• Web apps on the sideo Want flexibility and testability in my web frameworko Pyramid!

• Recently quit the finance job• Turned side project into start-up 

Page 4: Intro to Pyramid

What is Pyramid?

• An open source web framework• Easier to create arbitrary web apps• Can be used to build wide array of

applicationsoSimple BlogsoCMSoSocial Web Appso ...

Page 5: Intro to Pyramid

Brief History • Pylons,TurboGears, Django(2005-)

 • Repoze.bfg (2008-2010) 

o Influenced by Zope* (1998?-)o Chris Mcdonough

• Pylons, Repoze.bfg, TG merge into The Pylons Project (2010)o A collection of web related Python projects under a single

umbrella   o Pylons development discontinued o Repoze.bfg renamed to Pyramid o Pyramid currently the main web framework

Page 6: Intro to Pyramid

Setting up Pyramid

$ virtualenv --no-site-packages env 

$ cd env 

$ bin/easy_install pyramid $ bin/paster create -t pyramid_starter

 

Page 7: Intro to Pyramid

Hello Worldfrom paste.httpserver import serve from pyramid.config import Configurator from pyramid.response import Response  

def hello_world(request):     return Response('Hello %(name)s!' \%request.matchdict)

if __name__ == '__main__':     config = Configurator()     config.add_route('hello', '/hello/{name}')    config.add_view(hello_world, route_name='hello')     app =  config.make_wsgi_app()     serve(app, host='0.0.0.0')   #serving on 0.0.0.0:8080 view at http://127.0.0.1:8080

#url localhost:8080/hello/bob  -> prints 'Hello Bob!' in the browser

#full documentation and tutorials: 

#https://docs.pylonsproject.org/projects/pyramid/1.2/

Page 8: Intro to Pyramid

Pyramid's Tenets

• Simplicity • Minimalism

 • Documentation

 • Reliability

 • Openness

 • Speed

 *https://www.pylonsproject.org/projects/pyramid/about

Page 9: Intro to Pyramid

Simplicity

• "Only pay for what you eat" •  Not forced to user any particular technology

o No DBo SQLo MongoDBo All okay

• Easy to set up basic apps

Page 10: Intro to Pyramid

Minimalism

• Relatively small code base (~5000 lines)o Django ~60,000 lines

 • Concentrates on common core activities: URL mapping,

templating, security, and serving static assets

Page 11: Intro to Pyramid

Documentation

• Every aspect of the framework is documented •  https://docs.pylonsproject.org/

 • Coverage is good, but sometimes lacks good examples

o Improving over time 

Page 12: Intro to Pyramid

Reliability

• Tested exhaustively • 100% code test coverage

 • "If it ain’t tested, it’s broke"

 • Source code has good examples of well written tests

 

Page 13: Intro to Pyramid

Openness

• "As with Python, the Pyramid software is distributed under a permissive open source license."

 • Active community

o Main developers Chris McDonough, Ben Bangert, and others respond to question frequently

o Growing library of open source pyramid related projects

Page 14: Intro to Pyramid

Speed

• Core functionality is optimized for very fast execution

• Hardware maybe cheap these days

• The time and energy needed to manage all that hardware is not so cheap

 

Page 15: Intro to Pyramid

Performance Comparison: String Test

*http://blog.curiasolutions.com/the-great-web-framework-shootout/

Page 16: Intro to Pyramid

Performance Comparison: Templates

*http://blog.curiasolutions.com/the-great-web-framework-shootout/

Page 17: Intro to Pyramid

Performance Comparison: Templates + DB Queries

*http://blog.curiasolutions.com/the-great-web-framework-shootout/

Page 18: Intro to Pyramid

Profiling Comparison

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)

 *http://plope.com/pyroptimization

Page 19: Intro to Pyramid

Component Architecture

• Advantages of an un-opinionated frameworko Simplicityo Speed out of the boxo Bring in "best of breed" components as you see fit

• Start Pyramid projects with pre-canned scaffolds if you want (eg. SQLAlchemy + URL dispatch)

• Can add components by simply installing python packages

Page 20: Intro to Pyramid

Example: MongoDB Integration• Let's build a simple blog using Pyramid and MongoDB as

the persistent store  • Easy enough to wire up mongoDB manually

o start here: https://docs.pylonsproject.org/projects/pyramid_cookbook/dev/mongo.html

 • Or start with existing pyramid_mongodb template (ie.

scaffold) by Niall O’Higginso  https://github.com/niallo/pyramid_mongodbo  easy_install pyramid_mongodbo  $ paster create --list-templates          Available templates:                    pyramid_mongodb:        pyramid MongoDB

Page 21: Intro to Pyramid

Example: MongoDB Integration• __init__.py : wiring MongoDB to Pyramid

 def main(global_config, **settings):    """ This function returns a Pyramid WSGI application."""...    db_uri = settings['db_uri']    conn = pymongo.Connection(db_uri)    config.registry.settings['db_conn'] = conn    config.add_subscriber(add_mongo_db, NewRequest)...    return config.make_wsgi_app()

def add_mongo_db(event):    settings = event.request.registry.settings    db = settings['db_conn'][settings['db_name']]    event.request.db = db  *https://github.com/supr/Blog 

*

Page 22: Intro to Pyramid

Example: MongoDB Integration cont.

• blog/views.py: making calls to MongoDB

@view_config( route_name = "home", renderer = "index.mk" )def home(request):    entries = request.db.Entries.find({},sort=[("datetime",DESCENDING)]).limit(4)    return { 'entries':entries }

Page 23: Intro to Pyramid

Example: MongoDB Integration cont.

• snippet from blog/templates/index.mk

%for entry in entries:<h2>${entry['title'] | h,trim,unicode }</h2><p>Posted by ${entry['username'] | h} on ${entry['datetime'].strftime("%A, %d %B %Y at %I:%M %p")}</p><p>${entry['content'] | h,trim,unicode }</p><p>Tags:${",".join(entry['tags'])}</p>%endfor

Page 24: Intro to Pyramid

Example: MongoDB Integration cont.

• blog/templates/new.mk

<html>    <head>        <title> New Blog Post </title>    </head>    <body>        <h1> New Post </h1>        <form method="POST">        <input type="text" name="title"/>        <textarea name="content"></textarea>        <input type="text" name="tags"/>        <input type="submit" value="Post"             name="form.submitted"/>        </form>    </body></html>

Page 25: Intro to Pyramid

Example: MongoDB Integration cont.

@view_config( route_name = "new", renderer = "new.mk", permission = "new" )def new_entry(request):    message = ''    if 'form.submitted' in request.params:        try:            title = request.params['title']            content = request.params['content']            tags = [ x.strip() for x in request.params['tags'].split(",") ]            username = authenticated_userid(request)            entry = dict(                title = title,                content = content,                tags = tags,                username = username,                datetime = datetime.now(),                )            request.db.Entries.insert(entry)        except:            message = 'Invalid forum parameters'            return dict(                message = message                )    return {}

Page 26: Intro to Pyramid

Things I've Learned Along the Way

• MongoDB ORM wrappers aren't needed for most use-caseso Pymongo is simple and flexibleo Easy to use within Pyramid

 • Nose + Webtest

o Nose -  python test managero Webtest - utility that helps with testing python web appso They integrate well with pyramid

 

Page 27: Intro to Pyramid

Things I've Learned Along the Way

• Pyramid does not force the Model-View-Controller pattern on youo Difficult to internalize if you're used to MVC everywhereo Free yourself from MVCo It's not always the best architecture pattern

• Choices == powero but it can sometimes be overwhelming for beginnerso Tutorials, examples, and documentation improving

 

Page 28: Intro to Pyramid

Things I've Learned Along the Way cont.

• Two methods of routing requestso URL Dispatch

Simple pattern matching  Maps a view function to a URL pattern

o Traversal Analogous to opening a file/directory in your OS's file

system  o Stick with URL Dispatch if you're a beginner

 • Templating Engine

o Comes with Chameleon and Mako supporto I prefer Mako's syntax

 

Page 29: Intro to Pyramid

Community

• Community Contributions o Pyramid projects on Github

Best way to learn (other than documentation)  o Many pyramid_* packages and continuing to grow

 • Google Groups

o http://groups.google.com/group/pylons-discuss • IRC: #pylons on Freenode

Page 30: Intro to Pyramid

Summary

• Pyramid is a fast and flexible web framework• Beats similar web frameworks in many performance metrics • Component Architecture• More choices and flexibility can be good in the long run, but

maybe overwhelming for beginners at first• Learn from and contribute back to the Pylons Community

Page 31: Intro to Pyramid

Thanks for listening!

• Twitter: bcajes• Questlr.com

o Connecting people and real life quests. Share goals, challenges, and stories while inspring others.

o Beta signups     

Questions?