Photo by Domenico Loia on Unsplash
How to Build Python Flask RestAPI with Postgres and Dockerize It on Google Kubernetes using HELM - Part 1
Introduction
RestAPI is very popular. I recently learned some Python tech and how to build RestAPI using Flask Python, here I will show you the details.
And I will use the PostgreSQL database as the data source for RestAPI, and my last article described how to Install PostgreSQL Docker on Oracle Cloud.
Also, I like Docker very much, here I will install RestAPI into docker and deploy it to Google Kubernetes using HELM.
I really enjoyed the hands-on process :)
Build Python Flask RestAPI with Postgres
Database
Create sequence, table and inserting data in the PostgreSQL database
CREATE SEQUENCE IF NOT EXISTS public.tasks_seq
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;
CREATE TABLE IF NOT EXISTS public.tasks
(
id integer NOT NULL DEFAULT nextval('tasks_seq'::regclass),
name character varying(20) COLLATE pg_catalog."default",
description character varying(200) COLLATE pg_catalog."default",
CONSTRAINT tasks_pkey PRIMARY KEY (id)
);
insert into tasks(name,description) values('task1','this is task 1');
insert into tasks(name,description) values('task2','this is task 2');
insert into tasks(name,description) values('task3','this is task 3');
select * from tasks;
Using Example Project
Here is an example project on how to develop RESTful API with Flask and Python
Clone the project to your local
git clone https://github.com/bbachi/python-flask-restapi.git
Under the project, modify the requirements.txt under the project like this:
flask
psycopg2-binary
Flask-SQLAlchemy
python-dotenv
Install the packages in the requirements.txt
python3 -m pip install -r requirements.txt
Run Flask and check if it works
flask run
The VS Code terminal shows:
Open the browser and check if it works
http://127.0.0.1:5000/api/tasks
Coding
Keep the project files like this:
Modify the app.py
My codes implements receiving HTTP requests for RESTful Services and performing CRUD operations on the Postgres database
import os
import json
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')
# XXX.XXX.XXX.XXX is your PostgreSQL database IP
app.config['SQLALCHEMY_DATABASE_URI']='postgresql://postgres:postgres@XXX.XXX.XXX.XXX:5432/demo'
db = SQLAlchemy(app)
class Task(db.Model):
__tablename__ = 'tasks'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String())
description = db.Column(db.String())
def __init__(self, name, description):
self.name = name
self.description = description
def __repr__(self):
return '<id {}>'.format(self.id)
def serialize(self):
return {
'id': self.id,
'name': self.name,
'description': self.description
}
@app.route('/')
def home():
return "RestAPI Demo!"
@app.route('/api/tasks')
def tasks():
try:
tasks=Task.query.all()
return json.dumps([e.serialize() for e in tasks])
except Exception as e:
return(str(e))
@app.route('/api/task', methods=['POST'])
def create_task():
try:
body = request.get_json()
task = Task(body['name'], body['description'])
db.session.add(task)
db.session.commit()
return "Task added. task id={}".format(task.id)
except Exception as e:
return(str(e))
@app.route('/api/task/<int:id>', methods=['PUT'])
def update_task(id):
try:
body = request.get_json()
db.session.query(Task).filter_by(id=id).update(
dict(name=body['name'], description=body['description'])
)
db.session.commit()
return "Task "+str(id)+" updated"
except Exception as e:
return(str(e))
@app.route('/api/task/<int:id>', methods=['DELETE'])
def delete_task(id):
try:
#Task.query.filter_by(id=id).delete()
db.session.query(Task).filter_by(id=id).delete()
db.session.commit()
return "Task "+str(id)+" deleted"
except Exception as e:
return(str(e))
Run Flask again
flask run
Open the browser and check if it works
http://127.0.0.1:5000/api/tasks
It works and prove that the Python program has successfully fetched the data from the Postgres database.
Dockerize the RestAPI
In order to put the database connection information in the system environment variable and comment it out from the program, modify the app.py section like this
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')
# XXX.XXX.XXX.XXX is your PostgreSQL database IP
# app.config['SQLALCHEMY_DATABASE_URI']='postgresql://postgres:postgres@XXX.XXX.XXX.XXX:5432/demo'
And modify the Dockfile like this
FROM python:3.11
WORKDIR /opt/app
COPY . .
# XXX.XXX.XXX.XXX is your PostgreSQL database IP
ENV DATABASE_URL="postgresql://postgres:postgres@XXX.XXX.XXX.XXX:5432/demo"
RUN pip install --no-cache-dir -r requirements-prod.txt
EXPOSE 8080
CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0", "--port=8080"]
Download and install Docker
Docker build
docker build -t pythonrestapi .
Show docker images
docker images
Run docker
docker run -d -p 8080:8080 --name pythonrestapi pythonrestapi
docker ps -l
Open the browser and it also works
http://127.0.0.1:8080/api/tasks
Great!
At this point, I have successfully built a Rest API docker image and it runs looking good.
Next, I will try to deploy this image to Google Cloud.
Here the Part 2 - How to Build Python Flask RestAPI with Postgres and Dockerize It on Google Kubernetes using HELM - Part 2