Python Web Applications With Flask - Part I

August 7, 2013

After writing Python FR for the Web, I've mostly been coding in the high-level frameworks. Recently, thanks to an awesome gig, I re-introduced myself to Flask, which is "a microframework for Python". Flask is a tool and a platform. Like any other tools there are right and wrong ways to use it. Unlike some other tools, however, it can be a little unclear how to get started and correctly use it.

Forward

Before we get started on how to use Flask, let's talk a little about the best practices and where some of the design ideas come from.

I've been developing web applications with Django for about a year and a half now. Django adheres to the "Don't Repeat Yourself" policy. One of the many reasons people use Django as their web-framework of choice is because it comes with equipped with a number of tools out of the box. Because so much is built in and because of the way Django is designed there is a "django" way of doing things. If you look at enough Django apps you'll start to see the patterns emerge and get a feeling for how to use it.

Most of the design patterns that I've seen emerge in Django projects are in line with some of Python's core principles. Python is itself a tool. In order for Django to be an effective tool it must use the tools it is constructed from correctly. If you didn't already know, Python has some coding "guidelines" that can help you figure out how to best use it.

They're called the Zen of Python.

To give them a read, simply open a python interpreter and type-

>>> import this

-and then you'll see

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Testing in Django (part 1) - Best practices and examples

August 5, 2013

Testing is vital. Without properly testing your code, you will never know if the code works as it should, now or in the future when the codebase changes. Countless hours can be lost fixing problems caused by changes to the codebase. What's worse, you may not even know that there are problems at all until your end users complain about it, which is obviously not how you want to find out about code breaks.

Having tests in place will help ensure that if a specific function breaks you will know about it. Tests also makes debugging breaks in code much easier, which saves time and money.

I've literally lost gigs in the past from not properly testing new features against the old codebase. Do not let this happen to you. Take testing seriously. You will have more confidence in your code, and your employer will have more confidence in you. It's essentially an insurance policy. Finally, testing helps you structure good code, find bugs, and write documentation.

In this post, we'll be first looking at brief introduction that includes best practices before looking at a few examples.

Intro to testing in Django

Types of tests

Unit and integration are the two main types of tests:

  • Unit Tests are isolated tests that test one specific function.
  • Integration Tests, meanwhile, are larger tests that focus on user behavior and testing entire applications. Put another way, integration testing combines different pieces of code functionality to make sure that they interact correctly.

Focus on unit tests. Write A LOT of these. These tests are much easier to write and debug vs. integration tests, and the more you have, the less integration tests you will need. Unit tests should be fast. We will look at a few techniques for speeding up tests.

That said, integration tests are sometimes still necessary even if you have coverage with unit tests, since integration tests can help catch code regressions.

In general, tests result in either a Success (expected results), Failure (unexpected results), or an error. You not only need to test for expected results, but also how well your code handles unexpected results.

Django is here.

August 3, 2013

Yes, you are reading that right. I have finally finished added Django to the course, including an in-depth introduction with a number of projects that segue into an enterprise application. The enterprise app is meant for you to launch your own ecommerce website in the MVP (minimum viable product) fashion.

Along with this update come a number of smaller updates:

  • Updated the Twitter API example to work with the new API version
  • Fixed all errors in the FlaskTaskr section and updated conventions
  • Corrected various grammatical errors throughout the course

You will receive an email today with the new download link if you already purchased the course. Cheers!

There's a lot more to come. Next week will be the first of a series of blog posts covering Flask Best Practices as well as Django Testing Best Practices/Examples.

The site will also be redesigned so that there will be a member's backend where you can download your purchased courses. Expect a slick new design. This transition, from a basic HTML website to a full web application, will also be turned into brand new content either for blog posts or the course itself.

Expect more videos, more content, and many more BIG things from Python FR. What would you like to see? Have any questions or suggestions? Please leave your comments below.

Have a great weekend!

Create a Super Basic REST API with django-tastypie

July 29, 2013

One of my clients literally called thirty minutes ago (last Friday) needing a JSON payload based on a GET response from the data model. I installed django-tastypie and thirty minutes later had the project completed. Although this example is overly simplified, it's not far off from my real-world implementation.

Note: Although this tutorial uses Django 1.5, the basic concepts will work on most versions greater than 1.3.

Setup

