Skip to content

Commit

Permalink
Update Kube api & streamlit
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoinePELAMOURGUES committed Dec 4, 2024
1 parent 5304d6e commit 312bae9
Show file tree
Hide file tree
Showing 16 changed files with 246 additions and 230 deletions.
18 changes: 16 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
NAMESPACE1 = reco-movies
NAMESPACE1 = api
NAMESPACE2 = airflow
NAMESPACE3 = mlflow

Expand Down Expand Up @@ -145,6 +145,12 @@ start-mlflow:
helm install mlf-ts bitnami/mlflow --namespace mlflow --create-namespace
kubectl apply -f kubernetes/services/mlflow-service.yml

start-api:
kubectl create namespace api
kubectl apply -f kubernetes/deployments/fastapi-deployment.yml
kubectl apply -f kubernetes/deployments/streamlit-deployment.yml
kubectl apply -f kubernetes/secrets/api-secrets.yaml
kubectl apply -f kubernetes/services/api-service.yml

delete-pv-airflow:
kubectl delete pv airflow-local-dags-folder || true
Expand All @@ -161,6 +167,15 @@ reco: namespace pv secrets configmaps deployments services ingress
namespace: check-kube
kubectl apply -f kubernetes/namespace/namespace.yml --validate=false

change-namespace-api:
kubectl config set-context --current --namespace=$(NAMESPACE1)

change-namespace-airflow:
kubectl config set-context --current --namespace=$(NAMESPACE2)

change-namespace-mlflow:
kubectl config set-context --current --namespace=$(NAMESPACE3)

pv: check-kube
kubectl apply -f kubernetes/persistent-volumes/fastapi-persistent-volume.yml --validate=false
kubectl apply -f kubernetes/persistent-volumes/grafana-persistent-volume.yml --validate=false
Expand Down Expand Up @@ -200,6 +215,5 @@ clean-kube-reco: check-kube
clean-kube-airflow: check-kube
kubectl delete namespace $(NAMESPACE2)


clean-kube-mlflow: check-kube
kubectl delete namespace $(NAMESPACE3)
13 changes: 12 additions & 1 deletion docker/fastapi/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
# Utiliser une image de base Python
FROM python:3.12

# Définir le répertoire de travail
WORKDIR /app

# Installer les dépendances système nécessaires
RUN apt-get update && \
apt-get install -y python3-distutils gcc g++ && \
apt-get clean

# Copier le fichier requirements.txt
COPY ./requirements.txt /app/requirements.txt

# Installer les dépendances Python
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt

# Copier le reste de l'application
COPY . .

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
# Commande par défaut pour exécuter l'application (ajustez selon vos besoins)
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
75 changes: 60 additions & 15 deletions docker/fastapi/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from starlette import status
from database import get_db_connection
from passlib.context import CryptContext
from fastapi.security import OAuth2PasswordRequestForm, OAuth2PasswordBearer
from jose import jwt, JWTError
Expand All @@ -14,11 +13,15 @@
import re
import psycopg2
import logging
from kubernetes import client, config

# Configurer le logger
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Charger la configuration Kubernetes
config.load_incluster_config()

# Création d'un routeur pour gérer les routes d'authentification
router = APIRouter(
prefix='/auth', # Préfixe pour toutes les routes dans ce routeur
Expand Down Expand Up @@ -108,6 +111,26 @@ class Token(BaseModel):
registry=collector
)

def load_config():
"""Charge la configuration de la base de données à partir des variables d'environnement."""
return {
'host': os.getenv('AIRFLOW_POSTGRESQL_SERVICE_HOST'),
'database': os.getenv('DATABASE'),
'user': os.getenv('USER'),
'password': os.getenv('PASSWORD')
}

def connect(config):
"""Connecte au serveur PostgreSQL et retourne la connexion."""
try:
conn = psycopg2.connect(**config)
print('Connected to the PostgreSQL server.')
return conn
except (psycopg2.DatabaseError, Exception) as error:
print(f"Connection error: {error}")
return None


