Flask by Example - Part 1 - Project Setup

2014-04-21

The following is a guest post by Cam Linke, co-founder of Startup Edmonton.


Welcome! Today we're going to build an app using Flask with a simple text box that you enter text into and the app processes and displays a count of how many times each word appears on the page.

  1. In part one, we'll set up a local development environment and then deploy both a staging environment and a production environment on Heroku.
  2. In part two, we'll be doing a bunch of backend processing to count the words of a web page so we’ll implement a request queue that will do the actual processing of the words.

Setup

We'll start with a basic "Hello World" app on Heroku with staging (or pre-production) and production environments.

To get our initial setup created we're going to use Virtualenv and Virtualenvwrapper. This will give us a few extra tools to help us silo our environment. I'm going to assume for this tutorial you've used the following tools before:

First things first, let's get a repo set up. Create a repo in Github (if you want) and clone it into your working directory. Alternatively, initialize a new git repo within your working directory:

Using Flask-Login for User Management with Flask

2014-04-07

The following is a guest post by Jeff Knupp, author of Writing Idiomatic Python. Jeff currently has a Kickstarter campaign running to turn the book into a video series - check it out!


A few months ago, I grew tired of the digital goods payment service I used to sell my book and decided to write my own. Two hours later, bull was born. It was a little application written using Flask and Python, which turned out to be an excellent choice for implementation. It started with bare bones functionality: A customer could enter their details in a Stripe JavaScript pop-up, bull would record their email address and create a unique id for the purchase, then associate the user with the content they purchased.

It worked fantastically well. Whereas before a potential customer had to not only, enter their full name and address (both of which I had no use for), they also had to create an account on my payment processor's site. I'm not sure how many sales I lost due to the convoluted checkout process, but I'm sure it was a good deal. With bull, the time between clicking the "Buy Now" button on the book sales page to actually reading the book was about 10 seconds. Customers loved it.

I loved it too, but for a slightly different reason: since bull was running on my web server, I could get a much richer set of analytics than if I had to send customers to a third-party site for payment. This opened the door to a host of new possibilities: A/B testing, analytics reports, custom sales reports. I was stoked.

Adding Users

I decided that, at a minimum, I wanted bull to be able to display a "Sales Overview" page that contained basic sales data: transaction information, graphs of sales over time, etc. To do that (in a secure manner), I needed to add authentication and authorization to my little Flask app. Helpfully, though, I only needed to support a single, "admin" user who was authorized to view reports.

Luckily, as is usually the case, a third-party package already existed to handle this. Flask-login is a Flask extension that enables user authentication. All that's required is a User model and a few simple functions. Let's take a look at what was required.

The User Model

bull was already using Flask-sqlalchemy to create purchase and product models which captured the information about a sale and a product, respectively. Flask-login requires a User model with the following properties:

Primer on Jinja Templating

2014-03-03

jinga2

Right out of the box, Flask includes the powerful Jinja templating language. It's modeled after Django templates (but it renders much faster) and, although, Flask does not force you to use any templating language, it assumes that you'll be using Jinja since it does come pre-installed.

For those who have not been exposed to a templating language before, such languages essentially contain variables as well as some programming logic, which when evaluated (or rendered into HTML) are replaced with actual values. The variables and/or logic are placed between tags or delimiters. For example, Jinja templates use {% ... %} for expressions or logic (like for loops), while {{ ... }} are used for outputting the results of an expression or a variable to the end user. The latter tag, when rendered, is replaced with a value or values, and are seen by the end user.

Jinja Templates are just .html files. By convention they live in the "/templates" directory in a Flask project. If you're familiar with string formatting or interpolation, templating languages follow a similiar type of logic - just on the scale of an entire HTML page.

Quick Examples

Make sure you have Jinja installed before running these examples - pip install jinja2

>>> from jinja2 import Template
>>> t = Template("Hello {{ something }}!")
>>> t.render(something="World")
u'Hello World!'
>>>
>>> t = Template("My favorite numbers: {% for n in range(1,10) %}{{n}} " "{% endfor %}")
>>> t.render()
u'My favorite numbers: 1 2 3 4 5 6 7 8 9 '

