Skip to content

Commit

Permalink
Merge branch 'main' into dev_docker
Browse files Browse the repository at this point in the history
  • Loading branch information
gitkvark authored Dec 29, 2023
2 parents 38c5073 + a17f7ae commit 795f2f1
Show file tree
Hide file tree
Showing 17 changed files with 248 additions and 88 deletions.
10 changes: 1 addition & 9 deletions .github/workflows/terraform_deployments_prod_apply.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,4 @@ jobs:
id: apply-run
with:
workspace: ${{ env.TF_WORKSPACE }}
configuration_version: ${{ steps.apply-upload.outputs.configuration_version_id }}

- name: Apply
uses: hashicorp/tfc-workflows-github/actions/apply-run@v1.1.1
if: fromJSON(steps.apply-run.outputs.payload).data.attributes.actions.IsConfirmable
id: apply
with:
run: ${{ steps.apply-run.outputs.run_id }}
comment: "Apply Run from GitHub Actions CI ${{ github.sha }}"
configuration_version: ${{ steps.apply-upload.outputs.configuration_version_id }}
10 changes: 1 addition & 9 deletions .github/workflows/terraform_provisioning_prod_apply.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,4 @@ jobs:
id: apply-run
with:
workspace: ${{ env.TF_WORKSPACE }}
configuration_version: ${{ steps.apply-upload.outputs.configuration_version_id }}

- name: Apply
uses: hashicorp/tfc-workflows-github/actions/apply-run@v1.1.1
if: fromJSON(steps.apply-run.outputs.payload).data.attributes.actions.IsConfirmable
id: apply
with:
run: ${{ steps.apply-run.outputs.run_id }}
comment: "Apply Run from GitHub Actions CI ${{ github.sha }}"
configuration_version: ${{ steps.apply-upload.outputs.configuration_version_id }}
9 changes: 0 additions & 9 deletions app/config.py

This file was deleted.

26 changes: 0 additions & 26 deletions app/db.py

This file was deleted.

195 changes: 174 additions & 21 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,182 @@
from fastapi import FastAPI

from app.db import database, User
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field
from pydantic_settings import BaseSettings
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
from prometheus_fastapi_instrumentator import Instrumentator

app = FastAPI(title="FastAPI, Docker, and Traefik")
instrumentator = Instrumentator().instrument(app)
# Database configuration
import os

class Settings(BaseSettings):
db_url: str = Field(..., env='DATABASE_URL')

settings = Settings(db_url=os.environ['DATABASE_URL'])

#from .config import settings
#database = databases.Database(settings.db_url)
#DATABASE_URL = "postgresql://postgres:postgres123@192.168.1.30/db_app001"

engine = create_engine(settings.db_url)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

# Define User model
class User(Base):
__tablename__ = "users"

id = Column(Integer, primary_key=True, index=True)
name = Column(String, index=True)
email = Column(String, index=True)
course_id = Column(Integer, ForeignKey("courses.id_cours"))

course = relationship("Course", back_populates="users")

# Define Course model
class Course(Base):
__tablename__ = "courses"

id_cours = Column(Integer, primary_key=True, index=True)
course_name = Column(String, index=True)

users = relationship("User", back_populates="course")

# Create tables in the database
Base.metadata.create_all(bind=engine)

# FastAPI app setup
app = FastAPI()

# Prometheus monitoring setup
Instrumentator().instrument(app).expose(app)

# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

# Pydantic models for request and response
class UserCreate(BaseModel):
name: str
email: str

class CourseCreate(BaseModel):
course_name: str

class UserResponse(UserCreate):
id: int

class CourseResponse(CourseCreate):
id_cours: int

# Endpoints
@app.post("/users/", response_model=UserResponse)
def create_user(user: UserCreate):
db = SessionLocal()
db_user = User(**user.dict())
db.add(db_user)
db.commit()
db.refresh(db_user)
db.close()
return db_user

@app.put("/users/{user_id}", response_model=UserResponse)
def update_user(user_id: int, user: UserCreate):
db = SessionLocal()
db_user = db.query(User).filter(User.id == user_id).first()
if db_user:
db_user.name = user.name
db_user.email = user.email
db.commit()
db.refresh(db_user)
db.close()
return db_user

@app.get("/users/{user_id}", response_model=UserResponse)
def read_user(user_id: int):
db = SessionLocal()
db_user = db.query(User).filter(User.id == user_id).first()
db.close()
if db_user:
return db_user
else:
raise HTTPException(status_code=404, detail="User not found")

@app.get("/users/", response_model=list[UserResponse])
def read_users(skip: int = 0, limit: int = 10):
db = SessionLocal()
users = db.query(User).offset(skip).limit(limit).all()
db.close()
return users

@app.delete("/users/{user_id}", response_model=UserResponse)
def delete_user(user_id: int):
db = SessionLocal()
db_user = db.query(User).filter(User.id == user_id).first()
if db_user:
db.delete(db_user)
db.commit()
db.close()
return db_user
else:
db.close()
raise HTTPException(status_code=404, detail="User not found")

@app.get("/")
async def read_root():
return await User.objects.all()
@app.post("/courses/", response_model=CourseResponse)
def create_course(course: CourseCreate):
db = SessionLocal()
db_course = Course(**course.dict())
db.add(db_course)
db.commit()
db.refresh(db_course)
db.close()
return db_course