# Fonction pour valider le nom d'utilisateur
def validate_username(username):
if re.match("^[A-Za-z0-9_]+$", username) is None:
Expand Down Expand Up @@ -162,8 +185,11 @@ async def create_user(create_user_request: CreateUserRequest):
logger.error(f"Erreur validation mot de passe: {password_error}")
raise HTTPException(status_code=400, detail=password_error)

try:
with get_db_connection() as conn:
config = load_config()
conn = connect(config)

if conn is not None:
try:
with conn.cursor() as cur:
cur.execute("SELECT email FROM users WHERE email = %s", (create_user_request.email,))
if cur.fetchone() is not None:
Expand All @@ -174,14 +200,22 @@ async def create_user(create_user_request: CreateUserRequest):

# Créer le nouvel utilisateur
hached_password = bcrypt_context.hash(create_user_request.password)
cur.execute("INSERT INTO users (username, email, hached_password) VALUES (%s, %s, %s)", (create_user_request.username, create_user_request.email, hached_password,))
cur.execute("INSERT INTO users (username, email, hached_password) VALUES (%s, %s, %s)",
(create_user_request.username, create_user_request.email, hached_password,))
conn.commit()
logger.info("Utilisateur créé avec succès")

except psycopg2.Error as e:
error_counter.labels(error_type='database_error').inc()
logger.error(f"Erreur base de données: {str(e)}")
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
except psycopg2.Error as e:
error_counter.labels(error_type='database_error').inc()
logger.error(f"Erreur base de données: {str(e)}")
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")

finally:
conn.close() # Assurez-vous de fermer la connexion après utilisation

else:
logger.error("Échec de la connexion à la base de données.")
raise HTTPException(status_code=500, detail="Database connection failed.")

duration = time.time() - start_time
user_creation_duration_histogram.labels(status_code='201').observe(duration)
Expand Down Expand Up @@ -218,8 +252,11 @@ async def login_for_access_token(form_data: Annotated[OAuth2PasswordRequestForm,
return response

async def authenticate_user(email: str, password: str):
try:
with get_db_connection() as conn:
config = load_config()
conn = connect(config)

if conn is not None:
try:
with conn.cursor() as cur:
cur.execute(
"SELECT userid, username, email, hached_password FROM users WHERE email = %s",
Expand Down Expand Up @@ -247,11 +284,16 @@ async def authenticate_user(email: str, password: str):
logger.info(f"Valeur de userId dans authenticate_user: {user_data['userId']}")
return user_data

except psycopg2.Error as e:
error_counter.labels(error_type='database_error').inc()
logger.error(f"Erreur base de données: {str(e)}")
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
except psycopg2.Error as e:
error_counter.labels(error_type='database_error').inc()
logger.error(f"Erreur base de données: {str(e)}")
raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")

finally:
conn.close() # Assurez-vous de fermer la connexion après utilisation
else:
logger.error("Échec de la connexion à la base de données.")
raise HTTPException(status_code=500, detail="Database connection failed.")

# Fonction pour créer un token d'accès
def create_access_token(email: str, user_id: int, expires_delta: timedelta):
Expand All @@ -266,7 +308,10 @@ async def get_current_user(token: Annotated[str, Depends(oauth2_bearer)]):
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) # Décode le token
email: str = payload.get('sub') # Récupère le nom d'utilisateur
user_id: int = payload.get('id') # Récupère l'ID de l'utilisateur
with get_db_connection() as conn:
config = load_config()
conn = connect(config)

if conn is not None:
with conn.cursor() as cur:
cur.execute(
"SELECT userid, username FROM users WHERE userid = %s",
Expand Down
45 changes: 0 additions & 45 deletions docker/fastapi/database.py

This file was deleted.

Loading

0 comments on commit 312bae9

Please sign in to comment.