Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jiaaro/2657094 to your computer and use it in GitHub Desktop.
Save jiaaro/2657094 to your computer and use it in GitHub Desktop.
Brubeck on heroku with gunicorn
#!/bin/bash
#
# Note: This is the only file you *really* need. I've copied the contents
# of the important files that are part of our git repo for easier reading
# below :)
#
# I've prefixed this file with two dots to make it rise to the top of the
# gist. you can ignore those
#
# Create and enter a virtualenv called "myapp"
mkvirtualenv myapp --no-site-packages
workon myapp
mkdir myapp
cd myapp
# Install the dependencies and throw it in a requirements file (used by heroku)
pip install git+git://github.com/j2labs/brubeck.git dictshield ujson gevent gunicorn
pip freeze > requirements.txt
# This is a basic app
cat << EOF > app.py
from brubeck.request_handling import Brubeck, WebMessageHandler
from brubeck.connections import WSGIConnection
class DemoHandler(WebMessageHandler):
def get(self):
self.set_body("Hello, from Brubeck!")
return self.render()
config = {
'msg_conn': WSGIConnection(),
'handler_tuples': [
(r'^/', DemoHandler)
]
}
app = Brubeck(**config)
# This is the wsgi handler used by gunicorn
def application(environ, callback):
return app.msg_conn.process_message(app, environ, callback)
EOF
# Tell heroku how to run it
cat << EOF > Procfile
web: gunicorn app --bind "0.0.0.0:\$PORT" --workers 3
EOF
cat << EOF > .gitignore
*.pyc
EOF
# create a git repo for the code so we can push it into heroku
git init .
git add .
git commit -a -m "initial commit"
# create the heroku app and push our app into it
heroku create --stack cedar
git push heroku master
# open the site we just created
heroku open
from brubeck.request_handling import Brubeck, WebMessageHandler
from brubeck.connections import WSGIConnection
class DemoHandler(WebMessageHandler):
def get(self):
self.set_body("Hello, from Brubeck!")
return self.render()
config = {
'msg_conn': WSGIConnection(),
'handler_tuples': [
(r'^/', DemoHandler)
]
}
app = Brubeck(**config)
def application(environ, callback):
return app.msg_conn.process_message(app, environ, callback)
web: gunicorn app --bind "0.0.0.0:$PORT" --workers 3
brubeck==0.4.0
dictshield==0.4.3
gevent==0.13.7
greenlet==0.3.4
gunicorn==0.14.2
ujson==1.18
wsgiref==0.1.2
@j2labs
Copy link

j2labs commented May 11, 2012

This all looks great. I am not sure about this piece though.

app = Brubeck(**config)

def application(environ, callback): 
    return app.msg_conn.process_message(app, environ, callback)

Is it necessary to have a function called application or could you just call app.run() ?

@jiaaro
Copy link
Author

jiaaro commented May 12, 2012

gunicorn looks for a function called application by default (if you don't call it application you have to specify it in the command line call like so (say it was def ponies(environ, callback): ...):

gunicorn app:ponies --bind "0.0.0.0:$PORT" --workers 3

The reason I didn't call app.run is that app.run() starts up it's own wsgi server, but in this case we want gunicorn to be the wsgi server.

app.msg_conn.process_message() is the function that the built in brubeck wsgi server uses to process the incoming requests. application() is just a wrapper function to pass the app argument that WSGIConnection.process_message expects. (normally I would have used functools.partial but I wanted it to keep it simple).

@j2labs
Copy link

j2labs commented May 13, 2012

That makes sense. Thank you for the explanation!

Would you be willing to write that section and submit a pull request? I'd be happy to put your comments in the Brubeck docs if you're short on time, but I like trying to maintain an accurate account of where ideas come from.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment