feat: update Dockerfile and Makefile for improved deployment; add integration testing instructions and version endpoint
All checks were successful
Build and Push to Private Registry101 / build (push) Successful in 33s

This commit is contained in:
stephen schuresko
2025-02-18 08:29:31 -05:00
parent 40eda9f021
commit b9bf105939
9 changed files with 143 additions and 14 deletions

4
.gitignore vendored
View File

@@ -1,5 +1,5 @@
__pycache__
test.db
test*.db
.coverage
report.xml
coverage.xml
coverage.xml

View File

@@ -1,3 +1,5 @@
#
#
FROM python:3.12
@@ -13,4 +15,4 @@ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./*.py /code/
CMD ["python3", "papi.py", "--port", "8912"]
CMD ["uvicorn", "papi:app","--port", "8912","--host","0.0.0.0"]

View File

@@ -1,20 +1,35 @@
ENV=dev
VER=4
VER=0.0.4
TAG=${ENV}-${VER}
REGISTRY=kube-reg.fairfaxmedia.net
SVC=papi/svc1
DOCK_IMG=${REGISTRY}/${SVC}:${TAG}
LIVE_HOST:="http://localhost:8912"
clean:
rm -rf .pytest_cache
rm -rf .coverage
rm -rf report.xml
rm -rf test.db
rm -rf htmlcov
coverage: clean
install:
pip3 install -r requirements.txt
coverage: clean install
pytest --cov=papi --cov=posts --cov=users test_papi.py test_posts.py test_users.py --junitxml=report.xml --cov-report=html --cov-report=xml --cov-report=term --cov-fail-under 90
docker-img: coverage
docker build -t ${DOCK_IMG} .
docker-push: docker-img
docker push ${DOCK_IMG}
deploy: docker-push
helm upgrade papi ./papi-helm/ -f ./papi-helm/v.${ENV}.yaml --set image.tag=${TAG}
helm upgrade papi ./papi-helm/ -f ./papi-helm/v.${ENV}.yaml --set image.tag=${TAG} --set env.VERSION=${VER}
integration: install
pyresttest ${LIVE_HOST} integration.pyrest.yaml
run: install
uvicorn papi:app --reload --port 8912 --host 0.0.0.0
all: deploy

View File

@@ -72,4 +72,18 @@ ensure you are logged into kubernetes so that commands kubectl and helm both wor
then run
```bash
make deploy
```
```
##integration testing instructions
to test live on papi.kube-dev.fairfaxmedia.net
run the following:
```bash
make integration -e LIVE_HOST=http://papi.kube-dev.fairfaxmedia.net
```
to integration-test on localhost on the default port run
```bash
make integration
```

2
db.py
View File

@@ -11,7 +11,7 @@ if os.getenv("DATABASE_URL"):
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
version = os.environ.get("VERSION", "0.0.0")

85
integration.pyrest.yaml Normal file
View File

@@ -0,0 +1,85 @@
# Test using included Django test app
# First install python-django
# Then launch the app in another terminal by doing
# cd testapp
# python manage.py testserver test_data.json
# Once launched, tests can be executed via:
# python resttest.py http://localhost:8000 miniapp-test.yaml
---
- config:
- testset: "Tests using test app"
- variable_binds:
- 'uid': 1
- 'post_id': 1
- test: # create entity
- name: "Basic get"
- url: "/"
- test: # create entity
- name: "Get version"
- url: "/version"
- test: # create person by POST
- name: "Create person"
- url: "/users"
- method: "POST"
- body: '{"name": "Willim","email": "theadmiral@gmail.com"}'
- headers: {Content-Type: application/json}
- extract_binds:
- 'uid' : {'jsonpath_mini': "user.id"}
- test: # get single person
- name: "Get single person"
- url: {'template':'/users/$uid'} # use binded value
- method: 'GET'
- test: # update person by PUT
- name: "update person by PUT"
- url: {'template':'/users/$uid'}
- method: "PUT"
- body: '{"name": "Gaius"}'
- headers: {'Content-Type': 'application/json'}
- test: # create post by POST
- name: "Create post"
- url: "/posts"
- method: "POST"
- body: '{"title": "Willims post","content": "william made a post","author_id": 1}'
- headers: {Content-Type: application/json}
- extract_binds:
- 'post_id' : {'jsonpath_mini': "post.id"}
- test: # get single post
- name: "Get single post"
- url: {'template':'/posts/$post_id'}
- method: 'GET'
- test: # update post by PUT
- name: "update post by PUT"
- url: {'template':'/posts/$post_id'}
- method: "PUT"
- body: '{"title": "Gaius made a post"}'
- headers: {'Content-Type': 'application/json'}
- test: # delete post
- name: "Delete post"
- url: {'template':'/posts/$post_id'}
- method: "DELETE"
- test: # delete person
- name: "Delete person"
- url: {'template':'/users/$uid'}
- method: "DELETE"

17
papi.py
View File

@@ -1,4 +1,11 @@
#!/bin/env python3
#
# author: Stephen Schuresko
# date: 2025-02-18
# file: papi.py
# description: A simple FastAPI app (papi) with a few routes and models for users and posts
#
from fastapi import FastAPI, Depends
import uvicorn
from sqlalchemy import create_engine, Column, Integer,String, ForeignKey
@@ -7,6 +14,7 @@ from sqlalchemy.orm import sessionmaker, Session, declarative_base
import db
import users
import posts
import os
@@ -19,9 +27,6 @@ app.include_router(posts.router)
async def root():
return {"message": "Hello World"}
if __name__ == "__main__":
uvicorn.run("papi:app", host="0.0.0.0", port=8912, reload=True, log_level="debug",
workers=5, limit_concurrency=10, limit_max_requests=100)
@app.get("/version")
async def ver():
return {"version":db.version}

View File

@@ -1,3 +1,4 @@
fastapi
sqlalchemy
uvicorn
pyresttest

View File

@@ -12,3 +12,10 @@ def test_read_main():
assert response.json() == {"message": "Hello World"}
def test_read_version():
response = client.get("/version")
assert response.status_code == 200