Python Flask stands out as a favored platform to craft web applications and APIs using Python. Its appeal lies in offering developers a swift and uncomplicated approach to fabricating RESTful APIs that interlink with various software applications. Flask holds a featherweight stature and demands minimal configuration, rendering it an optimal selection for constructing modest to moderately-sized APIs. Hence, Flask emerges as the prime option for programmers seeking to erect resilient and expandable APIs within the Python ecosystem. This instance will elucidate the process of generating a straightforward REST API via a Flask tutorial.
PrerequisitesPermalink
Before commencing, it’s essential to confirm the fulfillment of a few prerequisites. To seamlessly engage and execute this tutorial, certain requirements must be met:
- Get Python installed
- Set up an IDE for code editing
- install Postman for endpoint testing purposes.
Creating the Base Project
To establish the foundational structure, begin by crafting a directory named ‘python-flask-api’ within your designated location.
Once the directory is in place, access the terminal from the root of this folder to execute commands for constructing and launching our Python project. After positioning your terminal in the project’s root directory, execute the subsequent commands to initialize the Flask-based Python Rest API project and oversee the essential dependencies.ermalink
Start by leveraging pip
to install Flask directly within the project directory. Execute the following command:
pip install Flask
Writing the CodePermalink
In our first line of code in theapp.py
file, we will import the modules forjson
,Flask
,jsonify
, andrequest
.
import json
from flask import Flask, jsonify, request
Next, we will create a new Flask application by adding the following code just below our import statements.
app = Flask(__name__)
Next, to give our API a little bit of data to work with, we will define an array of employee objects with an ID and name.
employees = [
{ 'id': 1, 'name': 'Ashley' },
{ 'id': 2, 'name': 'Kate' },
{ 'id': 3, 'name': 'Joe' }
]
nextEmployeeId = 4
def employee_is_valid(employee):
if employee['name']:
return True
return False
def get_employee(id):
for obj in employees:
if obj.get('id') == id:
return obj
return None // If object with the given ID is not found
To define our API endpoint, we will now add code to define a route for GET requests to the ‘/employees’ endpoint. This will return all employees (from our employee’s array defined above) in JSON format.
@app.route('/employees', methods=['GET'])
def get_employees():
return jsonify(employees)
On top of our GET method, we will also define a route for POST, PUT, and DELETE methods as well. These functions can be used to create a new employee and update or delete the employee based on their given ID.
@app.route('/employees', methods=['POST'])
def create_employee():
global nextEmployeeId
employee = json.loads(request.data)
if not employee_is_valid(employee):
return jsonify({ 'error': 'Invalid employee properties.' }), 400
employee['id'] = nextEmployeeId
nextEmployeeId += 1
employees.append(employee)
return '', 201, { 'location': f'/employees/{employee["id"]}' }
@app.route('/employees/<int:id>', methods=['PUT'])
def update_employee(id: int):
employee = get_employee(id)
if employee is None:
return jsonify({ 'error': 'Employee does not exist.' }), 404
updated_employee = json.loads(request.data)
if not employee_is_valid(updated_employee):
return jsonify({ 'error': 'Invalid employee properties.' }), 400
employee.update(updated_employee)
return jsonify(employee)
@app.route('/employees/<int:id>', methods=['DELETE'])
def delete_employee(id: int):
global employees
employee = get_employee(id)
if employee is None:
return jsonify({ 'error': 'Employee does not exist.' }), 404
employees = [e for e in employees if e['id'] != id]
return jsonify(employee), 200
Once our code is complete, it should look like this:
import json
from flask import Flask, jsonify, request
app = Flask(__name__)
employees = [
{ 'id': 1, 'name': 'Ashley' },
{ 'id': 2, 'name': 'Kate' },
{ 'id': 3, 'name': 'Joe' }
]
nextEmployeeId = 4
def employee_is_valid(employee):
if employee['name']:
return True return False
def get_employee(id):
for obj in employees:
if obj.get('id') == id:
return obj
return None # If object with the given ID is not found
@app.route('/employees', methods=['GET'])
def get_employees():
return jsonify(employees)
@app.route('/employees/<int:id>', methods=['GET'])
def get_employee_by_id(id: int):
employee = get_employee(id)
if employee is None:
return jsonify({ 'error': 'Employee does not exist'}), 404
return jsonify(employee)
def get_employee(id):
return next((e for e in employees if e['id'] == id), None)
def employee_is_valid(employee):
for key in employee.keys():
if key != 'name':
return False
return True
@app.route('/employees', methods=['POST'])
def create_employee():
global nextEmployeeId
employee = json.loads(request.data)
if not employee_is_valid(employee):
return jsonify({ 'error': 'Invalid employee properties.' }), 400
employee['id'] = nextEmployeeId
nextEmployeeId += 1
employees.append(employee)
return '', 201, { 'location': f'/employees/{employee["id"]}' }
@app.route('/employees/<int:id>', methods=['PUT'])
def update_employee(id: int):
employee = get_employee(id)
if employee is None:
return jsonify({ 'error': 'Employee does not exist.' }), 404
updated_employee = json.loads(request.data)
if not employee_is_valid(updated_employee):
return jsonify({ 'error': 'Invalid employee properties.' }), 400
employee.update(updated_employee)
return jsonify(employee)
@app.route('/employees/<int:id>', methods=['DELETE'])
def delete_employee(id: int):
global employees
employee = get_employee(id)
if employee is None:
return jsonify({ 'error': 'Employee does not exist.' }), 404
employees = [e for e in employees if e['id'] != id]
return jsonify(employee), 200
Lastly, we will add a line of code at the bottom of our code to run our Flask app. As you can see, we call therun
method and get the Flask app running on port 5000.
if __name__ == '__main__':
app.run(port=5000)
Running and Testing The CodePermalink
With our code written and saved, we can start the app up. To run the app, in the terminal, we will execute the followingpip
command.
python app.py
Now, our API is up and running. You can send a test HTTP request through Postman. By sending a request tolocalhost:5000/employees
or 127.0.0.1:5000/employees
. After the request is sent. you should see a200 OK
status code in the response along with an array of employees returned.
For this GET test, no request body is needed for the incoming request.
For the POST request to create a new employee let’s create a request from Postman. To achieve this we’ll need to create a request body in Postman like this:
Now if we call the GET again we’ll get the list of employees with the newly created employee “Manuel”:
For the PUT request to modify an employee, let’s create a request from Postman. To achieve this we’ll need to create a request body like this:
Since we’re handling some scenario in case the user input wrong information, if we try to update a non-existing employee, the employee will handle the request by returning a message with the following message “Employee does not exist.“.
For the DELETE request to remove an existing employee, let’s create a request from Postman. To achieve this we’ll need to create a request body like this:
We applied the same strategy as we did in the update endpoint to handle exceptions. If the user tries to delete a non-existing employee, the API will return an error message: “Employee does not exist.“.