Building a Simple Restful API with Python and Flask Part 1

1. Description

        I'm going to split this series into 3 or 4 articles. By the end of this series, you'll see how easy it is to build RESTful APIs with Flask. In this article, we will set up the environment and create an endpoint that will display "Hello World".

        I assume you have python 2.7 and pip installed on your computer. I have tested the code presented in this article on python 2.7, although it may be fine on python 3.4 or later.

Two, install flask

a. Installing flask

        Flask is a microframework for python. The "micro" in microframework means that Flask aims to keep the core simple but extensible ( http://flask.pocoo.org/docs/0.12/foreword/#what-does-micro-mean ). You can install flask with the following command:

$ pip install Flask

b. Prepare your IDE

        You can actually build python applications with any kind of text editor, but it's much easier if you use an IDE. Personally, I prefer to use Pycharm from jetbrains ( PyCharm: the Python IDE for Professional Developers by JetBrains ).

c. Create "hello world" in flask

        First, you need to create the project folder, for this tutorial, I named it "flask_tutorial". If you are using pycharm, you can create a project folder by selecting File and New Project from the menu.

 

After that you can set the project location and interpreter. Anyway, your computer can have some python interpreter.

After setting up your project, right click on your project folder on pycharm and select New -> Python File and name it "app.py".

Write the following code on app.py.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"


if __name__ == '__main__':
    app.run(debug=True)

        Run it from terminal. You can use the command line or from pycharm click on the terminal tab located in the bottom left corner and write the code below.

$ python app.py

 

Open a browser and visit localhost:5000. Voila, now you have your first flask app :)

        Ok, now let's look at the code.

from flask import Flask

        This line requires the application to import the flask module from the flask package. Flask for creating web application instances.

app = Flask(__name__)

        This line creates an instance of the web application. __name__ is a special variable in python that will be equal to "__main__" if the module (python file) is executed as the main program.


@app.route("/")

        This line defines the route. For example, if we set the route to "/" like above, if we visit localhost:5000/, the code will be executed. You can set the route to "/hello", and if we visit localhost:5000/hello, our "hello world" will be displayed.

def hello():
    return "Hello World!"

        This line defines the function that will be executed if we access the route.

if __name__ == '__main__':
    app.run(debug=True)

        This line says that your flask app will run if we run it from app.py. Also note that we set the parameter to . This will print possible Python errors on the web page, helping us track down errors.debug true

        Ok, that's all for Part 1, next we'll try to do CRUD operations on SQLLite using flask.

3. Use flask and SQLite to build a simple restful api

        In this article, I will show you how to use flask and SQLite to build simple restful apis with functions to create, read, update and delete data from a database.

3.1  安装 flask-sqlalchemy and flask-marshmallow

        SQLAlchemy is a python SQL toolkit and ORM that provides developers with the full power and flexibility of SQL. where flask-sqlalchemy is a flask extension that adds support for SQLAlchemy to flask applications ( Flask-SQLAlchemy — Flask-SQLAlchemy Documentation (2.x) ).      

        On the other hand, flask-marshmallow is a Flask extension for integrating Flask with Marshmallow (an object serialization/deserialization library). In this article, we use flask-marshmallow to render the json response.

You can easily install flask-sqlalchemy and flask-marshmallow using pip, using the following commands:

$ pip install flask_sqlalchemy
$ pip install flask_marshmallow
$ pip install marshmallow-sqlalchemy

3.2. Prepare code

        Create new flask_tutorial python file on folder named crud.py. Write down the following code in crud.py.

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
import os

app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'crud.sqlite')
db = SQLAlchemy(app)
ma = Marshmallow(app)


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, username, email):
        self.username = username
        self.email = email


class UserSchema(ma.Schema):
    class Meta:
        # Fields to expose
        fields = ('username', 'email')


user_schema = UserSchema()
users_schema = UserSchema(many=True)


# endpoint to create new user
@app.route("/user", methods=["POST"])
def add_user():
    username = request.json['username']
    email = request.json['email']
    
    new_user = User(username, email)

    db.session.add(new_user)
    db.session.commit()

    return jsonify(new_user)


# endpoint to show all users
@app.route("/user", methods=["GET"])
def get_user():
    all_users = User.query.all()
    result = users_schema.dump(all_users)
    return jsonify(result.data)


# endpoint to get user detail by id
@app.route("/user/<id>", methods=["GET"])
def user_detail(id):
    user = User.query.get(id)
    return user_schema.jsonify(user)


# endpoint to update user
@app.route("/user/<id>", methods=["PUT"])
def user_update(id):
    user = User.query.get(id)
    username = request.json['username']
    email = request.json['email']

    user.email = email
    user.username = username

    db.session.commit()
    return user_schema.jsonify(user)


# endpoint to delete user
@app.route("/user/<id>", methods=["DELETE"])
def user_delete(id):
    user = User.query.get(id)
    db.session.delete(user)
    db.session.commit()

    return user_schema.jsonify(user)


