correction des erreurs de déconnexion db

main
Anaz 2025-02-25 13:48:16 +04:00
parent 81a93c5683
commit 89436bd8f8
13 changed files with 312 additions and 242 deletions

View File

@ -1,7 +1,7 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from fastapi import APIRouter, Depends, Form, HTTPException, status, Body from fastapi import APIRouter, HTTPException, status, Body
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy import update, select from sqlalchemy import update, select
@ -10,7 +10,6 @@ from models.schemas import Token, UserCreate, UserResponse
from config.database import get_db from config.database import get_db
from models.db import users_table from models.db import users_table
from config.settings import settings from config.settings import settings
from sqlalchemy.ext.asyncio import AsyncSession
from jose import jwt, JWTError from jose import jwt, JWTError
from smtplib import SMTP from smtplib import SMTP
from services.user_service import UserService from services.user_service import UserService
@ -21,32 +20,33 @@ router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/signup", status_code=201, summary="User Signup") @router.post("/signup", status_code=201, summary="User Signup")
async def signup(user: UserCreate, db=Depends(get_db)): async def signup(user: UserCreate):
existing_user = await AuthService.get_user_by_email(user.email, db) async with get_db() as db:
if existing_user: existing_user = await AuthService.get_user_by_email(user.email, db)
raise HTTPException( if existing_user:
status_code=status.HTTP_400_BAD_REQUEST, raise HTTPException(
detail="Email already registered." status_code=status.HTTP_400_BAD_REQUEST,
) detail="Email already registered."
return await UserService.create_user(user, db) )
return await UserService.create_user(user, db)
@router.post("/token", response_model=Token, summary="Login and get access token") @router.post("/token", response_model=Token, summary="Login and get access token")
async def login_for_access_token( form_data: OAuth2PasswordRequestForm = Depends(), db=Depends(get_db)): async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Body(...)):
user = await AuthService.authenticate_user(form_data.username, form_data.password, db) async with get_db() as db:
logger.info(f"User {form_data.username} logged in") user = await AuthService.authenticate_user(form_data.username, form_data.password, db)
if not user: logger.info(f"User {form_data.username} logged in")
raise HTTPException( if not user:
status_code=status.HTTP_401_UNAUTHORIZED, raise HTTPException(
detail="Incorrect email or password", status_code=status.HTTP_401_UNAUTHORIZED,
headers={"WWW-Authenticate": "Bearer"}, detail="Incorrect email or password",
) headers={"WWW-Authenticate": "Bearer"},
access_token = AuthService.create_access_token(data={"sub": user["email"]}) )
return {"access_token": access_token, "token_type": "bearer"} access_token = AuthService.create_access_token(data={"sub": user["email"]})
return {"access_token": access_token, "token_type": "bearer"}
@router.post("/isvalid-token", summary="Verify token validity") @router.post("/isvalid-token", summary="Verify token validity")
async def verify_token(token: str = Body(...)): async def verify_token(token: str = Body(...)):
try: try:
# Décoder le token pour vérifier sa validité
payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm]) payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
return {"valid": True, "message": "Token is valid", "payload": payload} return {"valid": True, "message": "Token is valid", "payload": payload}
except jwt.ExpiredSignatureError: except jwt.ExpiredSignatureError:
@ -61,88 +61,86 @@ async def verify_token(token: str = Body(...)):
) )
@router.get("/me", summary="Get current user") @router.get("/me", summary="Get current user")
async def read_users_me(token:str = Depends(oauth2_scheme) , db=Depends(get_db)): async def read_users_me(token: str = Body(...)):
return await AuthService.get_current_user(token, db) async with get_db() as db:
return await AuthService.get_current_user(token, db)
@router.post("/reset-password") @router.post("/reset-password")
async def reset_password(token: str = Body(...), new_password: str = Body(...), db: AsyncSession = Depends(get_db)): async def reset_password(token: str = Body(...), new_password: str = Body(...)):
try: async with get_db() as db:
payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm]) try:
email = payload.get("sub") payload = jwt.decode(token, settings.secret_key, algorithms=[settings.algorithm])
if email is None: email = payload.get("sub")
raise HTTPException(status_code=400, detail="Invalid token") if email is None:
except JWTError: raise HTTPException(status_code=400, detail="Invalid token")
raise HTTPException(status_code=400, detail="Invalid or expired token") except JWTError:
raise HTTPException(status_code=400, detail="Invalid or expired token")
# Hash the new password hashed_password = pwd_context.hash(new_password)
hashed_password = pwd_context.hash(new_password)
# Update the user's password query = (
query = ( update(users_table)
update(users_table) .where(users_table.c.email == email)
.where(users_table.c.email == email) .values(hashed_password=hashed_password)
.values(hashed_password=hashed_password) .execution_options(synchronize_session="fetch")
.execution_options(synchronize_session="fetch") )
) await db.execute(query)
await db.execute(query)
await db.commit()
return JSONResponse(content={"message": "Password updated successfully."}) return JSONResponse(content={"message": "Password updated successfully."})
@router.post("/password-reset-request") @router.post("/password-reset-request")
async def password_reset_request(email: str, db: AsyncSession = Depends(get_db)): async def password_reset_request(email: str = Body(...)):
query = select(users_table).where(users_table.c.email == email) async with get_db() as db:
result = await db.execute(query) query = select(users_table).where(users_table.c.email == email)
user = result.fetchone() result = await db.execute(query)
if not user: user = result.fetchone()
raise HTTPException(status_code=404, detail="User not found") if not user:
raise HTTPException(status_code=404, detail="User not found")
# Générer un token JWT reset_token = jwt.encode(
reset_token = jwt.encode( {"sub": email, "exp": datetime.utcnow() + timedelta(hours=1)},
{"sub": email, "exp": datetime.utcnow() + timedelta(hours=1)}, settings.secret_key,
settings.secret_key, algorithm=settings.algorithm,
algorithm=settings.algorithm, )
)
reset_link = f"{settings.resetpass_url}/?token={reset_token}" reset_link = f"{settings.resetpass_url}/?token={reset_token}"
# Envoyer le lien par email try:
try: subject = "mot de passe perdu"
subject = "mot de passe perdu" sender_email = settings.email_username
sender_email = settings.email_username receiver_email = email
receiver_email = email logger.info(f"sender {settings.email_username} receiver {email}")
logger.info(f"sender {settings.email_username} receiver {email}")
message = MIMEMultipart("alternative") message = MIMEMultipart("alternative")
message["Subject"] = subject message["Subject"] = subject
message["From"] = sender_email message["From"] = sender_email
message["To"] = receiver_email message["To"] = receiver_email
text = f"You requested a password reset. Click the link below to reset your password:\n{reset_link}" text = f"You requested a password reset. Click the link below to reset your password:\n{reset_link}"
html = f""" html = f"""
<html> <html>
<body> <body>
<p>You requested a password reset.<br> <p>You requested a password reset.<br>
Click the link below to reset your password:<br> Click the link below to reset your password:<br>
<a href="{reset_link}">Redefinir mon mot de passe</a> <a href="{reset_link}">Redefinir mon mot de passe</a>
</p> </p>
</body> </body>
</html> </html>
""" """
part1 = MIMEText(text, "plain") part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html") part2 = MIMEText(html, "html")
message.attach(part1) message.attach(part1)
message.attach(part2) message.attach(part2)
with SMTP(settings.email_host, settings.email_port) as server: with SMTP(settings.email_host, settings.email_port) as server:
server.starttls() server.starttls()
server.login(settings.email_username, settings.email_password) server.login(settings.email_username, settings.email_password)
server.sendmail(sender_email, receiver_email, message.as_string()) server.sendmail(sender_email, receiver_email, message.as_string())
logger.info(f"Password reset email sent to {email}") logger.info(f"Password reset email sent to {email}")
return JSONResponse(content={"message": "Password reset link sent via email."}) return JSONResponse(content={"message": "Password reset link sent via email."})
except Exception as e: except Exception as e:
logger.error(f"Failed to send password reset email to {email}: {str(e)}") logger.error(f"Failed to send password reset email to {email}: {str(e)}")
raise HTTPException(status_code=500, detail=f"Failed to send password reset email. sender {sender_email} receiver {receiver_email}") raise HTTPException(status_code=500, detail=f"Failed to send password reset email. sender {sender_email} receiver {receiver_email}")