Primer on Python Decorators

2014-02-05

Decorators provide a simple syntax for calling higher-order functions. By definition, a decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it. Sounds confusing - but it's really not, especially after we go over a number of examples.

In this introductory tutorial, we'll look at what decorators are and how to create and use them.

You can find all the examples from this article here.

Before you can understand decorators, you must first understand:

  1. How functions work. Essentially, functions return a value based on the given arguments.

    def foo(bar):
      return bar + 1
    
    print foo(2) == 3
    
  2. In Python, functions are first-class objects. This means that functions can be passed around, and used as arguments, just like any other value (e.g, string, int, float).

    def foo(bar):
      return bar+1
    
    print foo
    print foo(2)
    print type(foo)
    
    def call_foo_with_arg(foo, arg):
      return foo(arg)
    
    print call_foo_with_arg(foo, 3)
    
  3. Because of the first-class nature of functions in Python, you can define functions inside other functions. Such functions are called nested functions.

    def parent():
      print "Printing from the parent() function."
    
      def first_child():
          return "Printing from the first_child() function."
    
      def second_child():
          return "Printing from the second_child() function."
    
      print first_child()
      print second_child()
    

    What happens when you call the parent() function? Think about this for a minute. You should get ...

    Printing from the parent() function.
    Printing from the first_child() function.
    Printing from the second_child() function
    

    Try calling the first_child(). You should get an error:

    Traceback (most recent call last):
    File "decorator3.py", line 15, in <module>
    first_child()
    NameError: name 'first_child' is not defined
    

    What have we learned?

    Whenever you call parent(), the sibling functions, first_child() and second_child() are also called AND because of scope, both of the sibling functions are not available (e.g., cannot be called) outside of the parent function.

  4. Python also allows you to return functions from other functions. Let's alter the previous function for this example.

    def parent(num):
    
      def first_child():
          return "Printing from the first_child() function."
    
      def second_child():
          return "Printing from the second_child() function."
    
      try:
          assert num == 10
          return first_child
      except AssertionError:
          return second_child
    
    foo = parent(10)
    bar = parent(11)
    
    print foo
    print bar
    
    print foo()
    print bar()
    

    The output of the first two print statements is:

    <function first_child at 0x1004a8c08>
    <function second_child at 0x1004a8cf8>
    

    This simply means that foo points to the first_child() function, while bar points to the second_child() function.

    The output of the second two functions confirms this:

    Printing from the first_child() function.
    Printing from the second_child() function.
    

    Finally, did you notice that in example three, we executed the sibling functions within the parent functions - e.g, second_child(). Meanwhile in this last example, we did not add parenthesis to the sibling functions - first_child - when called so that way we can use them in the future. Make sense?

Python Web Applications With Flask - Part III

2014-02-02

Please note: This is a collaboration piece between Michael Herman, from Real Python, and Sean Vieira, a Python developer from De Deo Designs.


Articles in this series:

  1. Part I: Application setup
  2. Part II: Setup user accounts, Templates, Static files
  3. Part III: Testing (unit and integration), Debugging, and Error handling <-- *CURRENT ARTICLE*

Welcome back to the Flask-Tracking development series! For those of you who are just joining us, we are implementing a web analytics application that conforms to this napkin specification. For all those of you following along at home, you may check out today's code with-

$ git checkout v0.3

-or you may download it from the releases page on Github. Those of you who are just joining us may wish to read a note on the repository structure as well.

In the previous segment we added user accounts to our application. This week we'll work on implementing a testing framework, talk a bit about why testing is important and then write some tests for our application. After, we'll talk a bit about debugging errors in our application and logging.

Why Testing

Before we actually write any of our tests lets talk about why testing is important. If you remember the Zen of Python from Part 1, you may have noticed that "Simple is better than complex" is right above "Complex is better than complicated". Simple is the ideal, complex is often a reality. Web applications, in particular, have many moving parts, and can very quickly move from simple to complex.