Flask Quickstart with some Quick Changes

An App Framework without too much Framework

One of the pieces that we built was a Web Application framework on top of Werkzeug. I fell in love with Werkzeug as soon as I learned how to spell it. It reminded me so much of how I learned how to do things with web apps in Django (but without the Django) and also has the world's most amazing debugger. I had heard a lot about Flask and how it was werkzeug based, but never explored it, so thought this time around it would be worth using.

I started with the Flask Quickstart tutorial but quickly made a couple changes to how I structured my application as it would scale.

While the URL routing decorator is a nice and easy to use shortcut, I had visions of url decorators distributed in views all over the place in files and folders that will get lost over time in the code base (can you tell I came from a messy codebase?) and felt like organizing them into a single file was important. So I created a urls.py file that would contain all the routing (similar to Django in that it's all in one place.)

from kickbacker import app
from kickbacker import views

@app.route('/backer/<backer_id>')
def respond_backers(backer_id):
        return views.show_backer(backer_id)

@app.route('/project/<project_id>/backers/')
def respond_show_backers(project_id):
        return views.show_backers(project_id)

@app.route('/projects')
def respond_projects():
        return views.show_projects()

I decided that I was going to use redis as my primary database and wanted a way to add that as a global variable to my flask app. Sub-classing the Flask class seemed the best way. While I was in there I decided to define the logging to use a more descriptive format and to use a RotatingFileHandler since I tend to add logging in way more places than I need to.

class KickFlask(Flask):

        def connect_redis(self):
                self.rs = redis.Redis(self.config['REDIS_HOST'])
                self.logger.info("Connected to Redis at %s" % \
                                        (self.config['REDIS_HOST']) )

        def setup_logging(self):
                log_filename = self.config['LOGFILE']
                file_handler = RotatingFileHandler(log_filename)
                if self.config['DEBUG']:
                        file_handler.setLevel(logging.INFO)
                else:
                        file_handler.setLevel(logging.ERROR)

                kb_fmt = u'[%(asctime)s %(levelname)s] - %(processName)s (%(process)s) - (%(module)s:%(funcName)s:%(lineno)s) %(message)s'
                kb_formatter = logging.Formatter(fmt=kb_fmt)
                file_handler.setFormatter(kb_formatter)

                self.logger.addHandler(file_handler)

Here is what my __init__.py file looks like, which connects to redis and sets up logging on start.

from kickflask import KickFlask
app = KickFlask(__name__)
app.config.from_object('kickbacker.settings.DevConfig')

app.setup_logging()
app.connect_redis()

import urls

I also decided to use the handy from_object method to load in different settings classes based on whether the application is running in a Production or a Development environment. For now I only have one environment setup but once a production is setup I can add some if/else logic to look for some file, uname, internal IP or something that is specific to production.

Here is my settings.py file

# Here lie the settings
class Config(object):
        DEBUG=False
        HOST='0.0.0.0'
        REDIS_HOST='localhost'
        LOGFILE='/var/log/kickbacker.log'

class ProdConfig(Config):
        DEBUG=False

# Run Server in Debug Mode
class DevConfig(Config):
        DEBUG=True

These changes are going to make it flexible enough for me to organize my urls all in one place, customize my Flask application to any number of random things, and also modify the settings for multiple environments I will end up needing later on (like a testing one.)

Afterword

I am currently working on a side project where the primary goal is to explore many of the widely-used open source alternatives to some of the pieces we attempted to build in-house at my last job: a werkzeug-powered app framework, a job queue, a local cache layer. But also to explore some of the other technologies that have become popular over the past few years: NoSQL, Node.js and who knows what else.

Posts (so far) in this Series

Comments !

About

Started writing one year ago, the day after heading out to travel around the world for a year without a cause.
Current Location: New York, New York

Previously:
Mexico City, Mexico
Tokyo, Japan
Hanoi, Vietnam
Vientiane, Laos
Phuket, Thailand
Kathmandu, Nepal
Rajastan, India
Kerala, India
Mumbai, India
Freetown, Sierra Leone
Koidu, Sierra Leone
Mombasa, Kenya
Nairobi, Kenya
Kigali, Rwanda
Rwinkwavu, Rwanda
Boston, MA

Latest Posts

Port Forward an old Airport Express

If Developers Took Steroids

We Need Elon Musk

Crossword Scraper

Git Conflicts in your Binary Files

Japanese Sidewalk Interfaces

Introducing Kickbacker

Real Life: Google Glass Done Wrong

Tux Trashcans

How Angry are your Developers?

A 500 Startups Model for the Art World

Unsubscribe from Black Friday/Cyber Monday

Copyrighting Art into Obscurity

Crack WiFi Passwords with aircrack

Using Sandy as an Excuse to Email Spam Customers