View File

@ -6,5 +6,6 @@ from config.database import get_db
router = APIRouter() router = APIRouter()
@router.post("/", status_code=201) @router.post("/", status_code=201)
async def report_issue(issue: TechnicalIssue, db=Depends(get_db)): async def report_issue(issue: TechnicalIssue):
return await MessageService.create_issue(issue, db) async with get_db() as db:
return await MessageService.create_issue(issue, db)

View File

@ -11,62 +11,58 @@ router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/", status_code=status.HTTP_201_CREATED) @router.post("/", status_code=status.HTTP_201_CREATED)
async def request_need(need: NeedRequestCreate, db=Depends(get_db)): async def request_need(need: NeedRequestCreate):
async with get_db() as db:
return await NeedRequestService.create_need(need, db) return await NeedRequestService.create_need(need, db)
@router.get("/", status_code=status.HTTP_200_OK) @router.get("/", status_code=status.HTTP_200_OK)
async def get_all_reports(db=Depends(get_db)): async def get_all_reports():
return await NeedRequestService.get_all_needs(db) async with get_db() as db:
return await NeedRequestService.get_all_needs(db)
@router.get("/{need_id}", status_code=status.HTTP_200_OK) @router.get("/{need_id}", status_code=status.HTTP_200_OK)
async def get_need(need_id: int, db=Depends(get_db)): async def get_need(need_id: int):
async with get_db() as db:
need = await NeedRequestService.get_need(need_id, db) need = await NeedRequestService.get_need(need_id, db)
if not need: if not need:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found") raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
return need return need
@router.put("/{need_id}", status_code=status.HTTP_200_OK) @router.put("/{need_id}", status_code=status.HTTP_200_OK)
async def update_need( async def update_need(
need_id: int, need_id: int,
need_update: NeedRequestUpdate, need_update: NeedRequestUpdate,
token: str = Depends(oauth2_scheme), token: str = Depends(oauth2_scheme)
db=Depends(get_db),
): ):
async with get_db() as db:
need = await NeedRequestService.get_need(need_id, db)
if not need:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
need = await NeedRequestService.get_need(need_id, db) # Vérifie si l'utilisateur est l'auteur ou un administrateur
if not need: if NeedRequestService.verify_requester_or_admin(need_id, token, db):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found") raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
# V<>rifie si l'utilisateur est l'auteur ou un administrateur detail="You do not have permission to update this need request",
if NeedRequestService.verify_requester_or_admin(need_id, token, db): )
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You do not have permission to update this need request",
)
return await NeedRequestService.update_need(need_id, need_update, db)
return await NeedRequestService.update_need(need_id, need_update, db)
@router.delete("/{need_id}", status_code=status.HTTP_200_OK) @router.delete("/{need_id}", status_code=status.HTTP_200_OK)
async def delete_need( async def delete_need(
need_id: int, need_id: int,
token: str = Depends(oauth2_scheme), token: str = Depends(oauth2_scheme)
db=Depends(get_db),
): ):
async with get_db() as db:
need = await NeedRequestService.get_need(need_id, db)
if not need:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found")
need = await NeedRequestService.get_need(need_id, db) # Vérifie si l'utilisateur est l'auteur ou un administrateur
if not need: if NeedRequestService.verify_requester_or_admin(need_id, token, db):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Need request not found") raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You do not have permission to delete this need request",
)
# V<>rifie si l'utilisateur est l'auteur ou un administrateur return await NeedRequestService.delete_need(need_id, db)
if NeedRequestService.verify_requester_or_admin(need_id, token, db):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="You do not have permission to delete this need request",
)
return await NeedRequestService.delete_need(need_id, db)

