change response for comic details

This commit is contained in:
Thomas Peetz
2025-09-20 13:05:07 +02:00
parent fd7a6bd1a1
commit 64ed4876a5
6 changed files with 63 additions and 31 deletions
+4 -1
View File
@@ -2,6 +2,7 @@ from typing import List, AnyStr
from fastapi import APIRouter, HTTPException, status from fastapi import APIRouter, HTTPException, status
from src.apis.utils import SessionDep from src.apis.utils import SessionDep
from src.core.log_conf import logger
from src.db.repository.comics.artist import get_artist_details from src.db.repository.comics.artist import get_artist_details
from src.db.repository.comics.comic import list_comics, get_issue_details from src.db.repository.comics.comic import list_comics, get_issue_details
from src.schema.comics.comic import ComicResponse, ComicDetailsResponse, get_comic_details, get_short_info from src.schema.comics.comic import ComicResponse, ComicDetailsResponse, get_comic_details, get_short_info
@@ -26,7 +27,9 @@ def get_comic(comic_id: AnyStr, db: SessionDep) -> ComicDetailsResponse:
comic = db.get(Comic, comic_id) comic = db.get(Comic, comic_id)
if comic is None: if comic is None:
raise HTTPException(status_code=404, detail="Comic could not be found") raise HTTPException(status_code=404, detail="Comic could not be found")
logger.info(f"create ComicDetailsResponse for {comic}")
response: ComicDetailsResponse = get_comic_details(comic) response: ComicDetailsResponse = get_comic_details(comic)
logger.info(f"ComicDetailsResponse: {response}")
return response return response
@router.get("/artists", response_model=List[ArtistResponse]) @router.get("/artists", response_model=List[ArtistResponse])
@@ -34,7 +37,7 @@ def get_all_artists(db: SessionDep) -> List[ArtistResponse]:
results: List[ArtistResponse] = [] results: List[ArtistResponse] = []
artists = db.query(Artist).all() artists = db.query(Artist).all()
for artist in artists: for artist in artists:
results.append(ArtistResponse(id=artist.id, name=artist.name)) results.append(ArtistResponse(id=artist.id, name=str(artist.name)))
return results return results
@router.get("/artists/{artist_id}", response_model=ArtistDetailResponse) @router.get("/artists/{artist_id}", response_model=ArtistDetailResponse)
+3 -4
View File
@@ -107,10 +107,10 @@ class Issue(Base, BaseMixin):
story_arc = relationship("StoryArc", back_populates="issues") story_arc = relationship("StoryArc", back_populates="issues")
issue_works = relationship("IssueWork") issue_works = relationship("IssueWork")
def get_full_title(self) -> AnyStr: def get_full_title(self) -> str:
full_title: AnyStr = self.issue_number full_title: str = str(self.issue_number)
if self.title: if self.title:
full_title += ": " + self.title full_title += str(": " + self.title)
return full_title return full_title
def get_artists(self) -> Dict[Any, List[Any]]: def get_artists(self) -> Dict[Any, List[Any]]:
@@ -186,4 +186,3 @@ class IssueWork(Base, BaseMixin):
artist = relationship("Artist", back_populates="issue_works") artist = relationship("Artist", back_populates="issue_works")
work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False) work_type_id = Column(String, ForeignKey("worktype.id"), nullable=False)
work_type = relationship("WorkType", back_populates="issue_works") work_type = relationship("WorkType", back_populates="issue_works")
+8 -8
View File
@@ -8,7 +8,7 @@ from src.schema.comics.comic import ComicSchema
from src.schema.comics.issue import IssueDetailsResponse from src.schema.comics.issue import IssueDetailsResponse
def list_comics(db: Session) -> List[Type[Comic]]: def list_comics(db: Session) -> List[Comic]:
comics = db.query(Comic).all() comics = db.query(Comic).all()
return comics return comics
@@ -16,16 +16,16 @@ def list_comics(db: Session) -> List[Type[Comic]]:
def get_issue_details(issue: Issue) -> IssueDetailsResponse: def get_issue_details(issue: Issue) -> IssueDetailsResponse:
response = IssueDetailsResponse( response = IssueDetailsResponse(
id=issue.id, id=issue.id,
issue_number=issue.issue_number, issue_number=str(issue.issue_number),
in_stock=issue.in_stock, in_stock=bool(issue.in_stock),
is_read=issue.is_read, is_read=bool(issue.is_read),
comic_id=issue.comic_id, comic_id=str(issue.comic_id),
volume_id=issue.volume_id volume_id=str(issue.volume_id)
) )
return response return response
def update_comic(comic: ComicSchema, comic_id: AnyStr, db: Session) -> type[Comic] | None: def update_comic(comic: ComicSchema, comic_id: AnyStr, db: Session) -> type[Comic] | None:
logger.info(f"update_comic: {comic} with {comic_id}") logger.info(f"update_comic: {comic} with {comic_id}")
comic = db.get(Comic, comic_id) comic = db.get(Comic, comic_id) # type: ignore
return comic return comic # type: ignore
+36 -17
View File
@@ -2,7 +2,11 @@ from typing import List, Dict, Optional
from pydantic import BaseModel, AnyUrl from pydantic import BaseModel, AnyUrl
from src.core.log_conf import logger
from src.db.models.comic import Comic from src.db.models.comic import Comic
from src.schema.comics.artist import ArtistResponse
from src.schema.comics.volume import VolumeResponse
from src.schema.comics.worktype import WorktypeResponse
class ComicResponse(BaseModel): class ComicResponse(BaseModel):
@@ -10,6 +14,13 @@ class ComicResponse(BaseModel):
title: str title: str
completed: bool completed: bool
class ComicWorktypeArtistResponse(BaseModel):
worktype: WorktypeResponse
artists: List[ArtistResponse]
class ComicDetailsResponse(BaseModel): class ComicDetailsResponse(BaseModel):
id: str id: str
created: str created: str
@@ -18,8 +29,8 @@ class ComicDetailsResponse(BaseModel):
current_order : bool current_order : bool
weblink: str weblink: str
publisher: str publisher: str
volumes: List[str] volumes: List[VolumeResponse]
works: Dict[str, List[str]] works: List[ComicWorktypeArtistResponse]
class ComicSchema(BaseModel): class ComicSchema(BaseModel):
@@ -33,31 +44,39 @@ class ComicSchema(BaseModel):
def get_short_info(comic: Comic) -> ComicResponse: def get_short_info(comic: Comic) -> ComicResponse:
response = ComicResponse( response = ComicResponse(
id=comic.id, id=comic.id,
title=comic.title, title=str(comic.title),
completed=(comic.completed == 1) completed=bool(comic.completed == 1)
) )
return response return response
def get_comic_details(comic: Comic) -> ComicDetailsResponse | None: def get_comic_details(comic: Comic) -> ComicDetailsResponse:
volumes = [] volumes: List[VolumeResponse] = []
for volume in comic.volumes: for volume in comic.volumes:
volumes.append(volume.name) volumes.append(VolumeResponse(id=volume.id, name=volume.name))
works = {} works: List[ComicWorktypeArtistResponse] = []
works_map: Dict[str, ComicWorktypeArtistResponse] = {}
for work in comic.comic_works: for work in comic.comic_works:
work_type = work.work_type.name worktype_id = work.work_type.id
artist_name = work.artist.name if worktype_id in works_map:
if work_type in works: artist = ArtistResponse(id=work.artist.id, name=work.artist.name)
works[work_type].append(artist_name) works_map[worktype_id].artists.append(artist)
logger.info(f"add artist to response map: {artist} -> {works_map}")
print(f"add artist to response map: {artist} -> {works_map}")
else: else:
works[work_type] = [artist_name] works_map[worktype_id] = ComicWorktypeArtistResponse(
worktype=WorktypeResponse(id=worktype_id, name=work.work_type.name),
artists=[ArtistResponse(id=work.artist.id, name=work.artist.name)]
)
for value in works_map.values():
works.append(value)
response = ComicDetailsResponse( response = ComicDetailsResponse(
id=comic.id, id=comic.id,
created=str(comic.created_date), created=str(comic.created_date),
title=comic.title, title=str(comic.title),
completed=comic.completed, completed=bool(comic.completed),
current_order=comic.current_order, current_order=bool(comic.current_order),
weblink=comic.weblink, weblink=str(comic.weblink),
publisher=comic.publisher.name, publisher=comic.publisher.name,
volumes=volumes, volumes=volumes,
works=works works=works
+6
View File
@@ -0,0 +1,6 @@
from pydantic import BaseModel
class VolumeResponse(BaseModel):
id: str
name: str
+5
View File
@@ -2,3 +2,8 @@ from pydantic import BaseModel
class AddWorkType(BaseModel): class AddWorkType(BaseModel):
worktype: str worktype: str
class WorktypeResponse(BaseModel):
id: str
name: str