Last mod: 2025.01.26
Raspberry Pi - REST API based on Flask (deprecated library)
Introduction
In my opinion, Python is the best language for building REST APIs for small portable systems like the Raspberry Pi. This is determined by several elements:
- Most of the IoT devices communicates have written libraries in Python
- Python allows you to create lightweight applications
- Python is a high-level language where we do not need to focus on implementation details
- We can use the Flask library to easily create web applications with a REST API
Software
Any OS for the Rapsberry Pi should have Python installed by default. Let's verify this:
python -V
If we have Python, we can proceed to install the Flask framework:
sudo apt -y upgrade
sudo apt install -y python3-flask
"Hello World" example
Create first app "Hello World". Write file app_restapi_helloworld.py with body:
from flask import Flask
# Create a Flask app
app = Flask(__name__)
# Route for the root URL '/'
@app.route("/")
def hello_world():
return "Hello World"
# Run the application
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)
Complete file: app_restapi_helloworld.py
And run:
python app_restapi_helloworld.py
If the application has started, type http://RASPBERRY_PI_IP:5000/ into the browser.
We should see a screen:
GET method with JSON response
Let's take a more important data, system parameters: CPU load, RAM consumption, disk usage. We need to install the package for reading system data:
sudo apt install python3-psutil
Prepare a Python function to read system data:
def get_system_info():
# CPU usage
cpu_usage = psutil.cpu_percent(interval=1)
# Memory usage
memory_info = psutil.virtual_memory()
ram_total = memory_info.total / (1024 * 1024) # Convert bytes to MB
ram_used = memory_info.used / (1024 * 1024) # Convert bytes to MB
ram_percent = memory_info.percent
# Disk usage
disk_info = psutil.disk_usage('/')
disk_total = disk_info.total / (1024 * 1024 * 1024) # Convert bytes to GB
disk_used = disk_info.used / (1024 * 1024 * 1024) # Convert bytes to GB
disk_percent = disk_info.percent
# Create a dictionary for JSON
system_info = {
"cpu": {
"usage_percent": cpu_usage
},
"memory": {
"total_mb": round(ram_total, 2),
"used_mb": round(ram_used, 2),
"usage_percent": ram_percent
},
"disk": {
"total_gb": round(disk_total, 2),
"used_gb": round(disk_used, 2),
"usage_percent": disk_percent
}
}
return system_info
Complete file: app_restapi_psutil.py
Add routing to app:
@app.route("/system_info")
def system_info():
return get_system_info()
Open in browser http://RASPBERRY_PI_IP:5000/system_info:
POST request with JSON body
We should use the POST method to send commands change server status. The parameters can be sent in several ways, the most flexible, lightweight and most commonly used is the JSON format.
Add import request:
from flask import Flask, request
and post method:
@app.route("/motors", methods=['POST'])
def post():
if not request.is_json:
return jsonify({"error": "Invalid JSON!"}), 400
data = request.json
left_motor_value = float(data.get('left'))
right_motor_value = float(data.get('right'))
print("Left:", round(left_motor_value, 2))
print("Right: ", round(right_motor_value, 2))
# TODO Add motor control implementation
return {"status" : "ok"}, 200
Complete file: app_restapi_psutil_and_post.py
Restart the application. The POST method cannot be called simply from the browser, let's use the curl command line tool from bash:
curl -X POST http://RASPBERRY_PI_IP:5000/motors \
-H "Content-Type: application/json" \
-d '{"left": 35.0, "right" : 90.5}'
From the client side we should see:
From the server side:
Links
https://www.python.org/
https://flask.palletsprojects.com/
https://restfulapi.net/
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
https://pypi.org/project/psutil/