View File

@ -13,31 +13,34 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/", status_code=201) @router.post("/", status_code=201)
async def create_report( async def create_report(
file: Optional[UploadFile] = File(None), # Le champ photo est reçu sous forme de fichier file: Optional[UploadFile] = File(None),
report: PersonReportCreate = Form(...), # Le champ report est reçu sous forme de chaîne JSON report: PersonReportCreate = Form(...),
db: get_db = Depends(),
token: str = Depends(oauth2_scheme) token: str = Depends(oauth2_scheme)
): ):
# Appeler le service pour traiter le rapport async with get_db() as db:
try: try:
created_report = await PersonReportService.create_report(report, db, token, file) created_report = await PersonReportService.create_report(report, db, token, file)
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail=f"An error occurred while creating the report: {str(e)}") raise HTTPException(status_code=500, detail=f"An error occurred while creating the report: {str(e)}")
return created_report return created_report
@router.put("/{report_id}") @router.put("/{report_id}")
async def update_report(report_id: int, report: PersonReportUpdate, db=Depends(get_db)): async def update_report(report_id: int, report: PersonReportUpdate):
return await PersonReportService.update_report(report_id, report, db) async with get_db() as db:
return await PersonReportService.update_report(report_id, report, db)
@router.get("/{report_id}") @router.get("/{report_id}")
async def get_report(report_id: int, db=Depends(get_db)): async def get_report(report_id: int):
return await PersonReportService.get_report(report_id, db) async with get_db() as db:
return await PersonReportService.get_report(report_id, db)
@router.get("/", response_model=list[PersonReportResponse]) @router.get("/", response_model=list[PersonReportResponse])
async def list_reports(status: Optional[str] = None, db=Depends(get_db)): async def list_reports(status: Optional[str] = None):
return await PersonReportService.list_reports(status, db) async with get_db() as db:
return await PersonReportService.list_reports(status, db)
@router.delete("/{report_id}", status_code=204) @router.delete("/{report_id}", status_code=204)
async def delete_report(report_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def delete_report(report_id: int, token: str = Depends(oauth2_scheme)):
return await PersonReportService.delete_report(report_id, db, token) async with get_db() as db:
return await PersonReportService.delete_report(report_id, db, token)

View File

@ -8,25 +8,26 @@ router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/", status_code=201) @router.post("/", status_code=201)
async def create_point(point: CreatePointOfInterest, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def create_point(point: CreatePointOfInterest, token: str = Depends(oauth2_scheme)):
return await PointsOfInterestService.create_point_of_interest(point, db, token) async with get_db() as db:
return await PointsOfInterestService.create_point_of_interest(point, db, token)
@router.get("/{point_id}") @router.get("/{point_id}")
async def get_point(point_id: int, db=Depends(get_db)): async def get_point(point_id: int):
return await PointsOfInterestService.get_point_of_interest(point_id, db) async with get_db() as db:
return await PointsOfInterestService.get_point_of_interest(point_id, db)
@router.get("/") @router.get("/")
async def get_all_points(db=Depends(get_db)): async def get_all_points():
return await PointsOfInterestService.get_all_points_of_interest(db) async with get_db() as db:
return await PointsOfInterestService.get_all_points_of_interest(db)
@router.put("/{point_id}") @router.put("/{point_id}")
async def update_point(point_id: int, point: UpdatePointOfInterest, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def update_point(point_id: int, point: UpdatePointOfInterest, token: str = Depends(oauth2_scheme)):
return await PointsOfInterestService.update_point_of_interest(point_id, point, db, token) async with get_db() as db:
return await PointsOfInterestService.update_point_of_interest(point_id, point, db, token)
@router.delete("/{point_id}") @router.delete("/{point_id}")
async def delete_point(point_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def delete_point(point_id: int, token: str = Depends(oauth2_scheme)):
return await PointsOfInterestService.delete_point_of_interest(point_id, db, token) async with get_db() as db:
return await PointsOfInterestService.delete_point_of_interest(point_id, db, token)

View File

@ -10,21 +10,26 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
router = APIRouter() router = APIRouter()
@router.post("/", status_code=status.HTTP_201_CREATED) @router.post("/", status_code=status.HTTP_201_CREATED)
async def report_user(report: UserReport, db=Depends(get_db)): async def report_user(report: UserReport):
return await ReportService.create_report(report, db) async with get_db() as db:
return await ReportService.create_report(report, db)
@router.get("/{report_id}", status_code=status.HTTP_200_OK) @router.get("/{report_id}", status_code=status.HTTP_200_OK)
async def get_report(report_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def get_report(report_id: int, token: str = Depends(oauth2_scheme)):
return await ReportService.get_report_by_id(report_id, db, token) async with get_db() as db:
return await ReportService.get_report_by_id(report_id, db, token)
@router.get("/", status_code=status.HTTP_200_OK) @router.get("/", status_code=status.HTTP_200_OK)
async def get_all_reports(db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def get_all_reports(token: str = Depends(oauth2_scheme)):
return await ReportService.get_all_reports(db, token) async with get_db() as db:
return await ReportService.get_all_reports(db, token)
@router.put("/{report_id}", status_code=status.HTTP_200_OK) @router.put("/{report_id}", status_code=status.HTTP_200_OK)
async def update_report(report_id: int, report_update: UserReportUpdate, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def update_report(report_id: int, report_update: UserReportUpdate, token: str = Depends(oauth2_scheme)):
return await ReportService.update_report(report_id, report_update, db, token) async with get_db() as db:
return await ReportService.update_report(report_id, report_update, db, token)
@router.delete("/{report_id}", status_code=status.HTTP_200_OK) @router.delete("/{report_id}", status_code=status.HTTP_200_OK)
async def delete_report(report_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def delete_report(report_id: int, token: str = Depends(oauth2_scheme)):
return await ReportService.delete_report(report_id, db, token) async with get_db() as db:
return await ReportService.delete_report(report_id, db, token)

View File

@ -9,50 +9,50 @@ from typing import List
router = APIRouter() router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/", status_code=201) @router.post("/", status_code=201)
async def create_role(name: str, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)): async def create_role(name: str, token: str = Depends(oauth2_scheme)):
""" """
Créer un nouveau rôle avec des permissions associées (réservé aux administrateurs). Créer un nouveau rôle avec des permissions associées (réservé aux administrateurs).
""" """
return await RoleService.create_role(name, db, token) async with get_db() as db:
return await RoleService.create_role(name, db, token)
@router.get("/{role_id}", response_model=Role) @router.get("/{role_id}", response_model=Role)
async def get_role(role_id: int, db: AsyncSession = Depends(get_db)): async def get_role(role_id: int):
""" """
Récupérer les détails d'un rôle spécifique. Récupérer les détails d'un rôle spécifique.
""" """
return await RoleService.get_role(role_id, db) async with get_db() as db:
return await RoleService.get_role(role_id, db)
@router.get("/", response_model=List[Role]) @router.get("/", response_model=List[Role])
async def get_all_roles(db: AsyncSession = Depends(get_db)): async def get_all_roles():
""" """
Récupérer tous les rôles avec leurs permissions associées. Récupérer tous les rôles avec leurs permissions associées.
""" """
return await RoleService.get_all_roles(db) async with get_db() as db:
return await RoleService.get_all_roles(db)
@router.put("/{role_id}") @router.put("/{role_id}")
async def update_role(role_id: int, role: Role, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)): async def update_role(role_id: int, role: Role, token: str = Depends(oauth2_scheme)):
""" """
Mettre à jour un rôle existant (réservé aux administrateurs). Mettre à jour un rôle existant (réservé aux administrateurs).
""" """
return await RoleService.update_role(role_id, role.dict(), db, token) async with get_db() as db:
return await RoleService.update_role(role_id, role.dict(), db, token)
@router.delete("/{role_id}") @router.delete("/{role_id}")
async def delete_role(role_id: int, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)): async def delete_role(role_id: int, token: str = Depends(oauth2_scheme)):
""" """
Supprimer un rôle (réservé aux administrateurs). Supprimer un rôle (réservé aux administrateurs).
""" """
return await RoleService.delete_role(role_id, db, token) async with get_db() as db:
return await RoleService.delete_role(role_id, db, token)
@router.get("/roles/permissions", response_model=List[Permission]) @router.get("/roles/permissions", response_model=List[Permission])
async def get_all_permissions(db: AsyncSession = Depends(get_db)): async def get_all_permissions():
""" """
Récupérer toutes les permissions disponibles. Récupérer toutes les permissions disponibles.
""" """
return await RoleService.get_all_permissions(db) async with get_db() as db:
return await RoleService.get_all_permissions(db)

View File

@ -8,25 +8,26 @@ router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/", status_code=201) @router.post("/", status_code=201)
async def create_shelter(shelter: CreateShelter, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def create_shelter(shelter: CreateShelter, token: str = Depends(oauth2_scheme)):
return await ShelterService.create_shelter(shelter, db, token) async with get_db() as db:
return await ShelterService.create_shelter(shelter, db, token)
@router.get("/{shelter_id}") @router.get("/{shelter_id}")
async def get_shelter(shelter_id: int, db=Depends(get_db)): async def get_shelter(shelter_id: int):
return await ShelterService.get_shelter(shelter_id, db) async with get_db() as db:
return await ShelterService.get_shelter(shelter_id, db)
@router.get("/") @router.get("/")
async def get_all_shelters(db=Depends(get_db)): async def get_all_shelters():
return await ShelterService.get_all_shelters(db) async with get_db() as db:
return await ShelterService.get_all_shelters(db)
@router.put("/{shelter_id}") @router.put("/{shelter_id}")
async def update_shelter(shelter_id: int, shelter: UpdateShelter, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def update_shelter(shelter_id: int, shelter: UpdateShelter, token: str = Depends(oauth2_scheme)):
return await ShelterService.update_shelter(shelter_id, shelter, db, token) async with get_db() as db:
return await ShelterService.update_shelter(shelter_id, shelter, db, token)
@router.delete("/{shelter_id}") @router.delete("/{shelter_id}")
async def delete_shelter(shelter_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def delete_shelter(shelter_id: int, token: str = Depends(oauth2_scheme)):
return await ShelterService.delete_shelter(shelter_id, db, token) async with get_db() as db:
return await ShelterService.delete_shelter(shelter_id, db, token)

View File

@ -9,21 +9,26 @@ router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/", status_code=201) @router.post("/", status_code=201)
async def create_issue(issue: CreateTechnicalIssue, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def create_issue(issue: CreateTechnicalIssue, token: str = Depends(oauth2_scheme)):
return await TechnicalIssueService.create_issue(issue, db, token) async with get_db() as db:
return await TechnicalIssueService.create_issue(issue, db, token)
@router.get("/{issue_id}") @router.get("/{issue_id}")
async def get_issue(issue_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def get_issue(issue_id: int, token: str = Depends(oauth2_scheme)):
return await TechnicalIssueService.get_issue(issue_id, db, token) async with get_db() as db:
return await TechnicalIssueService.get_issue(issue_id, db, token)
@router.get("/") @router.get("/")
async def get_all_issues(db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def get_all_issues(token: str = Depends(oauth2_scheme)):
return await TechnicalIssueService.get_all_issues(db, token) async with get_db() as db:
return await TechnicalIssueService.get_all_issues(db, token)
@router.put("/{issue_id}") @router.put("/{issue_id}")
async def update_issue(issue_id: int, issue_data: UpdateTechnicalIssue, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def update_issue(issue_id: int, issue_data: UpdateTechnicalIssue, token: str = Depends(oauth2_scheme)):
return await TechnicalIssueService.update_issue(issue_id, issue_data, db, token) async with get_db() as db:
return await TechnicalIssueService.update_issue(issue_id, issue_data, db, token)
@router.delete("/{issue_id}") @router.delete("/{issue_id}")
async def delete_issue(issue_id: int, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def delete_issue(issue_id: int, token: str = Depends(oauth2_scheme)):
return await TechnicalIssueService.delete_issue(issue_id, db, token) async with get_db() as db:
return await TechnicalIssueService.delete_issue(issue_id, db, token)

View File

@ -10,7 +10,8 @@ router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.post("/") @router.post("/")
async def upload_file(file: UploadFile, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def upload_file(file: UploadFile, token: str = Depends(oauth2_scheme)):
user = await AuthService.get_current_user(token, db) async with get_db() as db:
logger.info(f"User {user} is uploading a file") user = await AuthService.get_current_user(token, db)
return await UploadService.upload_image_to_s3(file, user["id"]) logger.info(f"User {user} is uploading a file")
return await UploadService.upload_image_to_s3(file, user["id"])

View File

@ -1,6 +1,5 @@
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer from fastapi.security import OAuth2PasswordBearer
from sqlalchemy.ext.asyncio import AsyncSession
from services.user_service import UserService from services.user_service import UserService
from models.schemas import UserUpdateRole, UserBlockBan, UserResponse from models.schemas import UserUpdateRole, UserBlockBan, UserResponse
from config.database import get_db from config.database import get_db
@ -11,29 +10,36 @@ router = APIRouter()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/token")
@router.get("/", response_model=list[UserResponse]) @router.get("/", response_model=list[UserResponse])
async def list_users(status: Optional[str] = None, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def list_users(status: Optional[str] = None, token: str = Depends(oauth2_scheme)):
return await UserService.list_users(token, status, db) async with get_db() as db:
return await UserService.list_users(token, status, db)
@router.patch("/role", status_code=200) @router.patch("/role", status_code=200)
async def change_role(user_update: UserUpdateRole, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)): async def change_role(user_update: UserUpdateRole, token: str = Depends(oauth2_scheme)):
return await UserService.change_user_role(user_update, db, token) async with get_db() as db:
return await UserService.change_user_role(user_update, db, token)
@router.post("/block", status_code=200) @router.post("/block", status_code=200)
async def block_user(user_action: UserBlockBan, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)): async def block_user(user_action: UserBlockBan, token: str = Depends(oauth2_scheme)):
return await UserService.block_user(user_action, db, token) async with get_db() as db:
return await UserService.block_user(user_action, db, token)
@router.post("/ban", status_code=200) @router.post("/ban", status_code=200)
async def ban_user(user_action: UserBlockBan, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)): async def ban_user(user_action: UserBlockBan, token: str = Depends(oauth2_scheme)):
return await UserService.ban_user(user_action, db, token) async with get_db() as db:
return await UserService.ban_user(user_action, db, token)
@router.post("/unblock", status_code=200) @router.post("/unblock", status_code=200)
async def unblock_user(user_action: UserBlockBan, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)): async def unblock_user(user_action: UserBlockBan, token: str = Depends(oauth2_scheme)):
return await UserService.unblock_user(user_action, db, token) async with get_db() as db:
return await UserService.unblock_user(user_action, db, token)
@router.post("/unban", status_code=200) @router.post("/unban", status_code=200)
async def unban_user(user_action: UserBlockBan, db: AsyncSession = Depends(get_db), token: str = Depends(oauth2_scheme)): async def unban_user(user_action: UserBlockBan, token: str = Depends(oauth2_scheme)):
return await UserService.unban_user(user_action, db, token) async with get_db() as db:
return await UserService.unban_user(user_action, db, token)
@router.get("/getuserbymail", response_model=UserResponse) @router.get("/getuserbymail", response_model=UserResponse)
async def get_user_by_email(email: str, db=Depends(get_db), token: str = Depends(oauth2_scheme)): async def get_user_by_email(email: str, token: str = Depends(oauth2_scheme)):
return await UserService.get_user_by_email(email, db, token) async with get_db() as db:
return await UserService.get_user_by_email(email, db, token)

View File

@ -1,14 +1,46 @@
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from sqlalchemy.exc import SQLAlchemyError
from config.settings import settings from config.settings import settings
import logging import logging
from contextlib import asynccontextmanager
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
DATABASE_URL = settings.database_url DATABASE_URL = settings.database_url
engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False) # Configuration optimisée du moteur
engine = create_async_engine(
DATABASE_URL,
echo=True,
pool_size=5,
max_overflow=10,
pool_timeout=30,
pool_recycle=1800,
pool_pre_ping=True
)
AsyncSessionLocal = sessionmaker(
engine,
class_=AsyncSession,
expire_on_commit=False,
autocommit=False,
autoflush=False
)
@asynccontextmanager
async def get_db():
session = AsyncSessionLocal()
try:
yield session
await session.commit()
except SQLAlchemyError as e:
await session.rollback()
logger.error(f"Database error: {str(e)}")
raise
finally:
await session.close()
async def init_db(): async def init_db():
from models.db import metadata from models.db import metadata
@ -18,8 +50,4 @@ async def init_db():
logger.info("Database tables created successfully.") logger.info("Database tables created successfully.")
except Exception as e: except Exception as e:
logger.error(f"Error creating database tables: {str(e)}") logger.error(f"Error creating database tables: {str(e)}")
raise raise
async def get_db():
async with AsyncSessionLocal() as session:
yield session

25
config/database.txt Normal file
View File

@ -0,0 +1,25 @@
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from config.settings import settings
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
DATABASE_URL = settings.database_url
engine = create_async_engine(DATABASE_URL, echo=True)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
async def init_db():
from models.db import metadata
try:
async with engine.begin() as conn:
await conn.run_sync(metadata.create_all)
logger.info("Database tables created successfully.")
except Exception as e:
logger.error(f"Error creating database tables: {str(e)}")
raise
async def get_db():
async with AsyncSessionLocal() as session:
yield session