Create a CRUD Restful Service API using Flask + MySQL

  1. SETTING UP ENVIRONMENT on Ubuntu20:
    (base) ubuntu@ubunu2004:~$ mkdir flaskdbexample
    (base) ubuntu@ubunu2004:~$ cd flaskdbexample
    (base) ubuntu@ubunu2004:~/flaskdbexample$ sudo apt install python3-virtualenv
    (base) ubuntu@ubunu2004:~/flaskdbexample$ virtualenv venv
    created virtual environment CPython3.8.2.final.0-64 in 805ms

(base) ubuntu@ubunu2004:~/flaskdbexample/venv/bin$ source ./activate
(venv) (base) ubuntu@ubunu2004:~$ cd flaskdbexample/
(venv) (base) ubuntu@ubunu2004:~/flaskdbexample$ pip install flask flask-sqlalchemy
(venv) (base) ubuntu@ubunu2004:~/flaskdbexample$ pip install pymysql
(venv) (base) ubuntu@ubunu2004:~/flaskdbexample$ pip install marshmallow_sqlalchemy

  1. Complete Code
    (venv) (base) ubuntu@ubunu2004:~/flaskdbexample$ vi app.py
from flask import Flask, request, jsonify, make_response
from flask_sqlalchemy import SQLAlchemy
from marshmallow_sqlalchemy import ModelSchema
from marshmallow import fields
app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://monty:password@192.168.0.43/EmployeeDB'
db = SQLAlchemy(app)

###Models####
class Product(db.Model):
    __tablename__ = "products"
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(20))
    productDescription = db.Column(db.String(100))
    productBrand = db.Column(db.String(20))
    price = db.Column(db.Integer)

    def create(self):
      db.session.add(self)
      db.session.commit()
      return self
    def __init__(self,title,productDescription,productBrand,price):
        self.title = title
        self.productDescription = productDescription
        self.productBrand = productBrand
        self.price = price
    def __repr__(self):
        return '' % self.id
db.create_all()
class ProductSchema(ModelSchema):
    class Meta(ModelSchema.Meta):
        model = Product
        sqla_session = db.session
    id = fields.Number(dump_only=True)
    title = fields.String(required=True)
    productDescription = fields.String(required=True)
    productBrand = fields.String(required=True)
    price = fields.Number(required=True)

@app.route('/products', methods = ['GET'])
def index():
    get_products = Product.query.all()
    product_schema = ProductSchema(many=True)
    products = product_schema.dump(get_products)
    return make_response(jsonify({"product": products}))
@app.route('/products/<id>', methods = ['GET'])
def get_product_by_id(id):
    get_product = Product.query.get(id)
    product_schema = ProductSchema()
    product = product_schema.dump(get_product)
    return make_response(jsonify({"product": product}))
@app.route('/products/<id>', methods = ['PUT'])
def update_product_by_id(id):
    data = request.get_json()
    get_product = Product.query.get(id)
    if data.get('title'):
        get_product.title = data['title']
    if data.get('productDescription'):
        get_product.productDescription = data['productDescription']
    if data.get('productBrand'):
        get_product.productBrand = data['productBrand']
    if data.get('price'):
        get_product.price= data['price']    
    db.session.add(get_product)
    db.session.commit()
    product_schema = ProductSchema(only=['id', 'title', 'productDescription','productBrand','price'])
    product = product_schema.dump(get_product)
    return make_response(jsonify({"product": product}))
@app.route('/products/<id>', methods = ['DELETE'])
def delete_product_by_id(id):
    get_product = Product.query.get(id)
    db.session.delete(get_product)
    db.session.commit()
    return make_response("",204)
@app.route('/products', methods = ['POST'])
def create_product():
    data = request.get_json()
    product_schema = ProductSchema()
    product = product_schema.load(data)
    result = product_schema.dump(product.create())
    return make_response(jsonify({"product": result}),200)
if __name__ == "__main__":
    app.run(debug=True)

