-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: add fastapi tutorial spread test
- Loading branch information
Showing
8 changed files
with
294 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from fastapi import FastAPI | ||
|
||
app = FastAPI() | ||
|
||
@app.get("/") | ||
async def root(): | ||
return {"message": "Hello World"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import os | ||
|
||
from fastapi import FastAPI | ||
|
||
app = FastAPI() | ||
|
||
@app.get("/") | ||
async def root(): | ||
return {"message": os.getenv("APP_GREETING", "Hello World")} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# configuration snippet for FastAPI application with a configuration | ||
|
||
config: | ||
options: | ||
greeting: | ||
description: | | ||
The greeting to be returned by the FastAPI application. | ||
default: "Hello, world!" | ||
type: string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
fastapi[standard] | ||
psycopg2-binary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
########################################### | ||
# IMPORTANT | ||
# Comments matter! | ||
# The docs use the wrapping comments as | ||
# markers for including said instructions | ||
# as snippets in the docs. | ||
########################################### | ||
summary: Getting started with FastAPI tutorial | ||
|
||
kill-timeout: 180m | ||
|
||
environment: | ||
|
||
execute: | | ||
# Move everything to $HOME so that Juju deployment works | ||
mv *.yaml *.py *.txt $HOME | ||
cd $HOME | ||
# Don't use the staging store for this test | ||
unset CHARMCRAFT_STORE_API_URL | ||
unset CHARMCRAFT_UPLOAD_URL | ||
unset CHARMCRAFT_REGISTRY_URL | ||
# MicroK8s config setup | ||
microk8s status --wait-ready | ||
microk8s enable hostpath-storage | ||
microk8s enable registry | ||
microk8s enable ingress | ||
# Bootstrap controller | ||
juju bootstrap microk8s dev-controller | ||
# [docs:create-venv] | ||
sudo apt-get update && sudo apt-get install python3-venv -y | ||
python3 -m venv .venv | ||
source .venv/bin/activate | ||
# [docs:create-venv-end] | ||
# [docs:install-requirements] | ||
pip install -r requirements.txt | ||
# [docs:install-requirements-end] | ||
fastapi dev app.py --port 8080 & | ||
retry -n 5 --wait 2 curl --fail localhost:8080 | ||
# [docs:curl-fastapi] | ||
curl localhost:8080 | ||
# [docs:curl-fastapi-end] | ||
kill $! | ||
# [docs:create-rockcraft-yaml] | ||
rockcraft init --profile fastapi-framework | ||
# [docs:create-rockcraft-yaml-end] | ||
sed -i "s/name: .*/name: fastapi-hello-world/g" rockcraft.yaml | ||
sed -i "s/amd64/$(dpkg --print-architecture)/g" rockcraft.yaml | ||
# [docs:pack] | ||
ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true rockcraft pack | ||
# [docs:pack-end] | ||
# [docs:skopeo-copy] | ||
rockcraft.skopeo --insecure-policy copy --dest-tls-verify=false \ | ||
oci-archive:fastapi-hello-world_0.1_$(dpkg --print-architecture).rock \ | ||
docker://localhost:32000/fastapi-hello-world:0.1 | ||
# [docs:skopeo-copy-end] | ||
# [docs:create-charm-dir] | ||
mkdir charm | ||
cd charm | ||
# [docs:create-charm-dir-end] | ||
# [docs:charm-init] | ||
charmcraft init --profile fastapi-framework --name fastapi-hello-world | ||
# [docs:charm-init-end] | ||
# update platforms in charmcraft.yaml file | ||
sed -i "s/amd64/$(dpkg --print-architecture)/g" charmcraft.yaml | ||
# [docs:charm-pack] | ||
CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true charmcraft pack | ||
# [docs:charm-pack-end] | ||
# [docs:add-juju-model] | ||
juju add-model fastapi-hello-world | ||
# [docs:add-juju-model-end] | ||
#[docs:add-model-constraints] | ||
juju set-model-constraints -m fastapi-hello-world arch=$(dpkg --print-architecture) | ||
#[docs:add-model-constraints-end] | ||
# [docs:deploy-fastapi-app] | ||
juju deploy \ | ||
./fastapi-hello-world_$(dpkg --print-architecture).charm \ | ||
fastapi-hello-world --resource \ | ||
app-image=localhost:32000/fastapi-hello-world:0.1 | ||
# [docs:deploy-fastapi-app-end] | ||
# [docs:deploy-nginx] | ||
juju deploy nginx-ingress-integrator --channel=latest/stable --trust | ||
juju integrate nginx-ingress-integrator fastapi-hello-world | ||
# [docs:deploy-nginx-end] | ||
# [docs:config-nginx] | ||
juju config nginx-ingress-integrator \ | ||
service-hostname=fastapi-hello-world path-routes=/ | ||
# [docs:config-nginx-end] | ||
# give Juju some time to deploy the apps | ||
juju wait-for application fastapi-hello-world --query='status=="active"' --timeout 10m | ||
juju wait-for application nginx-ingress-integrator --query='status=="active"' --timeout 10m | ||
# [docs:curl-init-deployment] | ||
curl http://fastapi-hello-world --resolve fastapi-hello-world:80:127.0.0.1 | ||
# [docs:curl-init-deployment-end] | ||
cd .. | ||
cat greeting_app.py > app.py | ||
sed -i "s/version: .*/version: 0.2/g" rockcraft.yaml | ||
# [docs:docker-update] | ||
ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true rockcraft pack | ||
rockcraft.skopeo --insecure-policy copy --dest-tls-verify=false \ | ||
oci-archive:fastapi-hello-world_0.2_$(dpkg --print-architecture).rock \ | ||
docker://localhost:32000/fastapi-hello-world:0.2 | ||
# [docs:docker-update-end] | ||
cat greeting_charmcraft.yaml >> ./charm/charmcraft.yaml | ||
cd charm | ||
# [docs:refresh-deployment] | ||
CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true charmcraft pack | ||
juju refresh fastapi-hello-world \ | ||
--path=./fastapi-hello-world_$(dpkg --print-architecture).charm \ | ||
--resource app-image=localhost:32000/fastapi-hello-world:0.2 | ||
# [docs:refresh-deployment-end] | ||
# give Juju some time to refresh the app | ||
juju wait-for application fastapi-hello-world --query='status=="active"' --timeout 10m | ||
# curl and check that the response is Hello | ||
curl http://fastapi-hello-world --resolve fastapi-hello-world:80:127.0.0.1 | grep Hello | ||
# [docs:change-config] | ||
juju config fastapi-hello-world greeting='Hi!' | ||
# [docs:change-config-end] | ||
# make sure that the application updates | ||
juju wait-for application fastapi-hello-world --query='status=="maintenance"' --timeout 10m | ||
juju wait-for application fastapi-hello-world --query='status=="active"' --timeout 10m | ||
# curl and check that the response is now Hi | ||
curl http://fastapi-hello-world --resolve fastapi-hello-world:80:127.0.0.1 | grep Hi | ||
cd .. | ||
cat visitors_migrate.py >> migrate.py | ||
cat visitors_app.py > app.py | ||
sed -i "s/version: .*/version: 0.3/g" rockcraft.yaml | ||
# [docs:docker-2nd-update] | ||
ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true rockcraft pack | ||
rockcraft.skopeo --insecure-policy copy --dest-tls-verify=false \ | ||
oci-archive:fastapi-hello-world_0.3_$(dpkg --print-architecture).rock \ | ||
docker://localhost:32000/fastapi-hello-world:0.3 | ||
# [docs:docker-2nd-update-end] | ||
cat visitors_charmcraft.yaml >> ./charm/charmcraft.yaml | ||
cd charm | ||
# [docs:refresh-2nd-deployment] | ||
CHARMCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS=true charmcraft pack | ||
juju refresh fastapi-hello-world \ | ||
--path=./fastapi-hello-world_$(dpkg --print-architecture).charm \ | ||
--resource app-image=localhost:32000/fastapi-hello-world:0.3 | ||
# [docs:refresh-2nd-deployment-end] | ||
# [docs:deploy-postgres] | ||
juju deploy postgresql-k8s --trust | ||
juju integrate fastapi-hello-world postgresql-k8s | ||
# [docs:deploy-postgres-end] | ||
# give Juju some time to deploy and refresh the apps | ||
juju wait-for application postgresql-k8s --query='status=="active"' --timeout 20m | juju status --relations | ||
juju wait-for application fastapi-hello-world --query='status=="active"' --timeout 20m | juju status --relations | ||
curl http://fastapi-hello-world --resolve fastapi-hello-world:80:127.0.0.1 | grep Hi | ||
curl http://fastapi-hello-world/visitors --resolve fastapi-hello-world:80:127.0.0.1 | grep 1 | ||
curl http://fastapi-hello-world --resolve fastapi-hello-world:80:127.0.0.1 | grep Hi | ||
curl http://fastapi-hello-world/visitors --resolve fastapi-hello-world:80:127.0.0.1 | grep 2 | ||
# Back out to main directory for cleanup | ||
cd .. | ||
# [docs:clean-environment] | ||
# exit and delete the virtual environment | ||
deactivate | ||
rm -rf charm .venv __pycache__ | ||
# delete all the files created during the tutorial | ||
rm fastapi-hello-world_0.1_$(dpkg --print-architecture).rock \ | ||
fastapi-hello-world_0.2_$(dpkg --print-architecture).rock \ | ||
fastapi-hello-world_0.3_$(dpkg --print-architecture).rock \ | ||
rockcraft.yaml app.py requirements.txt migrate.py | ||
# Remove the juju model | ||
juju destroy-model fastapi-hello-world --destroy-storage --no-prompt --force | ||
# [docs:clean-environment-end] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# FastAPI application that keeps track of visitors using a database | ||
|
||
import datetime | ||
import os | ||
from typing import Annotated | ||
|
||
from fastapi import FastAPI, Header | ||
import psycopg2 | ||
|
||
app = FastAPI() | ||
DATABASE_URI = os.environ["POSTGRESQL_DB_CONNECT_STRING"] | ||
|
||
|
||
@app.get("/") | ||
async def root(user_agent: Annotated[str | None, Header()] = None): | ||
with psycopg2.connect(DATABASE_URI) as conn, conn.cursor() as cur: | ||
timestamp = datetime.datetime.now() | ||
|
||
cur.execute( | ||
"INSERT INTO visitors (timestamp, user_agent) VALUES (%s, %s)", | ||
(timestamp, user_agent) | ||
) | ||
conn.commit() | ||
|
||
return {"message": os.getenv("APP_GREETING", "Hello World")} | ||
|
||
|
||
@app.get("/visitors") | ||
async def visitors(): | ||
with psycopg2.connect(DATABASE_URI) as conn, conn.cursor() as cur: | ||
cur.execute("SELECT COUNT(*) FROM visitors") | ||
total_visitors = cur.fetchone()[0] | ||
|
||
return {"count": total_visitors} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# requires snippet for FastAPI application with a database | ||
|
||
requires: | ||
postgresql: | ||
interface: postgresql_client | ||
optional: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Adds database to FastAPI application | ||
|
||
import os | ||
|
||
import psycopg2 | ||
|
||
DATABASE_URI = os.environ["POSTGRESQL_DB_CONNECT_STRING"] | ||
|
||
def migrate(): | ||
with psycopg2.connect(DATABASE_URI) as conn, conn.cursor() as cur: | ||
cur.execute(""" | ||
CREATE TABLE IF NOT EXISTS visitors ( | ||
timestamp TIMESTAMP NOT NULL, | ||
user_agent TEXT NOT NULL | ||
); | ||
""") | ||
conn.commit() | ||
|
||
|
||
if __name__ == "__main__": | ||
migrate() |