Lab: getting started with Flask
Nothing to hand in
Flask: a web framework
Once you have designed an HTTP-based API, you'll want to write code to implement it, and deploy that code on a publicly accessible server.
One of the biggest hassles of API implementation is the parsing of the URL. For example, if you're writing a server that expects to receive requests like "http://wherever.com/author/27", your server will need code to recognize that the caller is requesting the "author" resource with ID number 27. Once your server extracts this information, it will probably want to call a function get_author (or some similar name) with the parameter author_id=27. The get_author function will then query your database, assemble a JSON response, and send that response back to the client that made the original request.
In addition to URL parsing, there are other routine and tedious tasks involved in implementing web services. As a result, many people have developed web frameworks—tools to simplify some of these routine tasks. We will be using one such framework called Flask, one of the most popular Python web frameworks.
You'll install Flask on your working computer and run your API from there. It won't be available to the wider world in that configuration, but it will be convenient for development and testing.
Installing Flask
There's all sorts of discussion of details on the official Flask installation page. That said, I don't recommend following all those instructions. The Flask people really love using virtual environments, for which there are many good arguments. But in my experience, both for myself and most of my CS257 students, virtual environments add more complexity to my setup without providing discernable benefits.
So, here's what I recommend you do.
Trying out a simple Flask application
- "git pull" your clone of my cs257 git repository
- In the clone of my repository, run my Flask sample:
cd flask python3 flask_sample.py localhost 5000
The program will print out a few messages and then just hang. You can kill it at any time by bringing its terminal window forward and hitting Ctrl-C. But right now, don't do that—just let it run.
- Go to a browser, and navigate to http://localhost:5000/help. This should print out a help document for the API that flask_sample.py is implementing. (Sometimes browsers don't like to let you use "localhost", so if that link doesn't work, try http://127.0.0.1:5000/help.)
- Look back at the terminal window. Do you see any messages that reflect your browser activity? If so, what do you make of them? Reload the browser page you just looked at. Does anything change on the terminal?
- Play around with the API, and keep an eye on the terminal as you do so. When you're done, Ctrl-C in the terminal to shut down the API server.
- Open up flask_sample.py in a text editor. Note the hard-coded "database" at the beginning, and then read the code and comments, with particular attention on the "@app.route" lines. Compare what you see there to the behavior described in the /help output, and to whatever you observed when playing with the API.
- Make a copy of flask_sample.py to mess around with (say, flask_sample_copy.py), and
try putting in some print('blah blah', file=sys.stderr)debugging messages in various places. Relaunch your modified app (python3 flask_sample_copy.py localhost 5000) and try hitting it with your browser a few times. Do the error messages you inserted get printed when you expected them to? Keep playing like this until you're pretty sure you know which functions get called and when.
- Try to add a new "route" that enables the client to request a list of actors who were alive during a specified year. For example, set it up the the URL "http://localhost:5000/actors-alive-in/1980" will induce the API to return a JSON list of actors alive in 1980.
- Read through the code more carefully, and take notes about things in the code that you don't understand. Bring your questions to class or ask them on Slack.
- All done!
So where are we?
There's nothing more to do for this lab, but here's a little discussion of what comes next.
At this point, you can launch a simple Flask web app on your working computer and access it via a browser, but only from a browser that is also running on your computer. I'll eventually talk in class about what is involved in deploying Flask apps on the public internet, but for now, you're set to start developing your own API.
To do that, you'll use the functions in flask_sample.py to give you an idea of how to build additional "@app.route" endpoints corresponding to the endpoints of the API you're trying to implement. You might also find the official Flask documentation helpful.
Here's one approach, pretending we're working on a books/authors API:
- Copy flask_sample.py to api.py, delete the fake database, and comment out the various functions (keeping them around temporarily for reference).
- Pick one endpoint from your API design (e.g. "/author/<author_id>").
- Create a "stub" function in api.py that matches the endpoint:
@app.route('/author/<author_id>') def get_author(author_id): author = {'id': author_id, 'first_name': 'Alice', 'last_name': 'Stubauthor', 'birth_year': 1900, 'death_year': 1980} return json.dumps(author)That is, just create a fake author and return it.
- Fire up api.py and test the new endpoint (e.g. try different values of author_id and see if you see the difference in the JSON shown in your browser).
- Maybe commit your changes, just to save the endpoint stub.
- Do the hard work: implement and test your API endpoint.
- Repeat
Alternatively, you could create all the endpoint stubs at once, test that they are getting called at the appropriate times, and then start implementing them one at a time.