from fastapi import FastAPI, Depends, Request, HTTPException, status from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse from sqlalchemy.orm import Session import uvicorn import database import models import crud import schemas app = FastAPI() convert_422_to_400 = True if convert_422_to_400: # Taken from there. # https://stackoverflow.com/questions/75958222/can-i-return-400-error-instead-of-422-error # https://stackoverflow.com/questions/71681068/how-to-customise-error-response-for-a-specific-route-in-fastapi @app.exception_handler(RequestValidationError) async def validation_exception_handler( request: Request, exc: RequestValidationError ): return JSONResponse( status_code=status.HTTP_400_BAD_REQUEST, content={"detail": exc.errors()}, ) # Dependency def get_db(): db = database.SessionLocal() try: yield db finally: db.close() @app.get("/") async def root(): return {"message": "Hello World"} @app.post("/pydantic_movies/") async def create_movie(payload: schemas.MoviePayload, db: Session = Depends(get_db)): movie = crud.create_movie(db, **payload.dict()) out = {"message": f"Created {movie.title} XX", "id": movie.id} return out @app.post("/movies/") async def create_movie( name: str = "", db: Session = Depends(get_db), request: Request = None ): out = {} try: # Bypass for dev data = await request.json() except: data = {} crud_params = dict( genres=data.get("genres", ["Unknown"]), description=data.get("description", ""), title=data.get("title", ""), vote_average=data.get("vote_average"), vote_count=data.get("vote_count"), ) movie = crud.create_movie(db, **crud_params) out = {"message": f"Created {movie.title} XX", "id": movie.id} return out @app.put("/movies/{id_}") async def update_movie( id_: str, db: Session = Depends(get_db), request: Request = None ): try: movie = crud.get_movie_by_id(db, id_) except LookupError: raise HTTPException(status_code=404, detail=f"No movie found with id {id_}") try: # Bypass for dev data = await request.json() except: data = {} crud_params = dict( genres=data.get("genres", ["Unknown"]), description=data.get("description", ""), title=data.get("title", ""), vote_average=data.get("vote_average"), vote_count=data.get("vote_count"), ) movie = crud.update_movie(db, id_, **crud_params) out = {k: v for (k, v) in movie.__dict__.items() if not k.startswith("_")} return out @app.get("/movies/{id_}") async def get_movie(id_: str, db: Session = Depends(get_db)): try: movie = crud.get_movie_by_id(db, id_) out = {k: v for (k, v) in movie.__dict__.items() if not k.startswith("_")} except LookupError: raise HTTPException(status_code=404, detail=f"No movie found with id {id_}") else: return out @app.delete("/movies/{id_}", status_code=status.HTTP_204_NO_CONTENT) async def delete_movie(id_: str, db: Session = Depends(get_db)): try: movie = crud.delete_movie_by_id(db, id_) except LookupError: raise HTTPException(status_code=404, detail=f"No movie found with id {id_}") @app.get("/movies/") async def list_movie(db: Session = Depends(get_db)): movies = crud.get_all_movies(db) out = [ {k: v for (k, v) in movie.__dict__.items() if not k.startswith("_")} for movie in movies ] return out if __name__ == "__main__": database.create_db() uvicorn.run(app, host="127.0.0.1", port=5000)