if __name__ == '__main__':
    app.run(debug=True)

        For the shortcode, the above code will have 5 endpoints with functions to create new record, get all records from database, get record details by id, update selected record and delete selected record. Also in this code, we define the model for the database.

        Let's look at the code part by part

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
import os

        In this part, we import all the modules required by the application. We import Flask to create an instance of the web application, requests to get the request data, jsonify to convert the JSON output to an object with application /json  mimetype, flask_sqlalchemy to SQAlchemy to access the database, and flask_marshmallow to Marshmallow to serialize objects.Response

app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'crud.sqlite')

        This part creates an instance of our web application and sets the path to our SQLite uri.

db = SQLAlchemy(app)
ma = Marshmallow(app)

        In this part, we bind SQLAlchemy and Marshmallow into our Flask application.

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, username, email):
        self.username = username
        self.email = email

        After importing SQLAlchemy and binding it to our Flask application, we can declare our models. Here we declare a model called User and define its fields with its properties.

class UserSchema(ma.Schema):
    class Meta:
        # Fields to expose
        fields = ('username', 'email')


user_schema = UserSchema()
users_schema = UserSchema(many=True)

        This section defines the response structure for the endpoint. We want all endpoints to have JSON responses. Here we define that our JSON response will have two keys (username and email). Additionally, we define user_schema as an instance of UserSchema and user_schemas as a list of UserSchema instances.

# endpoint to create new user
@app.route("/user", methods=["POST"])
def add_user():
    username = request.json['username']
    email = request.json['email']
    
    new_user = User(username, email)

    db.session.add(new_user)
    db.session.commit()

    return jsonify(new_user)

        In this part, we define the endpoint to create a new user. First, we set the route to "/user" and the HTTP method to POST. After setting up the route and method, we define the function that will be executed when this endpoint is accessed. In this function, we first get the username and email from the request data. After that, we create a new user using the data in the request data. Finally, we add the new user to the database and display the new user in JSON in response.

# endpoint to show all users
@app.route("/user", methods=["GET"])
def get_user():
    all_users = User.query.all()
    result = users_schema.dump(all_users)
    return jsonify(result.data)

        In this part, we define the endpoint to get a list of all users and display the result as a JSON response.

# endpoint to get user detail by id
@app.route("/user/<id>", methods=["GET"])
def user_detail(id):
    user = User.query.get(id)
    return user_schema.jsonify(user)

        Like the previous part of this part, we defined endpoints to get user data, but instead of getting all users here, we just get data from one user by id. If you look closely at the routes, you can see that there are different patterns on the routes for this endpoint. The parent like " <id>" is a parameter, so you can change it with everything you want. This parameter should be placed on the function parameter ( def  user_detail(id) in this case  ), so that we can get this parameter value in the function.

# endpoint to update user
@app.route("/user/<id>", methods=["PUT"])
def user_update(id):
    user = User.query.get(id)
    username = request.json['username']
    email = request.json['email']

    user.email = email
    user.username = username

    db.session.commit()
    return user_schema.jsonify(user)

        In this part, we define endpoints to update users. First, we call the user associated with the given id on the parameter. We then update the username and email values ​​for this user with the values ​​from the request data.

# endpoint to delete user
@app.route("/user/<id>", methods=["DELETE"])
def user_delete(id):
    user = User.query.get(id)
    db.session.delete(user)
    db.session.commit()

    return user_schema.jsonify(user)

        Finally, we define the endpoint where the user is to be deleted. First, we call the user associated with the given id on the parameter. Then we delete it.

4. Generate SQLite database

        In the previous step, you have written code to handle CRUD operations for SQLite, but if you run this python file and try to access the endpoint (you can try to access localhost:5000/user), you will get an error similar to the following information

Operation Error: (sqlite3. Operation Error) No such table: users [SQL: u'SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email \nFROM user']

        The reason for this error message is that you are trying to get data from SQLite, but you don't have an SQLite database yet. So in this step we will generate the SQLite database before running the application. You can use the following steps to generate a SQLite database based on your model in crud.py.

  1. Enter the Python interactive shell

First, you need to enter the python interactive shell with the following command in the terminal:

$ python

2. Import database objects and generate SQLite database

Use the following code in python interactive shell

import database from crude
>>> db.create_all() >>>

crud.sqlite will be generated in your flask_tutorial folder.

5. Run the flask application

        Now, after generating the sqlite database, we can run our flask application. Run the following command from terminal to run the application.

$ python crud.py

        We're ready to try out our flask application. To try out the endpoints in our flask application, we can use an API development tool such as curl or postman. Personally, I like Postman ( Postman ) for api development. In this article, I will use postman to access the endpoint.

  1. create new user

2. Get all users

3. Get user by id

4. Update user

5. Delete user

6. Postscript

        That's all for this article. Next, I plan to write small tests using pytest.

Guess you like

Origin blog.csdn.net/gongdiwudu/article/details/132163596