3. testing the API
(venv) (base) ubuntu@ubunu2004:~/flaskdbexample$ flask run –host=0.0.0.0
A. POST data to http://ubunu2004:5000/products
{
“title” : “Python coding”,
“productDescription” : “ebook”,
“productBrand” : “SUN”,
“price” : “5000”
}

B. GET data

simple flask web app to INSERT record into MySQL

1. install flask and flask-mysqldb
pip install flask
pip install flask_mysqldb
2. mkdir flask_mysql and subfolder templates
we only need two files:
app.py and templates/index.html
3. make app works without DB:
index.html

<HTML>
<BODY bgcolor="cyan">
<form method="POST" action="">
    <center>
    <H1>Enter your details </H1> <br>
    First Name <input type = "text" name= "fname" /> <br>
    Last Name <input type = "text" name = "lname" /> <br>
    <input type = "submit">
    </center>
</form>
</BODY>
</HTML>

app.py

from flask import Flask, render_template
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template('index.html')
if __name__ == '__main__':
    app.run()

4. test app.py, you will get the web page as below:

5. then we can create table in MySQL:
CREATE TABLE MyUsers ( firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL);
update app.py:

from flask import Flask, render_template, request
from flask_mysqldb import MySQL
app = Flask(__name__)
app.config['MYSQL_HOST'] = '192.168.0.43'
app.config['MYSQL_USER'] = 'monty'
app.config['MYSQL_PASSWORD'] = 'somIUpass#98'
app.config['MYSQL_DB'] = 'EmployeeDB'
mysql = MySQL(app)
@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == "POST":
        details = request.form
        firstName = details['fname']
        lastName = details['lname']
        cur = mysql.connection.cursor()
        cur.execute("INSERT INTO MyUsers(firstName, lastName) VALUES (%s, %s)", (firstName, lastName))
        mysql.connection.commit()
        cur.close()
        return 'success'
    return render_template('index.html')
if __name__ == '__main__':
    app.run()

6. run it again, you can submit info into DB on http://127.0.0.1:5000/

python code debug

  1. python pdb debug
    we have sample code read_redis.py:
    import json
    import redis
    client = redis.Redis()
    data = client.lpop(‘info’)
    run it with command: python -i read_redis.py.
    once you got "exception occurred", start pdb debuggin as below:
>>> import pdb
>>> pdb.pm()
> c:\python\lib\site-packages\redis\connection.py(563)connect()
-> raise ConnectionError(self._error_message(e))
(Pdb) data
*** NameError: name 'data' is not defined
  1. VS CODE debug
    you can press F5 to start debugging python in VS CODE as below:

Bash String Manipulation