Either follow along below to create your sample Project or clone the repo from Github.

  1. Create a new directory, setup and activate virtualenv, install Django and the required dependencies:

    $ mkdir django-tastypie-tutorial
    $ cd django-tastypie-tutorial
    $ virtualenv --no-site-packages env
    $ source env/bin/activate
    $ pip install Django==1.5
    $ pip install django-tastypie==0.9.15
    $ pip install defusedxml==0.4.1
    $ pip install lxml==3.2.1
    
  2. Create a basic Django Project and App:

    $ django-admin.py startproject django15
    $ cd django15
    $ python manage.py startapp whatever
    

    Make sure to add the app to your INSTALLED_APPS section in settings.py.

  3. Add support for SQLite (or your RDMS of choice) in settings.py:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': 'test.db', 
        }
    }
    
  4. Enable the Django Admin.

  5. Update your models.py file:

    from django.db import models
    
    class Whatever(models.Model):
        title = models.CharField(max_length=200)
        body = models.TextField()
        created_at = models.DateTimeField(auto_now_add=True)
    
        def __unicode__(self):
            return self.title
    
  6. Sync the DB:

    $ python manage.py syncdb
    
  7. Fire up the Django Shell and populate the database:

    $ python manage.py shell
    >>> from whatever.models import Whatever
    >>> w = Whatever(title="What Am I Good At?", body="What am I good at? What is my talent? What makes me stand out? These are the questions we ask ourselves over and over again and somehow can not seem to come up with the perfect answer. This is because we are blinded, we are blinded by our own bias on who we are and what we should be. But discovering the answers to these questions is crucial in branding yourself.")
    >>> w.save()
    >>>
    >>> w = Whatever(title="Charting Best Practices: Proper Data Visualization", body="Charting data and determining business progress is an important part of measuring success. From recording financial statistics to webpage visitor tracking, finding the best practices for charting your data is vastly important for your company’s success. Here is a look at five charting best practices for optimal data visualization and analysis.")
    >>> w.save()
    >>>
    >>> w = Whatever(title="Understand Your Support System Better With Sentiment Analysis", body="There’s more to evaluating success than monitoring your bottom line. While analyzing your support system on a macro level helps to ensure your costs are going down and earnings are rising, taking a micro approach to your business gives you a thorough appreciation of your business’ performance. Sentiment analysis helps you to clearly see whether your business practices are leading to higher customer satisfaction, or if you’re on the verge of running clients away.")
    >>> w.save()
    

Developing with Bottle - part 2 (plot.ly API)

July 12, 2013

In this next post in the Developing with Bottle series, we'll be looking at both GET and POST requests as well as HTML forms. I'll also show you how to consume data from the plot.ly API. You'll also get to see how to create a cool graph showing the results of a cohort analysis study. (Click here if you are unfamiliar with cohort analysis.)

Click here to view part 1 if you missed it.

Basic Setup

  1. Start by downloading this Gist from Part 1, and then run it using the following command:

    $ bash bottle.sh
    

    This will create a basic project structure:

    ├── app.py
    ├── requirements.txt
    └── testenv
    
  2. Activate the virtualenv:

    $ source testenv/bin/activate
    
  3. Install the requirements:

    $ pip install -r requirements.txt
    
  4. Navigate to https://www.plot.ly/api, sign up for a new account, sign in, and then create a new API key (do NOT use mine):

    API

  5. Install plot.ly:

    $ pip install plotly
    
  6. Next update the code in app.py:

    import os
    from bottle import run, template, get, post, request
    from plotly import plotly
    
    py = plotly(username='mjhea0', key='2ic27cpzex')
    
    @get('/plot')
    def form():
        return '''<h2>Graph via Plot.ly</h2>
                  <form method="POST" action="/plot">
                    Name: <input name="name1" type="text" />
                    Age: <input name="age1" type="text" /><br/>
                    Name: <input name="name2" type="text" />
                    Age: <input name="age2" type="text" /><br/>
                    Name: <input name="name3" type="text" />
                    Age: <input name="age3" type="text" /><br/>                
                    <input type="submit" />
                  </form>'''
    
    @post('/plot')
    def submit():
        name1   = request.forms.get('name1')
        age1    = request.forms.get('age1')
        name2   = request.forms.get('name2')
        age2    = request.forms.get('age2')
        name3   = request.forms.get('name3')
        age3    = request.forms.get('age3')
    
        x0 = [name1, name2, name3];
        y0 = [age1, age2, age3];
        data = {'x': x0, 'y': y0, 'type': 'bar'}
        response = py.plot([data])
        url = response['url']
        filename = response['filename']
        return template('''Congrats! View your chart here <a href=""></a>!''', url=url)
    
    if __name__ == '__main__':
        port = int(os.environ.get('PORT', 8080))
        run(host='0.0.0.0', port=port, debug=True)
    

    What's going on here?

    In the first function, form(), we created an HTML form for capturing the data we need to make a bar graph. Then in the second function, submit(), we grabbed the form inputs, assigned them to variables, then used the plot.ly API to generate a new chart. Make sure you replace the username and key variables with your own credentials.

  7. Run your app locally, python app.py, and go to http://localhost:8080/plot.

  8. Enter the names of three people and their respective ages. Press submit, and then if all is well you should see a congrats message and a URL. Click the URL to view your graph:

    graph