From 7cdbadbf8432ddd617d93bfcad12efdad2e2e94a Mon Sep 17 00:00:00 2001 From: Thomas Peetz Date: Tue, 19 May 2026 23:00:19 +0200 Subject: [PATCH] add missing comics endpoints --- kontor-api/src/apis/base.py | 217 +++++++++++++++--- kontor-api/src/apis/version1/admin/login.py | 9 +- .../src/apis/version1/comics/comicwork.py | 20 ++ .../src/apis/version1/comics/issuework.py | 20 ++ kontor-api/src/schema/comics/comicwork.py | 32 +++ kontor-api/src/schema/comics/issuework.py | 32 +++ kontor-scripts/api.py | 13 +- 7 files changed, 306 insertions(+), 37 deletions(-) create mode 100644 kontor-api/src/apis/version1/comics/comicwork.py create mode 100644 kontor-api/src/apis/version1/comics/issuework.py create mode 100644 kontor-api/src/schema/comics/comicwork.py create mode 100644 kontor-api/src/schema/comics/issuework.py diff --git a/kontor-api/src/apis/base.py b/kontor-api/src/apis/base.py index b291b6b..5cb99d5 100644 --- a/kontor-api/src/apis/base.py +++ b/kontor-api/src/apis/base.py @@ -4,36 +4,197 @@ add router for different parts (like comics, tysc, media) from fastapi import APIRouter, Depends from src.apis.version1.admin import mailaccount -from src.apis.version1.comics import artist, comic, issue, worktype, volume, storyarc -from src.apis.version1.media import mediaactor, mediaactorfile, mediafile, mediavideo, mediaarticle -from src.apis.version1.tysc import card, cardset, fieldposition, player, rooster, sport, team, vendor +from src.apis.version1.comics import ( + artist, + comic, + issue, + worktype, + volume, + storyarc, + comicwork, + issuework, +) +from src.apis.version1.media import ( + mediaactor, + mediaactorfile, + mediafile, + mediavideo, + mediaarticle, +) +from src.apis.version1.tysc import ( + card, + cardset, + fieldposition, + player, + rooster, + sport, + team, + vendor, +) from src.core.security import get_current_user_from_token from src.apis.version1 import comic, media, tysc, admin api_router = APIRouter(prefix="/api") -api_router.include_router(comic.router, prefix="/comics", tags=["comics"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(artist.router, prefix="/comics", tags=["comics"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(issue.router, prefix="/comics", tags=["comics"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(worktype.router, prefix="/comics", tags=["comics"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(volume.router, prefix="/comics", tags=["comics"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(storyarc.router, prefix="/comics", tags=["comics"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(mediafile.router, prefix="/media", tags=["media"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(mediavideo.router, prefix="/media", tags=["media"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(mediaarticle.router, prefix="/media", tags=["media"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(mediaactor.router, prefix="/media", tags=["media"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(mediaactorfile.router, prefix="/media", tags=["media"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(sport.router, prefix="/tysc", tags=["tysc"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(player.router, prefix="/tysc", tags=["tysc"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(team.router, prefix="/tysc", tags=["tysc"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(fieldposition.router, prefix="/tysc", tags=["tysc"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(rooster.router, prefix="/tysc", tags=["tysc"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(vendor.router, prefix="/tysc", tags=["tysc"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(cardset.router, prefix="/tysc", tags=["tysc"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(card.router, prefix="/tysc", tags=["tysc"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(article.router, prefix="/bookshelf", tags=["bookshelf"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(profile.router, prefix="/user", tags=["user"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(token.router, prefix="/user", tags=["user"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(permission.router, prefix="/user", tags=["user"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(assignment.router, prefix="/user", tags=["user"], dependencies=[Depends(get_current_user_from_token)]) -api_router.include_router(mailaccount.router, prefix="/admin", tags=["admin"], dependencies=[Depends(get_current_user_from_token)]) +api_router.include_router( + comic.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + artist.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + issue.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + worktype.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + volume.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + storyarc.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + comicwork.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + issuework.router, + prefix="/comics", + tags=["comics"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mediafile.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mediavideo.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mediaarticle.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mediaactor.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mediaactorfile.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + sport.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + player.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + team.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + fieldposition.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + rooster.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + vendor.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + cardset.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + card.router, + prefix="/tysc", + tags=["tysc"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + article.router, + prefix="/bookshelf", + tags=["bookshelf"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + profile.router, + prefix="/user", + tags=["user"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + token.router, + prefix="/user", + tags=["user"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + permission.router, + prefix="/user", + tags=["user"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + assignment.router, + prefix="/user", + tags=["user"], + dependencies=[Depends(get_current_user_from_token)], +) +api_router.include_router( + mailaccount.router, + prefix="/admin", + tags=["admin"], + dependencies=[Depends(get_current_user_from_token)], +) diff --git a/kontor-api/src/apis/version1/admin/login.py b/kontor-api/src/apis/version1/admin/login.py index 344dff9..22bbc93 100644 --- a/kontor-api/src/apis/version1/admin/login.py +++ b/kontor-api/src/apis/version1/admin/login.py @@ -2,7 +2,6 @@ from datetime import timedelta from fastapi import APIRouter, Depends, HTTPException, Response, status from fastapi.security import OAuth2PasswordRequestForm -from typing import Annotated from src.core.config import settings from src.core.log_conf import logger from src.core.security import ( @@ -16,6 +15,7 @@ from src.webapps.auth.forms import LoginForm login_router = APIRouter() + @login_router.post( "/login", tags=["login"], @@ -42,8 +42,10 @@ def login(request: LoginRequest) -> Token: @login_router.post("/token", tags=["login"], summary="Login for access token") -#async def login_for_access_token(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]) -> Token: -async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()) -> Token: +# async def login_for_access_token(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]) -> Token: +async def login_for_access_token( + form_data: OAuth2PasswordRequestForm = Depends(), +) -> Token: user = authenticate_user_by_username(form_data.username, form_data.password) if not user: raise HTTPException(status_code=400, detail="Incorrect username or password") @@ -54,6 +56,7 @@ async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends( ) return Token(access_token=access_token, token_type="bearer") + def login_for_token_cookie(response: Response, form_data: LoginForm = Depends()): user = authenticate_user_by_email(str(form_data.username), str(form_data.password)) if not user: diff --git a/kontor-api/src/apis/version1/comics/comicwork.py b/kontor-api/src/apis/version1/comics/comicwork.py new file mode 100644 index 0000000..96df658 --- /dev/null +++ b/kontor-api/src/apis/version1/comics/comicwork.py @@ -0,0 +1,20 @@ +from typing import List + +from fastapi import APIRouter + +from src.db.models.comic import ComicWork +from src.db.session import SessionDep +from src.schema.comics.comicwork import ComicWorkResponse, to_response + + +router = APIRouter() + + +@router.get("/comicworks", response_model=List[ComicWorkResponse]) +def get_comicworks(db: SessionDep) -> List[ComicWorkResponse]: + results: List[ComicWorkResponse] = [] + worktypes = db.query(ComicWork).all() + for worktype in worktypes: + response = to_response(worktype) + results.append(response) + return results diff --git a/kontor-api/src/apis/version1/comics/issuework.py b/kontor-api/src/apis/version1/comics/issuework.py new file mode 100644 index 0000000..711bd86 --- /dev/null +++ b/kontor-api/src/apis/version1/comics/issuework.py @@ -0,0 +1,20 @@ +from typing import List + +from fastapi import APIRouter + +from src.db.models.comic import IssueWork +from src.db.session import SessionDep +from src.schema.comics.issuework import IssueWorkResponse, to_response + + +router = APIRouter() + + +@router.get("/issueworks", response_model=List[IssueWorkResponse]) +def get_issueworks(db: SessionDep) -> List[IssueWorkResponse]: + results: List[IssueWorkResponse] = [] + worktypes = db.query(IssueWork).all() + for worktype in worktypes: + response = to_response(worktype) + results.append(response) + return results diff --git a/kontor-api/src/schema/comics/comicwork.py b/kontor-api/src/schema/comics/comicwork.py new file mode 100644 index 0000000..7de570c --- /dev/null +++ b/kontor-api/src/schema/comics/comicwork.py @@ -0,0 +1,32 @@ +""" +Model definitions for ComicWork. +""" + +from datetime import datetime + +from pydantic import BaseModel + +from src.db.models.comic import ComicWork + + +class ComicWorkResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + comic_id: str + artist_id: str + work_type_id: str + + +def to_response(comicwork: ComicWork) -> ComicWorkResponse: + response: ComicWorkResponse = ComicWorkResponse( + id=comicwork.id, + created_date=comicwork.created_date, + last_modified_date=comicwork.last_modified_date, + version=comicwork.version, + comic_id=comicwork.comic_id, + artist_id=comicwork.artist_id, + work_type_id=comicwork.work_type_id, + ) + return response diff --git a/kontor-api/src/schema/comics/issuework.py b/kontor-api/src/schema/comics/issuework.py new file mode 100644 index 0000000..2df9b90 --- /dev/null +++ b/kontor-api/src/schema/comics/issuework.py @@ -0,0 +1,32 @@ +""" +Model definitions for IssueWork. +""" + +from datetime import datetime + +from pydantic import BaseModel + +from src.db.models.comic import IssueWork + + +class IssueWorkResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + issue_id: str + artist_id: str + work_type_id: str + + +def to_response(issuework: IssueWork) -> IssueWorkResponse: + response: IssueWorkResponse = IssueWorkResponse( + id=issuework.id, + created_date=issuework.created_date, + last_modified_date=issuework.last_modified_date, + version=issuework.version, + issue_id=issuework.issue_id, + artist_id=issuework.artist_id, + work_type_id=issuework.work_type_id, + ) + return response diff --git a/kontor-scripts/api.py b/kontor-scripts/api.py index 1a1b2c5..b3bf465 100644 --- a/kontor-scripts/api.py +++ b/kontor-scripts/api.py @@ -27,6 +27,7 @@ MAPPING: Dict[str, str] = { "volume": "api/comics/volumes", "story_arc": "api/comics/storyarcs", "issue": "api/comics/issues", + "comic_work": "api/comics/comicworks", "issue_work": "api/comics/issueworks", "article": "api/bookshelf/articles", "bookshelf_publisher": "api/bookshelf/publishers", @@ -46,13 +47,15 @@ MAPPING: Dict[str, str] = { "mail_account": "api/admin/mailaccounts", } + class EndPointNotAvailableException(Exception): """ Raised when calling an not existing endpoint. """ - + pass + @dataclass class Login: """ @@ -106,7 +109,7 @@ class Server: headers: Dict[str, str] = {"Authorization": f"Bearer {self.token}"} response = requests.get(url, headers=headers, timeout=self.timeout) log.debug(f"Status: {response.status_code}") - if response.status_code==404: + if response.status_code == 404: raise EndPointNotAvailableException data = response.json() return data @@ -129,16 +132,14 @@ class ApiConfig: login: Login server: List[Server] - + def get_server(self, server_name: str) -> Optional[Server]: - """ - """ + """ """ found_server = None for server in self.server: if server.name == server_name: found_server = server return found_server - def get_logger(level, config: str):