📝 Added all responses codes to automatic documentation, fixed some output sample values and fixed the TODO for user search

nominatim_fix
Alix JEUDI--LEMOINE 7 months ago
parent 401d4d8385
commit c993d2f1af

@ -0,0 +1,5 @@
from pydantic import BaseModel
class UserDTO(BaseModel):
uid: str
username: str

@ -1,3 +1,4 @@
from .UserRegisterDTO import UserRegisterDTO
from .FriendAddDTO import FriendAddDTO
from .FriendListDTO import FriendListDTO
from .FriendListDTO import FriendListDTO
from .UserDTO import UserDTO

@ -1,8 +1,8 @@
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.responses import JSONResponse
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from typing import Optional
from datetime import datetime, timedelta
from pymongo import MongoClient
from jose import JWTError, jwt
from bson.objectid import ObjectId
from app.utils import get_password_hash, verify_password
@ -20,8 +20,10 @@ from app.dto import *
# Contains all constants
from app.config import *
import pymongo
# Database setup
client = MongoClient(MONGODB_URL, username=MONGODB_USERNAME, password=MONGODB_PASSWORD)
client = pymongo.MongoClient(MONGODB_URL, username=MONGODB_USERNAME, password=MONGODB_PASSWORD)
db = client[MONGODB_DATABASE]
# FastAPI app instance
@ -73,7 +75,11 @@ async def get_current_user(token: str = Depends(oauth2_scheme)) -> User:
# Routes - TODO: find workaround to display 401/409/... HTTP error codes in openapi.json
@app.post("/register", response_model=Token)
@app.post(
path="/register",
response_model=Token,
responses={409: {"model": Message}}
)
async def register(user: UserRegisterDTO):
user_exists = users_collection.find_one({"username": user.username})
if user_exists:
@ -90,7 +96,11 @@ async def register(user: UserRegisterDTO):
return {"access_token": access_token, "token_type": "bearer", "user_id": str(user["_id"])}
@app.post("/login", response_model=Token)
@app.post(
path="/login",
response_model=Token,
responses={401: {"model": Message}}
)
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
user = users_collection.find_one({"username": form_data.username})
if not user or not verify_password(form_data.password, user["password"]):
@ -105,12 +115,18 @@ async def login(form_data: OAuth2PasswordRequestForm = Depends()):
return {"access_token": access_token, "token_type": "bearer", "user_id": str(user["_id"])}
@app.get("/logout")
@app.get(
path="/logout",
responses={401: {"model": Message}}
)
async def logout(current_user: User = Depends(get_current_user)):
# TODO: find usecase / what to do ??
return {"message": "Logged out"}
@app.get("/pin/{id}")
@app.get(
path="/pin/{id}",
responses={401: {"model": Message}, 404: {"model": Message}}
)
async def get_pin(id: str, current_user: User = Depends(get_current_user)):
pin = pins_collection.find_one({"_id": ObjectId(id)})
if pin is None:
@ -118,7 +134,10 @@ async def get_pin(id: str, current_user: User = Depends(get_current_user)):
return pin
@app.patch("/pin/{id}")
@app.patch(
path="/pin/{id}",
responses={401: {"model": Message}, 404: {"model": Message}}
)
async def update_pin(id: str, pin: Pin, current_user: User = Depends(get_current_user)):
result = pins_collection.update_one({"_id": ObjectId(id)}, {"$set": pin.model_dump()})
if result.matched_count == 0:
@ -126,17 +145,26 @@ async def update_pin(id: str, pin: Pin, current_user: User = Depends(get_current
return {"message": "Pin updated"}
@app.post("/pin/add")
@app.post(
path="/pin/add",
responses={401: {"model": Message}}
)
async def add_pin(pin: Pin, current_user: User = Depends(get_current_user)):
pin_id = pins_collection.insert_one(pin.model_dump()).inserted_id
return {"id": str(pin_id)}
@app.get("/pins")
@app.get(
path="/pins",
responses={401: {"model": Message}}
)
async def list_pins(current_user: User = Depends(get_current_user)):
pins = pins_serialize(pins_collection.find().to_list())
return pins
@app.get("/friend/{id}")
@app.get(
path="/friend/{id}",
responses={401: {"model": Message}, 404: {"model": Message}}
)
async def get_friend(id: str, current_user: User = Depends(get_current_user)):
friend = friends_collection.find_one({"_id": ObjectId(id)})
if friend is None:
@ -144,7 +172,10 @@ async def get_friend(id: str, current_user: User = Depends(get_current_user)):
return friend
@app.post("/friend/add")
@app.post(
path="/friend/add",
responses={401: {"model": Message}, 409: {"model": Message}}
)
async def add_friend(friendAdd: FriendAddDTO, current_user: User = Depends(get_current_user)):
# TODO: test if exists
friend: Friend = friendAdd.model_dump()
@ -161,7 +192,10 @@ async def add_friend(friendAdd: FriendAddDTO, current_user: User = Depends(get_c
friend_id = friends_collection.insert_one(friend).inserted_id
return {"id": str(friend_id)}
@app.delete("/friend/{id}/delete")
@app.delete(
path="/friend/{id}/delete",
responses={401: {"model": Message}, 404: {"model": Message}}
)
async def delete_friend(id: str, current_user: User = Depends(get_current_user)):
result = friends_collection.delete_one({"_id": ObjectId(id)})
if result.deleted_count == 0:
@ -169,7 +203,10 @@ async def delete_friend(id: str, current_user: User = Depends(get_current_user))
return {"message": "Friend deleted"}
@app.patch("/friend/{id}/accept")
@app.patch(
path="/friend/{id}/accept",
responses={401: {"model": Message}, 404: {"model": Message}}
)
async def accept_friend(id: str, current_user: User = Depends(get_current_user)):
result = friends_collection.update_one({"_id": ObjectId(id)}, {"$set": {"status": "accepted"}})
if result.matched_count == 0:
@ -177,7 +214,10 @@ async def accept_friend(id: str, current_user: User = Depends(get_current_user))
return {"message": "Friend request accepted"}
@app.post("/friend/{id}/deny")
@app.post(
path="/friend/{id}/deny",
responses={401: {"model": Message}, 404: {"model": Message}}
)
async def deny_friend(id: str, current_user: User = Depends(get_current_user)):
result = friends_collection.update_one({"_id": ObjectId(id)}, {"$set": {"status": "denied"}})
if result.matched_count == 0:
@ -185,12 +225,23 @@ async def deny_friend(id: str, current_user: User = Depends(get_current_user)):
return {"message": "Friend request denied"}
@app.get("/friends", response_model=FriendListDTO)
@app.get(
path="/friends",
response_model=FriendListDTO,
responses={401: {"model": Message}}
)
async def list_friends(current_user: User = Depends(get_current_user)):
return FriendListDTO(**friends_serialize(friends_collection.find({"user_id": current_user.uid}).to_list(), friends_collection.find({"friend_user_id": current_user.uid})))
@app.get("/users")
@app.get(
path="/users",
responses={401: {"model": Message}, 422: {"model": Message}},
response_model=list[UserDTO]
)
async def search_users(name: str, current_user: User = Depends(get_current_user)):
# TODO: /!\ pymongo.errors.OperationFailure if regex is poop
users = users_serialize(users_collection.find({"username": {"$regex": name, "$options": "i"}}).to_list())
try:
users = users_serialize(users_collection.find({"username": {"$regex": name, "$options": "i"}}).to_list())
except pymongo.errors.OperationFailure:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Regex may be wrongly formatted")
return users

@ -2,4 +2,5 @@ from .friend import Friend
from .pin import Pin
from .token_data import TokenData
from .token import Token
from .user import User
from .user import User
from .message import Message

@ -0,0 +1,5 @@
from pydantic import BaseModel
class Message(BaseModel):
detail: str

@ -1,11 +1,12 @@
from app.dto.UserDTO import UserDTO
from app.models.user import User
def users_serialize(users: list) -> list:
def users_serialize(users: list) -> list[UserDTO]:
serialized_users: list = []
for user in users:
serialized_users.append({
"id": str(user["_id"]),
"uid": str(user["_id"]),
"username": user["username"]
})
return serialized_users

Loading…
Cancel
Save