Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Install Python 2.7 and then run:

easy_install flask sqlalchemy coffeescript alembic twilio
easy_install --index-url --upgrade stripe
git clone
cd python-markdown2
sudo python install

Or, install pip and then run:

pip install -r requirements.txt

Writing scripts

Scripts can be placed in the scripts/ directory. They can either be .js or .coffee. CoffeeScript source will be cached after compilation.

To reference from HTML, use scripts/foo.js no matter whether it's Javascript or CoffeeScript.

Routing and You

Example file, handlers/

from handler import handler

def get_index(id, bar=None):
	return 'foo %r %r' % (id, bar)

This will create a route for /echo/<id> that takes an optional GET parameter called bar. Hitting /echo/blah?bar=baz will return: foo u'blah' u'baz'. Note the unicode strings.

Dear Flask, it's me, Cody

If you are modifying data, make sure you start your function name with post_ rather than get_. This enforces the POST method and will require a CSRF token.

How the route was won

Routes are generated based on handler module name and method name. The code for this is really straightforward:

if module == 'index':
	route = '/'
	route = '/%s/' % module
if name != 'index':
	route += '%s/' % name
if len(args) and args[0] == 'id':
	route += '<id>'

So that means that a handler module named is the very root of the web app. A method named index (GET or POST -- you can have both if it makes sense!) is the root of a given handler. So the application's handler for / is a method named get_index in a handler module named Got it? Good.

The id argument must be the first to the function if you want to have it. This is handy for URLs like /user/55. All non-id arguments are optional. Handle their non-existence or perish.

Template Magic

One additional way to use handlers is to automatically spit out JSON or put your data into a template.

def get_foo():
	return True

This will return true as it's JSON-encoded.

def get_login():
	return dict(status='Login failed')

This will automatically output your login template (templates/login.html) with the status variable assigned.


Handlers can also provide automatic RPC.

def rpc_foo(blah):
	return dict(foo='bar', arg=blah)

This will automatically generate an RPC stub, which can be called from CoffeeScript:

$ 'baz', (data) ->
	console.log data

This will print out a dict {foo: 'bar', arg: 'baz'}. RPC methods cannot take id (they're assumed to just be another parameter), always return JSON, and can't have a template applied to them, obviously.


Handlers can take care of high-level authorization.

def get_admin():

def get_user(id):

Make sure that you handle fine-grained authorization in your own handlers.


CSRF tokens are taken care of on RPC calls and are required for all POSTs. Inside your forms, place $CSRF$ at the beginning and it'll be dealt with.


We're using Alembic for migrations, and they live in migrations/. Read this for more info.

Ensure you create a migration for anything that affects prod, but development should be done with SQLite and you should simply nuke your DB for each model change.


No description, website, or topics provided.




No releases published


No packages published