1. Identify String Length inside Bash Shell Script
${#string}
2. Extract a Substring from a Variable inside Bash Shell Script
${string:position:length}
3. Shortest Substring Match
Following syntax deletes the shortest match of $substring from front of $string
${string#substring}
Following syntax deletes the shortest match of $substring from back of $string
${string%substring}
Following sample shell script explains the above two shortest substring match concepts.
$ cat shortest.sh
filename="bash.string.txt"
echo ${filename#.}
echo ${filename%.
}
$ ./shortest.sh
After deletion of shortest match from front: string.txt
After deletion of shortest match from back: bash.string
4. Longest Substring Match
Following syntax deletes the longest match of $substring from front of $string
${string##substring}
Following syntax deletes the longest match of $substring from back of $string
${string%%substring}
Following sample shell script explains the above two longest substring match concepts.
$ cat longest.sh
filename="bash.string.txt"
echo "After deletion of longest match from front:" ${filename##.}
echo "After deletion of longest match from back:" ${filename%%.
}
$ ./longest.sh
After deletion of longest match from front: txt
After deletion of longest match from back: bash
5. Find and Replace String Values inside Bash Shell Script
Replace only first match
${string/pattern/replacement}
It matches the pattern in the variable $string, and replace only the first match of the pattern with the replacement.
$ cat firstmatch.sh
filename="bash.string.txt"
echo "After Replacement:" ${filename/str./operations.}
$ ./firstmatch.sh
After Replacement: bash.operations.txt
Replace all the matches
${string//pattern/replacement}
It replaces all the matches of pattern with replacement.
$ cat allmatch.sh
filename="Path of the bash is /bin/bash"
echo "After Replacement:" ${filename//bash/sh}
$ ./allmatch.sh
After Replacement: Path of the sh is /bin/sh
Replace beginning and end
${string/#pattern/replacement}
Following syntax replaces with the replacement string, only when the pattern matches beginning of the $string.
${string/%pattern/replacement}
Following syntax replaces with the replacement string, only when the pattern matches at the end of the given $string.
$ cat posmatch.sh
filename="/root/admin/monitoring/process.sh"
echo "Replaced at the beginning:" ${filename/#\/root/\/tmp}
echo "Replaced at the end": ${filename/%.
/.ksh}
$ ./posmatch.sh
Replaced at the beginning: /tmp/admin/monitoring/process.sh
Replaced at the end: /root/admin/monitoring/process.ksh
6. Check if Two Strings are Equal
VAR1="Linuxize"
VAR2="Linuxize"
if [ "$VAR1" = "$VAR2" ]; then
echo "Strings are equal."
else
echo "Strings are not equal."
fi
7. Check if a String Contains a Substring
VAR=’GNU/Linux is an operating system’
if [[ $VAR == "Linux" ]]; then
echo "It’s there."
fi
Copy
8. Check if a String is Empty
VAR=”
if [[ -z $VAR ]]; then
echo "String is empty."
fi

Bash scripting Tutorial

Writing Readable Bash Scripts

#!/bin/bash

set -u
set -e
set -o pipefail

function is-even {
    if [[ $(($1 % 2)) -gt 0 ]]
    then return 1
    else return 0
    fi
}

function epoch {
    date +"%s"
}

if is-even $(epoch)
then echo "Even epoch"
else echo "Odd epoch"
fi

===============================================
set -u will cause the script to fail if you’re trying to reference a variable that hasn’t been set. The default behavior will just evaluate the variable to the empty string.

set -e will cause the script to exit immediately if a command fails. The default behavior is to simply continue executing the remaining commands in the script.

set -o pipefail will cause a pipeline to fail if any of the commands in the pipeline failed. The default behavior is to only use the exit status of the last command.

Passing arguments to the bash script

#!/bin/bash
# use predefined variables to access passed arguments
#echo arguments to the shell
echo $1 $2 $3 ' -> echo $1 $2 $3'

# We can also store arguments from bash command line in special array
args=("$@")
#echo arguments to the shell
echo ${args[0]} ${args[1]} ${args[2]} ' -> args=("$@"); echo ${args[0]} ${args[1]} ${args[2]}'

#use $@ to print out all arguments at once
echo $@ ' -> echo $@'

# use $# variable to print out
# number of arguments passed to the bash script
echo Number of arguments passed: $# ' -> echo Number of arguments passed: $#' 

Reading User Input

#!/bin/bash
 
echo -e "Hi, please type the word: \c "
read  word
echo "The word you entered is: $word"
echo -e "Can you please enter two words? "
read word1 word2
echo "Here is your input: \"$word1\" \"$word2\""
echo -e "How do you feel about bash scripting? "
# read command now stores a reply into the default build-in variable $REPLY
read
echo "You said $REPLY, I'm glad to hear that! "
echo -e "What are your favorite colours ? "
# -a makes read command to read into an array
read -a colours
echo "My favorite colours are also ${colours[0]}, ${colours[1]} and ${colours[2]}:-)" 

Declare simple bash array

#!/bin/bash
#Declare array with 4 elements
ARRAY=( 'Debian Linux' 'Redhat Linux' Ubuntu Linux )
# get number of elements in the array
ELEMENTS=${#ARRAY[@]}

# echo each element in array 
# for loop
for (( i=0;i<$ELEMENTS;i++)); do
    echo ${ARRAY[${i}]}
done 

Read file into bash array

#!/bin/bash
# Declare array
declare -a ARRAY
# Link filedescriptor 10 with stdin
exec 10<&0
# stdin replaced with a file supplied as a first argument
exec < $1
let count=0

while read LINE; do

    ARRAY[$count]=$LINE
    ((count++))
done

echo Number of elements: ${#ARRAY[@]}
# echo array's content
echo ${ARRAY[@]}
# restore stdin from filedescriptor 10
# and close filedescriptor 10
exec 0<&10 10<&-

Bash if / else / fi statements

1. Simple Bash if/else statement
#!/bin/bash
directory="./BashScripting"

# bash check if directory exists
if [ -d $directory ]; then
	echo "Directory exists"
else 
	echo "Directory does not exists"
fi 

2. Nested if/else
#!/bin/bash
 
# Declare variable choice and assign value 4
choice=4
# Print to stdout
 echo "1. Bash"
 echo "2. Scripting"
 echo "3. Tutorial"
 echo -n "Please choose a word [1,2 or 3]? "
# Loop while the variable choice is equal 4
# bash while loop
while [ $choice -eq 4 ]; do
 
# read user input
read choice
# bash nested if/else
if [ $choice -eq 1 ] ; then
 
        echo "You have chosen word: Bash"

else                   

        if [ $choice -eq 2 ] ; then
                 echo "You have chosen word: Scripting"
        else
         
                if [ $choice -eq 3 ] ; then
                        echo "You have chosen word: Tutorial"
                else
                        echo "Please make a choice between 1-3 !"
                        echo "1. Bash"
                        echo "2. Scripting"
                        echo "3. Tutorial"
                        echo -n "Please choose a word [1,2 or 3]? "
                        choice=4
                fi   
        fi
fi
done 

Bash Comparisons

1. Arithmetic Comparisons
-lt	<
-gt	>
-le	<=
-ge	>=
-eq	==
-ne	!=
#!/bin/bash
# declare integers
NUM1=2
NUM2=2
if [ $NUM1 -eq $NUM2 ]; then
	echo "Both Values are equal"
else 
	echo "Values are NOT equal"
fi 

2. String Comparisons
=	equal
!=	not equal
<	less then
>	greater then
-n s1	string s1 is not empty
-z s1	string s1 is empty
#!/bin/bash
#Declare string S1
S1="Bash"
#Declare string S2
S2="Scripting"
if [ $S1 = $S2 ]; then
	echo "Both Strings are equal"
else 
	echo "Strings are NOT equal"
fi 

Bash File Testing

-b filename	Block special file
-c filename	Special character file
-d directoryname	Check for directory existence
-e filename	Check for file existence
-f filename	Check for regular file existence not a directory
-G filename	Check if file exists and is owned by effective group ID.
-g filename	true if file exists and is set-group-id.
-k filename	Sticky bit
-L filename	Symbolic link
-O filename	True if file exists and is owned by the effective user id.
-r filename	Check if file is a readable
-S filename	Check if file is socket
-s filename	Check if file is nonzero size
-u filename	Check if file set-ser-id bit is set
-w filename	Check if file is writable
-x filename	Check if file is executable
#!/bin/bash
file="./file"
if [ -e $file ]; then
	echo "File exists"
else 
	echo "File does not exists"
fi 

#!/bin/bash
 
while [ ! -e myfile ]; do
# Sleep until file does exists/is created
sleep 1
done 

Bash for/while/until loop

#!/bin/bash
# bash for loop
for f in $( ls /var/ ); do
	echo $f
done 

#!/bin/bash
COUNT=6
# bash while loop
while [ $COUNT -gt 0 ]; do
	echo Value of count is: $COUNT
	let COUNT=COUNT-1
done 

#!/bin/bash
COUNT=0
# bash until loop
until [ $COUNT -gt 5 ]; do
        echo Value of count is: $COUNT
        let COUNT=COUNT+1
done 

Bash Functions

!/bin/bash
# BASH FUNCTIONS CAN BE DECLARED IN ANY ORDER
function function_B {
        echo Function B.
}
function function_A {
        echo $1
}
function function_D {
        echo Function D.
}
function function_C {
        echo $1
}
# FUNCTION CALLS
# Pass parameter to function A
function_A "Function A."
function_B
# Pass parameter to function C
function_C "Function C."
function_D 

Bash Select

#!/bin/bash
 
PS3='Choose one word: ' 

# bash select
select word in "linux" "bash" "scripting" "tutorial" 
do
  echo "The word you have selected is: $word"
# Break, otherwise endless loop
  break  
done

exit 0 

Case statement conditional

#!/bin/bash
echo "What is your preferred programming / scripting language"
echo "1) bash"
echo "2) perl"
echo "3) phyton"
echo "4) c++"
echo "5) I do not know !"
read case;
#simple case bash structure
# note in this case $case is variable and does not have to
# be named case this is just an example
case $case in
    1) echo "You selected bash";;
    2) echo "You selected perl";;
    3) echo "You selected phyton";;
    4) echo "You selected c++";;
    5) exit
esac 

Bash quotes and quotations
Quotations and quotes are important part of bash and bash scripting. Here are some bash quotes and quotations basics.
Escaping Meta characters
Before we start with quotes and quotations we should know something about escaping meta characters. Escaping will suppress a special meaning of meta characters and therefore meta characters will be read by bash literally. To do this we need to use backslash “\” character. Example:

#!/bin/bash
 #Declare bash string variable
BASH_VAR="Bash Script"
# echo variable BASH_VAR
echo $BASH_VAR
#when meta character such us "$" is escaped with "\" it will be read literally
echo $BASH_VAR 
# backslash has also special meaning and it can be suppressed with yet another "\"
echo "\" 

Single quotes
Single quotes in bash will suppress special meaning of every meta characters. Therefore meta characters will be read literally. It is not possible to use another single quote within two single quotes not even if the single quote is escaped by backslash.

#!/bin/bash
 
 #Declare bash string variable
 BASH_VAR="Bash Script"
 
 # echo variable BASH_VAR
 echo $BASH_VAR
 
 # meta characters special meaning in bash is suppressed when  using single quotes 
 echo '$BASH_VAR  "$BASH_VAR"' 

Double Quotes
Double quotes in bash will suppress special meaning of every meta characters except “$”, “\” and “`”. Any other meta characters will be read literally. It is also possible to use single quote within double quotes. If we need to use double quotes within double quotes bash can read them literally when escaping them with “\”. Example:

#!/bin/bash
 
#Declare bash string variable
BASH_VAR="Bash Script"

# echo variable BASH_VAR
echo $BASH_VAR

# meta characters and its special meaning in bash is 
# suppressed when using double quotes except "$", "\" and "`"

echo "It's $BASH_VAR  and \"$BASH_VAR\" using backticks: `date`" 

Arithmetic Operations

echo '### Bash Arithmetic Expansion ###'
# There are two formats for arithmetic expansion: $[ expression ] 
# and $(( expression #)) its your choice which you use

echo 4 + 5 = $((4 + 5))
echo 7 - 7 = $[ 7 - 7 ]
echo 4 x 6 = $((3 * 2))
echo 6 / 3 = $((6 / 3))
echo 8 % 7 = $((8 % 7))
echo 2 ^ 8 = $[ 2 ** 8 ]


echo '### Declare ###'

echo -e "Please enter two numbers \c"
# read user input
read num1 num2
declare -i result
result=$num1+$num2
echo "Result is:$result "

# bash convert binary number 10001
result=2#10001
echo $result

# bash convert octal number 16
result=8#16
echo $result

# bash convert hex number 0xE6A
result=16#E6A
echo $result 

Round floating point number:
#!/bin/bash
# get floating point number
floating_point_number=3.3446
echo $floating_point_number
# round floating point number with bash
for bash_rounded_number in $(printf %.0f $floating_point_number); do
echo "Rounded number with bash:" $bash_rounded_number
done 

bash script search string and delete the line above

we search a string "test" in file.txt file, then delete its line above.
 hans@testvm:~ $ cat ./del_line_above.sh
#!/bin/bash
line_number="$(grep -n 'test' file.txt| cut -d: -f1)"
line_number_above="$((line_number - 1))"
sed "${line_number_above}d" file.txt

 hans@testvm:~ $ cat file.txt
aadsfasfda
line 1
line 2
line 3
line 4
test
java
hans@testvm:~ $ ./del_line_above.sh
aadsfasfda
line 1
line 2
line 3
test
java

Through the forest – Adam’s first poem

Sometimes I sit and wander through the forest ,
Think about humanity and how we’ve grown.
Sit and Learn to our heart desire, but then comes the moan.

Everyone hears, it haunts more then once a life,
A moan of struggles, that echoes through a pipe.

It sends a waves of a hunger for war, forcing everyone to write to their dears.
Then the moan turns into sobbing, representing the world’s tears.

The moan is of pure misery, from the depths of Tautrous herself.
Making people furious and then crumble and melt.
People start as saplings easy to break and bend. They grow, then break in two and snap.

Then I look at the great tree, standing tall and proud.
Looking down at their many branches grown each by themselves.

It only needed a can of water, a trinkle of effort.
To stand as high as the sky, tall and bold.

Looking between the two, sapling and great oak.
One prepared to snap, the other could support a boat.

Makes me wonder, what’s the difference between giants and an elf.
Then I realize that it’s only what people see in them, and what they see in themselves.

TAOBAO login with selenium and pyautogui

there are two challenges during taobao.com login:
1. sometimes the site will ask you pull the slider
resolved with Selenium ActionChains
2. taobao disabled selenium click()
resolved with pyautogui lib:
pip install pyautogui
here is the code for taobao.com login:

from selenium import webdriver
import logging
import time
from selenium.common.exceptions import NoSuchElementException, WebDriverException
from retrying import retry
from selenium.webdriver import ActionChains

import pyautogui
pyautogui.PAUSE = 0.5 

logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class taobao():
    def __init__(self):
        self.browser = webdriver.Chrome("path\to\your\chromedriver.exe")
        self.browser.maximize_window()
        self.browser.implicitly_wait(5)
        self.domain = 'http://www.taobao.com'
        self.action_chains = ActionChains(self.browser)

    def login(self, username, password):
        while True:
            self.browser.get(self.domain)
            time.sleep(1)

            #self.browser.find_element_by_class_name('h').click()
            #self.browser.find_element_by_id('fm-login-id').send_keys(username)
            #self.browser.find_element_by_id('fm-login-password').send_keys(password)
            self.browser.find_element_by_xpath('//*[@id="J_SiteNavLogin"]/div[1]/div[1]/a[1]').click()
            self.browser.find_element_by_xpath('//*[@id="fm-login-id"]').send_keys(username)
            self.browser.find_element_by_xpath('//*[@id="fm-login-password"]').send_keys(password)
            time.sleep(1)

            try:
                # using Selenium ActionChains for the website SLIDE authentication
                slider = self.browser.find_element_by_xpath("//span[contains(@class, 'btn_slide')]")
                if slider.is_displayed():
                    # pull the slider
                    self.action_chains.drag_and_drop_by_offset(slider, 258, 0).perform()
                    time.sleep(0.5)
                    # release the slider
                    self.action_chains.release().perform()
            except (NoSuchElementException, WebDriverException):
                logger.info('slider not found')

            # using pyautogui click the LOGIN PNG image
            #self.browser.find_element_by_class_name('password-login').click()
            #self.browser.find_element_by_xpath('//*[@id="login-form"]/div[4]/button').click()
             coords = pyautogui.locateOnScreen('1.png')
            x, y = pyautogui.center(coords)
            pyautogui.leftClick(x, y)

            nickname = self.get_nickname()
            if nickname:
                logger.info('successfully logon, nickname is' + nickname)
                break
            logger.debug('login failed,please try again after 5 seconds')
            time.sleep(5)

    def get_nickname(self):
        self.browser.get(self.domain)
        time.sleep(0.5)
        try:
            return self.browser.find_element_by_class_name('site-nav-user').text
        except NoSuchElementException:
            return ''


if __name__ == '__main__':
    # Input your TAOBAO username and password
    username = 'username'
    password = 'password'
    tb = taobao()
    tb.login(username, password)

Complete Django/MySQL CRUD Operations

Learned from CodAffection online course, code has been staged on github:
https://github.com/zhuby1973/python/tree/master/employee_project

we need pip install django-crispy-forms for this project.
1. django-admin startproject employee_project
2. python manage.py runserver
3. python manage.py startapp employee_register
edit settings.py, urls.py, views.py and models.py, then run migrate command to create tables:
python manage.py migrate
python manage.py makemigrations employee_register
python manage.py sqlmigrate employee_register 0001
python manage.py sqlmigrate employee_register 0002
python manage.py migrate
python manage.py createsuperuser (create admin user and verify in admin page)
you can verify the tables in MySQL.

# this is employee_register/views.py:
from django.shortcuts import render,redirect
from .forms import EmployeeForm, RegisterForm
from .models import Employee
import os
from django.conf import settings
from django.contrib import messages
#from django.contrib.auth import login, authenticate
#from django.contrib.auth.forms import UserCreationForm

# Create your views here.
def register(request):
    registerForm = RegisterForm(request.POST or None)
    if request.method == "POST":
        if registerForm.is_valid():
            registerForm.is_staff = True
            registerForm.save()

    return render(request, "registration/register.html", {"form": registerForm})

def employee_list(request):
    print (settings.BASE_DIR)
    context = {'employee_list':Employee.objects.all()}
    return render(request,"employee_register/employee_list.html",context)

def employee_form(request, id=0):
    if request.method == "GET":
        if id == 0:
            form = EmployeeForm()
        else:
            employee = Employee.objects.get(id=id)
            form = EmployeeForm(instance=employee)
        return render(request,"employee_register/employee_form.html",{'form':form})
    else:
        if id == 0:
            form = EmployeeForm(request.POST or None, request.FILES or None)
        else:
            employee = Employee.objects.get(id=id)
            employee.image.delete()
            form = EmployeeForm(request.POST or None, request.FILES or None, instance = employee)

        if form.is_valid():
            form.save()
            if id == 0:
                messages.success(request, "Employee Record Added Successfully!")
            else:
                messages.info(request,"Employee Record Updated Successfully!")

        return redirect("/employee/list")


def employee_delete(request,id):
    employee = Employee.objects.get(id=id)
    employee.delete()
    messages.error(request, 'Employee Record Deleted Successfully!')

    return redirect('/employee/list')

create Web Service with FastAPI and uvicorn

  1. pip install fastapi
  2. pip install uvicorn
    code main.py:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class People(BaseModel):
    name: str
    age: int
    address: str = None
@app.post('/insert')
def insert(people: People):
    age_after_10_years = people.age + 10
    msg = f'Name: {people.name},age after ten years:{age_after_10_years}'
    return {'success': True, 'msg': msg}
@app.get('/')
def index():
    return {'message': 'Hi, this is your FastApi service!'}

run command: uvicorn main:app --reload, then you can access docs
http://127.0.0.1:8000/docs, you can test POST/GET as below or test it with Postman.