This is a guest post by the awesome @apiguy, aka Freedom Dumlao. You can read more by him at his site Dash Rocket.
If you’ve spent any time thinking about developing web applications in Python, no doubt you’ve considered, and maybe even tried Flask. It’s an amazing little framework with massive appeal. I love it’s minimal and a la carte approach to features, and I love that it makes getting started easier than any other framework I’ve worked with in the past.
One place where Flask really distinquishes itself from the rest of the pack is it’s approach to supporting larger applications. The framework includes two methods for organizing your views beyond the global scope of the main module, either Blueprints, a novel aproach using a mock application object in seperate Python modules, or using special class based views from the flask.view module. Both are useful in many cases, but for me neither really quite fit.
Blueprints work well for grouping similar views together, such as all the views for your admin interface. It’s a great help when trying to organize a large project, but suffers from a lack of a managed context. I wanted to be able to specify data and behaviors that were important and applicable only to a certain set of views and outside of putting stuff in the request object my options were limited.
The flask.view View classes are pretty interesting and provide some class based context, but they don’t help much with grouping similar views together. I found myself writing much more code than seemed reasonable when using them and started to lose the feeling of working with a simple framework that got out of my way and let me focus on what my application was trying to do.
Enter Flask-Classy. My idea seemed simple. Let me group my application views in a way that was both logical and provided a context that was extensible. I examined my own projects and those of my colleagues to find patterns that could easily be simplified by use of a few basic, common conventions.
The most common pattern I found was creating RESTful endpoints for resources in an application. There were a few solutions out there but the most common pattern I found was one I had used myself on more than a few occasions:
@route(‘/entry/<id>’, methods=[‘GET’, ‘PUT’])
def entry(id):
if request.method == “GET”:
…
elif request.method == “PUT”:
…
Or alternatively:
@route(‘/entries/<id>’, methods=[‘GET’])
def get_entry(id):
…
@route(‘/entries/<id>’, methods=[‘PUT’])
def put_entry(id):
…
Neither of these methods is easy to manage once your application has more than a few entities. So task #1 for Flask-Classy was to make that better. I achieved this by making Flask-Classy aware of common RESTful CRUD operations, so you could easily just define some methods of a class and get the common functionality for free:
class EntriesView(FlaskView):
def get(id):
…
def put(id):
…
This way all of your related views could be grouped together in classes that are located anywhere in your application. You get complete control over the structure of your code and you get to write less of it!
After the basic CRUD stuff was in there I went ahead and added support for adding your own methods and getting automatic routing for them as well. I’ve added a custom routing decorator and subdomain support to make sure that experienced Flask developers don’t have to leave any of their favorite features behind, and I’m contiuing to add new features with the help of the amazing Flask community all the time.
So for your next web app, give Flask and Flask-Classy a try. I’d love your feedback, feature ideas, and criticisms. (OK if we’re being honest I probably don’t want your criticism, but I’ll take it anyway.)
- Documentation: http://packages.python.org/Flask-Classy/
- GitHub: https://github.com/apiguy/flask-classy