add testing to fastapi

This commit is contained in:
Thomas Peetz
2025-04-17 02:21:14 +02:00
parent 4a61d6a727
commit a6eeea6c1f
11 changed files with 156 additions and 14 deletions
+2 -1
View File
@@ -1,11 +1,12 @@
from fastapi import FastAPI
from .routers import comic, media
from .routers import comic, media, tysc
app = FastAPI()
app.include_router(comic.router)
app.include_router(media.router)
app.include_router(tysc.router)
@app.get("/")
def read_root():
+36
View File
@@ -0,0 +1,36 @@
from typing import List, Dict
from uuid import UUID
from pydantic import BaseModel
from app.schema import Artist
class ArtistCreation(BaseModel):
name: str
class ArtistResponse(BaseModel):
id: UUID
name: str
class ArtistDetailResponse(BaseModel):
id: UUID
name: str
works: Dict[str, List[str]]
def get_artist_details(artist: Artist) -> ArtistDetailResponse:
works = {}
for work in artist.comic_works:
work_type = work.work_type.name
comic_title = work.comic.title
if work_type in works:
works[work_type].append(comic_title)
else:
works[work_type] = [comic_title]
response = ArtistDetailResponse(
id=artist.id,
name=artist.name,
works=works
)
return response
+46
View File
@@ -0,0 +1,46 @@
from typing import List, Dict
from uuid import UUID
from pydantic import BaseModel
from app.schema import Comic
class ComicResponse(BaseModel):
id: UUID
title: str
completed: bool
class ComicDetailsResponse(BaseModel):
id: UUID
title: str
completed : bool
current_order : bool
publisher: str
volumes: List[str]
works: Dict[str, List[str]]
def get_comic_details(comic: Comic) -> ComicDetailsResponse | None:
volumes = []
for volume in comic.volumes:
volumes.append(volume.name)
works = {}
for work in comic.comic_works:
work_type = work.work_type.name
artist_name = work.artist.name
if work_type in works:
works[work_type].append(artist_name)
else:
works[work_type] = [artist_name]
response = ComicDetailsResponse(
id=comic.id,
title=comic.title,
completed=(comic.completed == 1),
current_order=(comic.current_order == 1),
publisher=comic.publisher.name,
volumes=volumes,
works=works
)
return response
@@ -3,8 +3,7 @@ from uuid import UUID
from pydantic import BaseModel
class ComicResponse(BaseModel):
class SportResponse(BaseModel):
id: UUID
title: str
completed: bool
name: str
+37 -9
View File
@@ -1,11 +1,11 @@
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException
from typing import List
from fastapi import APIRouter, HTTPException, status
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.models.comic import ComicResponse
from app.schema import Comic, get_db, SessionDep
from app.models.comics.comic import ComicResponse, ComicDetailsResponse, get_comic_details
from app.models.comics.artist import ArtistCreation, ArtistDetailResponse, ArtistResponse, get_artist_details
from app.schema import Comic, SessionDep, Artist
router = APIRouter(
prefix="/comic",
@@ -22,11 +22,39 @@ def get_all_comics(db: SessionDep) -> list[ComicResponse]:
results.append(ComicResponse(id=comic.id, title=comic.title, completed=(comic.completed == 1)))
return results
@router.get("/comics/{comic_id}")
def get_comic(comic_id: UUID, db: SessionDep) -> ComicResponse:
@router.get("/comics/{comic_id}", response_model=ComicDetailsResponse)
def get_comic(comic_id: UUID, db: SessionDep) -> ComicDetailsResponse:
comic = db.get(Comic, comic_id)
if comic is None:
raise HTTPException(status_code=404, detail="Comic could not be found")
response: ComicResponse = ComicResponse(id=comic_id, title=comic.title, completed=comic.completed)
response: ComicDetailsResponse = get_comic_details(comic)
return response
@router.get("/artists", response_model=List[ArtistResponse])
def get_all_artists(db: SessionDep) -> List[ArtistResponse]:
results: List[ArtistResponse] = []
artists = db.query(Artist).all()
for artist in artists:
results.append(ArtistResponse(id=artist.id, name=artist.name))
return results
@router.get("/artists/{artist_id}", response_model=ArtistDetailResponse)
def get_artist(artist_id: UUID, db: SessionDep) -> ArtistDetailResponse:
artist = db.get(Artist, artist_id)
if artist is None:
raise HTTPException(status_code=404, detail="Artist could not be found")
response: ArtistDetailResponse = get_artist_details(artist)
return response
@router.post("/artists", status_code=status.HTTP_201_CREATED)
def add_artist(db: SessionDep, artist_creation: ArtistCreation) -> ArtistResponse:
artist: Artist = Artist()
setattr(artist, "name", artist_creation.name)
try:
db.add(artist)
db.commit()
except:
raise HTTPException(status_code=409, detail="Artist already added")
response = ArtistResponse(id=artist.id, name=artist.name)
return response
+20
View File
@@ -0,0 +1,20 @@
from typing import List
from fastapi import APIRouter
from app.models.tysc import SportResponse
from app.schema import Sport, SessionDep
router = APIRouter(
prefix="/tysc",
tags=["tysc"],
responses={404: {"description": "Not found"}},
)
@router.get("/sports")
def get_all_sports(db: SessionDep) -> List[SportResponse]:
results: list[SportResponse] = []
sports = db.query(Sport).all()
for sport in sports:
results.append(SportResponse(id=sport.id, name=sport.name))
return results
View File
+10
View File
@@ -0,0 +1,10 @@
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_get_authors():
response = client.get("/comic/artists")
assert response.status_code == 200
assert len(response.json()) == 5
+2 -1
View File
@@ -7,4 +7,5 @@ beautifulsoup4
sqlmodel
requests
fastapi[standard]
httpx==0.24.1
pytest==7.4.0