Creating a RESTful API with Flask Framework is flexible and customizable with so many add-ons. Get a simple API up and running with only 5 lines of code.
Flask is one of the most popular web frameworks used in Python development. It is commonly used because of its simplicity and easy to learn structure. It’s easy to learn and adapt because there is almost no prior code you need to use in order to get a simple app up and running. It’s also very flexible and customizable with so many add-ons and external libraries. You don’t have to fill your code with unnecessary libraries or code snippets if you’re not ever going to use them! You can have a simple “hello world” web page with almost only 5 lines of code and that’s a beautiful thing in today’s complicated development world. For me, Flask is by far the easiest framework that I ever had to learn. I love writing with Flask and I recommend it to everyone who is already using Python.
As I mentioned, Flask has many add-ons and libraries that you can use and Flask-RESTful is only one of them. It is an extension that enables you to easily and quickly write and build REST APIs. It’s a simple but powerful extension that you can design more than simple RESTful applications.
In this article I will show you how you can get started with Flask-RESTful. As you may know many tutorial guides use to-do list apps to show you the simple tricks of a development tool. But I chose a different example to spice things up a little bit. In this example I will create a REST API for a movie grading/commenting app, which I found a very cool name: Cinemapi!
How does the flask framework work?
Before we start, I suggest you use a virtual environment to keep things clean. Let’s create our virtual environment:
1 |
python3 -m venv virtualenv |
Now we need to start the virtual environment:
1 |
source virtualenv/bin/activate |
Now that we are all set, let’s begin.
First of all, you need to install flask-restful on your environment:
1 |
pip install flask-restful |
A Minimal REST API Example
Before we move on to our Cinemapi app, I want to first show a minimal REST API app. Let’s call it hello.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from flask import Flask from flask_restful import Resource, Api app = Flask(__name__) api = Api(app) class HelloWorld(Resource): def get(self): return {'hello': 'world'} api.add_resource(HelloWorld, '/') if __name__ == '__main__': app.run(debug=True) |
Let’s look at it line by line:
- On the first two lines, we import necessary classes.
- Then on the third and fourth line we create our REST API app.
- The next part is to create our resource class. Here we create our HelloWorld class.
As you can see we only created a get method for this class. And it only returns our object, which you will see below.
On the 8th line we add the resource we created to the API. We tell the API to direct our HelloWorld class to / endpoint. We will see more details about it on our cinemapi app.
This app only returns the object we created in the HelloWorld class. To run the app you need to run below command:
1 |
python hello.py |
The app runs on port 5000 so you can test it with curl like this:
A Simple Movie Example
Now let’s move to a little more complicated example. Let’s begin small. Here is a simple code that you can both get and put movies to your app.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from flask import Flask, request from flask_restful import Resource, Api app = Flask(__name__) api = Api(app) MOVIES = {} class Movie(Resource): def get(self, movie_id): return {movie_id: movies[movie_id]} def put(self, movie_id): movies[movie_id] = request.form['data'] return {movie_id: movies[movie_id]} api.add_resource(Movie, '/') if __name__ == '__main__': app.run(debug=True) |
Let’s analyze the code. This time we have a Movie class that references our MOVIES object. You can see that it’s empty right now so let’s put some movies in it. But first, we need to run our app:
1 |
python cinemapi.py |
Here we will put a movie in this list using a curl command:
1 |
curl http://localhost:5000/movie1 -d "data=Superman vs Batman" -X PUT |
As you can see in the code, when we put a movie in to the object, it “requests” the “data” from the user. And we provide it by using “data”.
Now we have movie item in our object and we can get it by using the same endpoint:
1 |
curl http://localhost:5000/movie1 -X GET |
We can put and get as many movies as we like in this example using this endpoint.
Full example with Cinemapi
If this is too simple for you, let me introduce you to my cool movie app Cinemapi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
from flask import Flask from flask_restful import reqparse, abort, Api, Resource app = Flask(__name__) api = Api(app) MOVIES = { 'movie1': {'movie': 'superman vs batman', 'rating': '9/10', 'comment': 'meh'}} def check_if_not_exists(movie_id): if movie_id not in MOVIES: abort(404, message="{} doesn't exist".format(movie_id)) parser = reqparse.RequestParser() parser.add_argument('movie') parser.add_argument('rating') parser.add_argument('comment') class Movie(Resource): def get(self, movie_id): check_if_not_exists(movie_id) return MOVIES[movie_id] def delete(self, movie_id): check_if_not_exists(movie_id) del MOVIES[movie_id] return '', 204 def put(self, movie_id): args = parser.parse_args() movie = {'movie': args['movie']} rating = {'rating': args['rating']} comment ={'comment': args['comment']} MOVIES[movie_id] = [movie, rating, comment] return movie, 201 class AllMovies(Resource): def get(self): return MOVIES def post(self): args = parser.parse_args() movie_id = int(max(MOVIES.keys()).lstrip('movie')) + 1 movie_id = 'movie%i' % movie_id MOVIES[movie_id] = {'movie': args['movie'], 'rating': args['rating'], 'comment': args['comment']} return MOVIES[movie_id], 201 api.add_resource(AllMovies, '/movies') api.add_resource(Movie, '/movies/') if __name__ == '__main__': app.run(debug=True) |
I think the code here speaks for itself. It is so simple that when you read it, you understand the most part and what it does. But let’s review piece by piece.
- We have a MOVIES object that already has one item in it.
- In the next part, we have a control that checks if the movie exists in the object that we will use later.
- Since we have three different items we will request from the user, parser organizes and distributes these items to their places.
- We have two classes here; one is for showing, deleting and updating a single movie and the other one is for showing all movies and letting you post to add a new one.
- In the first class, we first check if the user wants to get or delete a movie because if the movie doesn’t exist then the app will give an exception. If the movie really exists, then we return or delete the movies as requested by the user.
- In the second class we have get; which returns all the movies. And post; which adds the new movie by incrementing the id by 1 automatically.
So it’s time to test our brand new API. Let’s run it with, yes you know it:
1 |
python cinemapi.py |
First get all the movies in the object
1 |
curl http://localhost:5000/ -X GET |
As you can see in the first command, now we don’t have a / endpoint and that’s why the app returns 404 not found. In the second command, you can see all the movies in the object, which is just one for now. So let’s add another:
1 |
curl http://localhost:5000/movies -d "movie=Joker" -d "rating=10/10" -d "Very good movie" -X POST -v |
As you can see, a new movie is added to the object. But let’s see it in the movies list:
So now let’s assume you have a very big movie list with hundreds of movies and you only want to get a specific movie, then you will use movies/<movie_id> endpoint, like this:
That’s it! Isn’t it simple? As I mentioned in the beginning of the article, Flask is very customizable with tons of add-ons and libraries. So I want to emphasize that you shouldn’t let the simplicity mislead you because you can extend your development to complex levels with Flask. And Flask-RESTful is a very good starting point to do so.
APILayer is a marketplace, where high quality and curated APIs taking place. If you wish to work with us promoting your APIs, check our page for our unbeatable revenue sharing models.