Click here to load reader
Upload
james-dennis
View
2.804
Download
1
Embed Size (px)
DESCRIPTION
A bird's eye view of Brubeck. Please see http://brubeck.io for more information.
Citation preview
What is Brubeck?
• A Mongrel2 Handler• A Web Framework– Influenced by Flask, Tornado and Django
• A pipeline of coroutines• Some coded opinions and a few libraries– Backend platform agnostic– Database agnostic– No spaghetti…
• implicit context switching
What is a “Mongrel2”?
• Mongrel2 is an asynchronous web server• Delegates handling to external handlers– We build that part anyway– Communicates via 2 ZeroMQ (zmq) sockets• Significantly less overhead than HTTP
• Language agnostic– Simple messaging via JSON or tnetstrings– Zmq is language agnostic, thus so is Mongrel2
Mongrel2 + A Handler
What is a Mongrel2 Handler?• Processes the Mongrel2 messages– Essentially, a Zed specific WSGI
• There has been some dissent: Y U NO USE WSGI?• Responds in HTTP format• A language opinion– Remember, ZeroMQ sockets are language agnostic– Zed chose Lua– I liked his model, but wanted to use Python.
• I like building stuff!– Lots of languages now supported
Mongrel2 + Brubeck(s)
class DemoHandler(WebMessageHandler): def get(self): self.set_body('Take five!') return self.render()
urls = [('^/brubeck', DemoHandler)]
class DemoHandler(WebMessageHandler): def get(self): self.set_body(’Take five!') return self.render()urls = [('^/brubeck', DemoHandler)]
OR just use functions…
@app.add_route('^/brubeck', method='GET')def foo(application, message): body = 'Take five!' return http_response(body, 200, 'OK', {})
Brubeck: templatesJinja2, Mako or Tornado templates are supported
class DemoHandler(..., Jinja2Rendering): def get(self): name = self.get_argument('name') context = { 'name' : name, } return self.render_template(’some.html', **context)
Brubeck: authSimple example, using `web_authenticated` decorator:
class DemoHandler(..., UserHandlingMixin): @web_authenticated def get(self): context = { 'name': self.current_user.username, } return self.render_template('some.html', **context)
• Also supports secure cookies• Routes users to login template• https://github.com/j2labs/brubeck/blob/master/demos/demo_login.py
Pipeline of Coroutines
Each request creates 3
1. Preprocessing• Currently just maps URL to handler
2. Request Handling• The part you write
3. Postprocessing• Just sends the HTTP response for now
Databaseless Modeling
This is a Brubeck User, built with DictShield
class User(Document): username = StringField(max_length=30, required=True) password = StringField(max_length=128) is_active = BooleanField(default=False) last_login = LongField(default=curtime) date_joined = LongField(default=curtime) ...
Databaseless Modeling
Validation is easy>>> u = User(username='jd', is_active=True)>>> u.set_password('foo')>>> u.validate() # no exception >>> u.username = True # this line makes no sense>>> u.validate() # thus, validation failsdictshield.base.DictPunch: username(True): Invalid value>>>
Databaseless ModelingCall `to_python()` for a dict
>>> user_instance.to_python(){ '_types': ['User'], '_cls': 'User', 'username': u'jd', 'is_active': False, 'last_login': 1311718487532L, 'password': u'bcrypt|||salt|||hash', 'date_joined': 1311718487532L}
Databaseless ModelingThe persistence details are up to you
# Mongo>>> db.users.save(u.to_python())
# Riak>>> user = bucket.new('user_key', data=u.to_python())>>> user.store()
# Memcached>>> mc["user_key"] = u.to_json()
Questions ??
Brubeck: http://brubeck.ioCode: http://github.com/j2labs/brubeck
Mongrel2: http://mongrel2.orgDictShield: http://github.com/j2labs/dictshield
Concurrency: http://eventlet.net or: http://gevent.org