Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/api/stuff.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,5 @@ async def update_stuff(
db_session: AsyncSession = Depends(get_db),
):
stuff = await Stuff.find(db_session, name)
await stuff.update(db_session, **payload.model_dump())
await stuff.update(**payload.model_dump())
return stuff
1 change: 1 addition & 0 deletions app/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ async def get_db() -> AsyncGenerator:
# logger.debug(f"ASYNC Pool: {engine.pool.status()}")
try:
yield session
await session.commit()
except Exception as e:
await logger.aerror(f"Error getting database session: {e}")
raise
16 changes: 15 additions & 1 deletion app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

import asyncpg
from fastapi import Depends, FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from rotoger import AppStructLogger
from sqlalchemy.exc import SQLAlchemyError

from app.api.health import router as health_router
from app.api.ml import router as ml_router
Expand Down Expand Up @@ -61,6 +62,19 @@ def create_app() -> FastAPI:
dependencies=[Depends(AuthBearer())],
)

@app.exception_handler(SQLAlchemyError)
async def sqlalchemy_exception_handler(request: Request, exc: SQLAlchemyError):
await logger.aerror(
"A database error occurred",
sql_error=repr(exc),
request_url=request.url.path,
request_body=request.body,
)
return JSONResponse(
status_code=500,
content={"message": "A database error occurred. Please try again later."},
)

@app.get("/index", response_class=HTMLResponse)
def get_index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
Expand Down
38 changes: 10 additions & 28 deletions app/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,64 +20,46 @@ def __tablename__(self) -> str:
return self.__name__.lower()

async def save(self, db_session: AsyncSession):
"""

:param db_session:
:return:
"""
try:
db_session.add(self)
await db_session.commit()
await db_session.flush()
await db_session.refresh(self)
return self
except SQLAlchemyError as ex:
await logger.aerror(f"Error inserting instance of {self}: {repr(ex)}")
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=repr(ex)
) from ex
raise # This will make the exception handler catch it

async def delete(self, db_session: AsyncSession):
"""

:param db_session:
:return:
"""
try:
await db_session.delete(self)
await db_session.commit()
return True
except SQLAlchemyError as ex:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=repr(ex)
) from ex

async def update(self, db: AsyncSession, **kwargs):
"""

:param db:
:param kwargs
:return:
"""
async def update(self, **kwargs):
try:
for k, v in kwargs.items():
setattr(self, k, v)
return await db.commit()
return True
except SQLAlchemyError as ex:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=repr(ex)
) from ex

async def save_or_update(self, db: AsyncSession):
async def save_or_update(self, db_session: AsyncSession):
try:
db.add(self)
return await db.commit()
db_session.add(self)
await db_session.flush()
return True
except IntegrityError as exception:
if isinstance(exception.orig, UniqueViolationError):
return await db.merge(self)
return await db_session.merge(self)
else:
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
detail=repr(exception),
) from exception
finally:
await db.close()
await db_session.close()
4 changes: 3 additions & 1 deletion app/schemas/stuff.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@


class RandomStuff(BaseModel):
chaos: dict[str, Any] = Field(..., description="JSON data for chaos field")
chaos: dict[str, Any] = Field(
..., description="Pretty chaotic JSON data can be added here..."
)


class StuffSchema(BaseModel):
Expand Down
Empty file added tests/api/test_chaotic_stuff.py
Empty file.