Jump to content

Server-Side Scripting/Key-Value Databases/Python (FastAPI)

From Wikiversity

routers/lesson11.py

[edit | edit source]
# This program creates and displays a temperature database
# with options to insert, update, and delete records.
#
# References:
#   https://en.wikibooks.org/wiki/Python_Programming
#   https://realpython.com/python-redis/

from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

import redis as redis_lib

router = APIRouter(prefix="/lesson11")
templates = Jinja2Templates(directory="templates")

# Requires a Redis installation to manage the database.
# Use of a Docker container is recommended.
# See https://en.wikiversity.org/wiki/Docker/Redis .
# If both the FastAPI website and Redis are running in containers, 
# use 172.17.0.2 for the Redis host address.
# If the FastAPI website and/or Redis are running locally, use 127.0.0.1
# for the Redis host address.

# HOST = "172.17.0.2"
HOST = "127.0.0.1"
DATABASE = 0
COLLECTION = "countries"

@router.get("/", response_class=HTMLResponse)
async def get_lesson11(request: Request):
    try:
        result = get_data()
    except Exception as exception:
        result = exception

    return templates.TemplateResponse(
        "lesson11.html", 
        {   
            "request": request,
            "table": result
        }
    )

@router.post("/", response_class=HTMLResponse)
async def post_lesson11(request: Request):
    form = dict(await request.form())
    try:
        country = form["country"].strip()
        temperature = form["temperature"].strip()

        if not country_exists(country):
            insert_country(country, temperature)
        elif temperature != "":
            update_country(country, temperature)
        else:
            delete_country(country)

        result = get_data()
    except Exception as exception:
        result = exception

    return templates.TemplateResponse(
        "lesson11.html", 
        {   
            "request": request,
            "table": result
        }
    )

def get_data():
    redis = redis_lib.Redis(host=HOST, db=DATABASE)
    result = "<table><tr><th>Country</th>"
    result += "<th>Temperature</th></tr>"
    countries = redis.keys()
    countries.sort()
    for country in countries:
        temperature = redis.get(country)
        result += f"<tr><td>{country.decode()}</td>"
        result += f"<td>{temperature.decode()}</td></tr>"
    result += "</table>"
    return result

def country_exists(country):
    redis = redis_lib.Redis(host=HOST, db=DATABASE)
    return bool(redis.exists(country))

def insert_country(country, temperature):
    redis = redis_lib.Redis(host=HOST, db=DATABASE)
    redis.set(country, temperature)

def update_country(country, temperature):
    redis = redis_lib.Redis(host=HOST, db=DATABASE)
    redis.set(country, temperature)

def delete_country(country):
    redis = redis_lib.Redis(host=HOST, db=DATABASE)
    redis.delete(country)

templates/lesson11.html

[edit | edit source]
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Lesson 11</title>
    <link rel="stylesheet" href="{{url_for('static', path='/styles.css')}}">
</head>

<body>
    <h1>Temperature Data Entry</h1>
    <p>Enter country and temperature. Enter again to update.</p>
    <p>Enter country without temperature to delete.</p>
    <form method="POST">
        <p><label for="country">Country:</label>
            <input type="text" id="country" name="country" required>
        </p>
        <p><label for="stop">Temperature:</label>
            <input type="text" id="temperature" name="temperature">
        </p>
        <p><input type="submit" name="submit" value="Submit"></p>
    </form>
    <hr>
    {{table|safe}}
</body>

</html>

Try It

[edit | edit source]

See Server-Side Scripting/Routes and Templates/Python (FastAPI) to create a test environment.

See Also

[edit | edit source]