@app.put("/courses/{course_id}", response_model=CourseResponse)
def update_course(course_id: int, course: CourseCreate):
db = SessionLocal()
db_course = db.query(Course).filter(Course.id_cours == course_id).first()
if db_course:
db_course.course_name = course.course_name
db.commit()
db.refresh(db_course)
db.close()
return db_course

@app.on_event("startup")
async def startup():
# Expose prometheus metrics using the Instrumentator
# https://github.com/trallnag/prometheus-fastapi-instrumentator
instrumentator.expose(app)
if not database.is_connected:
await database.connect()
# create a dummy entry
await User.objects.get_or_create(email="test@test.com")
@app.get("/courses/{course_id}", response_model=CourseResponse)
def read_course(course_id: int):
db = SessionLocal()
db_course = db.query(Course).filter(Course.id_cours == course_id).first()
db.close()
if db_course:
return db_course
else:
raise HTTPException(status_code=404, detail="Course not found")

@app.get("/courses/", response_model=list[CourseResponse])
def read_courses(skip: int = 0, limit: int = 10):
db = SessionLocal()
courses = db.query(Course).offset(skip).limit(limit).all()
db.close()
return courses

@app.on_event("shutdown")
async def shutdown():
if database.is_connected:
await database.disconnect()
@app.delete("/courses/{course_id}", response_model=CourseResponse)
def delete_course(course_id: int):
db = SessionLocal()
db_course = db.query(Course).filter(Course.id_cours == course_id).first()
if db_course:
db.delete(db_course)
db.commit()
db.close()
return db_course
else:
db.close()
raise HTTPException(status_code=404, detail="Course not found")
38 changes: 34 additions & 4 deletions app/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
asyncpg==0.29.0
fastapi==0.106.0
ormar==0.12.2
annotated-types==0.6.0
anyio==3.7.1
certifi==2023.11.17
click==8.1.7
colorama==0.4.6
dnspython==2.4.2
email-validator==2.1.0.post1
fastapi==0.105.0
greenlet==3.0.3
h11==0.14.0
httpcore==1.0.2
httptools==0.6.1
httpx==0.26.0
idna==3.6
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
orjson==3.9.10
prometheus-client==0.19.0
prometheus-fastapi-instrumentator==6.1.0
psycopg2-binary==2.9.9
pydantic==2.5.3
pydantic-extra-types==2.2.0
pydantic-settings==2.1.0
pydantic_core==2.14.6
python-dotenv==1.0.0
python-multipart==0.0.6
PyYAML==6.0.1
sniffio==1.3.0
SQLAlchemy==2.0.23
starlette==0.27.0
typing_extensions==4.9.0
ujson==5.9.0
uvicorn==0.25.0
prometheus-fastapi-instrumentator==6.1.0
watchfiles==0.21.0
websockets==12.0
2 changes: 1 addition & 1 deletion helm/fastapi-app/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.6
version: 0.1.9

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
Expand Down
18 changes: 12 additions & 6 deletions scripts/bootstrap.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,26 @@ set -e #ux
cwd="$(pwd)"
## Change to project directory
cd "$(dirname "$0")/.."
# shellcheck source="../.env"
source .env
if [ -f .env ]; then
# shellcheck source="../.env" disable=SC1091
source .env
fi

./scripts/python_setup.sh "$@"

echo "-- Shell: Source profile in case it's been updated"
# shellcheck source="$HOME/.profile"
# shellcheck source="$HOME/.profile" disable=SC1091
source "$HOME/.profile"

echo "-- Activate Python virtual environment"
# shellcheck source="../.venv/bin/activate"
source .venv/bin/activate
echo "-- Source '.env' configuration file"
# shellcheck source="../.env"
source .env

if [ -f .env ]; then
echo "-- Source '.env' configuration file"
# shellcheck source="../.env" disable=SC1091
source .env
fi

## and go back
cd "$cwd"
Empty file modified scripts/prestart.sh
100644 → 100755
Empty file.
6 changes: 5 additions & 1 deletion scripts/python_setup.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ cwd="$(pwd)"
## Change to project directory
cd "$(dirname "$0")/.."
# shellcheck source="../.env"
source .env
if [ -f .env ]; then
# shellcheck source="../.env"
source .env
fi

## Only compatible with Debian and Ubuntu
if [[ ! $(dpkg -s python3-venv) ]]; then
Expand All @@ -23,6 +26,7 @@ fi
echo "-- Python: Activate '.venv' virtual environment"
# shellcheck source="../.venv/bin/activate"
source .venv/bin/activate

echo "-- Upgrage Python pip and setuptools in venv"
pip install --upgrade setuptools pip
echo "-- Install Python requirements in venv"
Expand Down
2 changes: 2 additions & 0 deletions terraform/deployments/preprod/releases/fastapi_app.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ resource "helm_release" "fastapi_app" {
name = "fastapi-app"
chart = "${path.module}/../../../../helm/fastapi-app"
create_namespace = true
version = "0.1.9"
recreate_pods = true
values = [
file("${path.module}/../../../../helm/fastapi-app/values-preprod.yaml")
]
Expand Down
1 change: 1 addition & 0 deletions terraform/deployments/preprod/releases/postgres_cluster.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ resource "helm_release" "postgres_cluster" {
name = "postgres-cluster"
chart = "${path.module}/../../../../helm/postgres-cluster"
create_namespace = true
version = "0.1.12"
values = [
file("${path.module}/../../../../helm/postgres-cluster/values-preprod.yaml")
]
Expand Down
Loading

0 comments on commit 795f2f1

Please sign in to comment.