Files
apilog/app/routes/entry.py

127 lines
3.8 KiB
Python

from datetime import datetime
from typing import Callable
from uuid import UUID
from creyPY.fastapi.crud import create_obj_from_data
from creyPY.fastapi.db.session import get_db
from creyPY.fastapi.order_by import order_by
from creyPY.fastapi.pagination import Page, paginate
from fastapi import APIRouter, Depends, HTTPException, Security
from fastapi_filters import FilterValues, create_filters
from fastapi_filters.ext.sqlalchemy import apply_filters
from pydantic.json_schema import SkipJsonSchema
from sqlalchemy import select
from sqlalchemy.orm import Session
from sqlalchemy.sql.selectable import Select
from app.models.entry import LogEntry, LogType, TransactionType
from app.schema.entry import LogIN, LogOUT
from app.services.auth import verify
router = APIRouter(prefix="/log", tags=["logging"])
@router.post("/", status_code=201)
async def create_log(
data: LogIN,
sub: str = Security(verify),
db: Session = Depends(get_db),
) -> LogOUT:
obj = create_obj_from_data(
data,
LogEntry,
db,
additional_data={"created_by_id": sub},
)
return LogOUT.model_validate(obj)
@router.delete("/{log_id}", status_code=204)
async def delete_log(
log_id: UUID,
sub: str = Security(verify),
db: Session = Depends(get_db),
) -> None:
obj = db.query(LogEntry).filter_by(id=log_id, created_by_id=sub).one_or_none()
if obj is None:
raise HTTPException(status_code=404, detail="Item not found")
db.delete(obj)
db.commit()
return None
@router.get("/{log_id}")
async def get_log(
log_id: UUID,
sub: str = Security(verify),
db: Session = Depends(get_db),
) -> LogOUT:
obj = db.query(LogEntry).filter_by(id=log_id, created_by_id=sub).one_or_none()
if obj is None:
raise HTTPException(status_code=404, detail="Item not found")
return LogOUT.model_validate(obj)
@router.get("/")
async def get_logs(
search: str | SkipJsonSchema[None] = None,
order_by_query: Callable[[Select], Select] = Depends(order_by),
filters: FilterValues = Depends(
create_filters(
created_by_id=str,
environment=str,
l_type=LogType,
t_type=TransactionType,
application=UUID,
object_reference=str,
author=str,
created_at=datetime,
)
),
sub: str = Security(verify),
db: Session = Depends(get_db),
) -> Page[LogOUT]:
"""
Filter logs of your systems. Searching works only for author and message. Use filters for the rest.
"""
the_select = apply_filters(select(LogEntry).filter(LogEntry.created_by_id == sub), filters)
if search:
the_select = the_select.filter(
LogEntry.message.ilike(f"%{search}%") | LogEntry.author.ilike(f"%{search}%")
)
return paginate(db, order_by_query(the_select))
@router.delete("/", status_code=200, operation_id="log_delete_many")
async def delete_logs(
application: UUID,
environment: str | SkipJsonSchema[None] = None,
l_type: LogType | SkipJsonSchema[None] = None,
t_type: TransactionType | SkipJsonSchema[None] = None,
object_reference: str | SkipJsonSchema[None] = None,
author: str | SkipJsonSchema[None] = None,
sub: str = Security(verify),
db: Session = Depends(get_db),
) -> int:
filters = {
"application": application,
"created_by_id": sub,
}
if environment is not None:
filters["environment"] = environment
if l_type is not None:
filters["l_type"] = l_type
if t_type is not None:
filters["t_type"] = t_type
if object_reference is not None:
filters["object_reference"] = object_reference
if author is not None:
filters["author"] = author
query = db.query(LogEntry).filter_by(**filters)
the_impact = query.count()
query.delete(synchronize_session=False)
db.commit()
return the_impact