From 48149b67cf0aaa1793017731ecd557faf234a3de Mon Sep 17 00:00:00 2001 From: Thomas Peetz Date: Fri, 14 Aug 2026 16:39:46 +0200 Subject: [PATCH] extract SQLAlchemy model in separate python library --- kontor-api/Containerfile | 2 +- kontor-api/pyproject.toml | 5 +- kontor-api/src/apis/base.py | 7 + kontor-api/src/apis/version1/admin/login.py | 4 +- .../src/apis/version1/admin/mailaccount.py | 4 +- .../src/apis/version1/bookshelf/article.py | 4 +- .../apis/version1/bookshelf/articleauthor.py | 4 +- .../src/apis/version1/bookshelf/author.py | 4 +- .../src/apis/version1/bookshelf/book.py | 4 +- .../src/apis/version1/bookshelf/bookauthor.py | 4 +- .../version1/bookshelf/bookshelf_publisher.py | 4 +- kontor-api/src/apis/version1/comics/artist.py | 8 +- kontor-api/src/apis/version1/comics/comic.py | 8 +- .../src/apis/version1/comics/comicwork.py | 4 +- kontor-api/src/apis/version1/comics/issue.py | 4 +- .../src/apis/version1/comics/issuework.py | 4 +- .../src/apis/version1/comics/publisher.py | 8 +- .../src/apis/version1/comics/storyarc.py | 4 +- kontor-api/src/apis/version1/comics/volume.py | 4 +- .../src/apis/version1/comics/worktype.py | 4 +- kontor-api/src/apis/version1/healthcheck.py | 2 +- kontor-api/src/apis/version1/media/actor.py | 6 +- kontor-api/src/apis/version1/media/file.py | 12 +- kontor-api/src/apis/version1/media/lofi.py | 42 +++ .../src/apis/version1/media/mediaactorfile.py | 6 +- .../src/apis/version1/media/mediaarticle.py | 4 +- .../src/apis/version1/media/mediavideo.py | 4 +- kontor-api/src/apis/version1/tysc/card.py | 4 +- kontor-api/src/apis/version1/tysc/cardset.py | 4 +- .../src/apis/version1/tysc/fieldposition.py | 4 +- kontor-api/src/apis/version1/tysc/player.py | 4 +- kontor-api/src/apis/version1/tysc/rooster.py | 4 +- kontor-api/src/apis/version1/tysc/sport.py | 4 +- kontor-api/src/apis/version1/tysc/team.py | 4 +- kontor-api/src/apis/version1/tysc/vendor.py | 4 +- .../src/apis/version1/user/assignment.py | 4 +- .../src/apis/version1/user/permission.py | 4 +- kontor-api/src/apis/version1/user/profile.py | 4 +- kontor-api/src/apis/version1/user/token.py | 4 +- kontor-api/src/core/security.py | 10 +- kontor-api/src/db/models/admin.py | 75 ----- kontor-api/src/db/models/base.py | 27 -- kontor-api/src/db/models/bookshelf.py | 52 --- kontor-api/src/db/models/comic.py | 188 ----------- kontor-api/src/db/models/media.py | 97 ------ kontor-api/src/db/models/tysc.py | 100 ------ .../src/db/repository/comics/publisher.py | 24 -- kontor-api/src/db/repository/user.py | 4 +- kontor-api/src/main.py | 2 +- .../src/templates/media/add_lofi_link.html | 29 ++ .../src/templates/media/lofi_detail.html | 51 +++ kontor-api/src/templates/media/lofi_list.html | 29 ++ kontor-api/src/templates/media/media_nav.html | 1 + kontor-api/src/webapps/admin/route_admin.py | 2 +- kontor-api/src/webapps/base.py | 3 +- kontor-api/src/webapps/comic/route_artists.py | 9 +- kontor-api/src/webapps/comic/route_comics.py | 6 +- .../src/webapps/comic/route_worktype.py | 6 +- kontor-api/src/webapps/media/route_actors.py | 2 +- kontor-api/src/webapps/media/route_lofi.py | 51 +++ kontor-api/src/webapps/media/route_media.py | 6 +- kontor-api/src/webapps/media/route_videos.py | 14 +- kontor-api/tests/conftest.py | 2 +- kontor-api/uv.lock | 136 +++++--- kontor-model/.python-version | 1 + .../__init__.py => kontor-model/README.md | 0 kontor-model/pyproject.toml | 18 + kontor-model/src/kontor_model/__init__.py | 2 + .../src/kontor_model/db}/__init__.py | 0 .../src/kontor_model}/db/models/__init__.py | 12 +- .../src/kontor_model}/db/models/admin.py | 2 +- .../src/kontor_model}/db/models/base.py | 0 .../src/kontor_model}/db/models/bookshelf.py | 4 +- .../src/kontor_model}/db/models/comic.py | 2 +- .../src/kontor_model}/db/models/media.py | 89 ++--- .../src/kontor_model}/db/models/tysc.py | 2 +- .../kontor_model/db/repository}/__init__.py | 0 .../src/kontor_model}/db/repository/admin.py | 2 +- .../db/repository/comics}/__init__.py | 0 .../db/repository/comics/artist.py | 25 +- .../db/repository/comics/comic.py | 21 +- .../db/repository/comics/publisher.py | 52 +++ .../db/repository/comics/worktype.py | 7 +- .../db/repository/media/actor.py | 15 +- .../db/repository/media/actorfile.py | 11 +- .../kontor_model}/db/repository/media/file.py | 13 +- .../kontor_model/db/repository/media/lofi.py | 22 ++ .../db/repository/media/video.py | 9 +- .../src/kontor_model/db/repository/user.py | 41 +++ .../src/kontor_model/py.typed | 0 .../src/kontor_model/schema}/__init__.py | 0 .../kontor_model}/schema/admin/healthcheck.py | 0 .../src/kontor_model}/schema/admin/login.py | 0 .../kontor_model}/schema/admin/mailaccount.py | 12 +- .../src/kontor_model}/schema/admin/token.py | 0 .../kontor_model}/schema/bookshelf/article.py | 4 +- .../schema/bookshelf/articleauthor.py | 6 +- .../kontor_model}/schema/bookshelf/author.py | 6 +- .../kontor_model}/schema/bookshelf/book.py | 8 +- .../schema/bookshelf/bookauthor.py | 6 +- .../schema/bookshelf/publisher.py | 4 +- .../kontor_model/schema/comics}/__init__.py | 0 .../src/kontor_model}/schema/comics/artist.py | 2 +- .../schema/comics/artist_details.py | 6 +- .../src/kontor_model}/schema/comics/comic.py | 12 +- .../schema/comics/comic_details.py | 10 +- .../kontor_model}/schema/comics/comicwork.py | 8 +- .../src/kontor_model}/schema/comics/issue.py | 16 +- .../schema/comics/issue_details.py | 4 +- .../kontor_model}/schema/comics/issuework.py | 8 +- .../kontor_model}/schema/comics/publisher.py | 6 +- .../schema/comics/publisher_details.py | 4 +- .../kontor_model}/schema/comics/storyarc.py | 8 +- .../src/kontor_model}/schema/comics/volume.py | 6 +- .../kontor_model}/schema/comics/worktype.py | 4 +- .../kontor_model/schema/media}/__init__.py | 0 .../src/kontor_model}/schema/media/actor.py | 6 +- .../kontor_model}/schema/media/actorfile.py | 6 +- .../src/kontor_model}/schema/media/article.py | 8 +- .../src/kontor_model}/schema/media/file.py | 2 +- .../src/kontor_model/schema/media/lofi.py | 33 ++ .../src/kontor_model}/schema/media/video.py | 16 +- .../src/kontor_model/schema/tysc}/__init__.py | 0 .../src/kontor_model}/schema/tysc/card.py | 8 +- .../src/kontor_model}/schema/tysc/cardset.py | 10 +- .../schema/tysc/fieldposition.py | 8 +- .../src/kontor_model}/schema/tysc/player.py | 6 +- .../src/kontor_model}/schema/tysc/rooster.py | 8 +- .../src/kontor_model}/schema/tysc/sport.py | 4 +- .../src/kontor_model}/schema/tysc/team.py | 8 +- .../src/kontor_model}/schema/tysc/vendor.py | 4 +- .../kontor_model}/schema/user/assignment.py | 6 +- .../kontor_model}/schema/user/permission.py | 4 +- .../src/kontor_model}/schema/user/profile.py | 14 +- .../src/kontor_model}/schema/user/token.py | 10 +- kontor-model/uv.lock | 317 ++++++++++++++++++ kontor-scripts/add_links.py | 2 +- kontor-scripts/api.py | 3 +- kontor-scripts/db/models/database.py | 66 ---- kontor-scripts/download.py | 3 +- kontor-scripts/export.py | 4 +- kontor-scripts/find_links.py | 1 - kontor-scripts/import.py | 4 +- kontor-scripts/pyproject.toml | 4 + kontor-scripts/update_title.py | 6 +- kontor-scripts/uv.lock | 48 ++- script/cibuild | 2 +- script/update | 2 +- 148 files changed, 1195 insertions(+), 1062 deletions(-) create mode 100644 kontor-api/src/apis/version1/media/lofi.py delete mode 100644 kontor-api/src/db/models/admin.py delete mode 100644 kontor-api/src/db/models/base.py delete mode 100644 kontor-api/src/db/models/bookshelf.py delete mode 100644 kontor-api/src/db/models/comic.py delete mode 100644 kontor-api/src/db/models/media.py delete mode 100644 kontor-api/src/db/models/tysc.py delete mode 100644 kontor-api/src/db/repository/comics/publisher.py create mode 100644 kontor-api/src/templates/media/add_lofi_link.html create mode 100644 kontor-api/src/templates/media/lofi_detail.html create mode 100644 kontor-api/src/templates/media/lofi_list.html create mode 100644 kontor-api/src/webapps/media/route_lofi.py create mode 100644 kontor-model/.python-version rename kontor-api/src/db/models/__init__.py => kontor-model/README.md (100%) create mode 100644 kontor-model/pyproject.toml create mode 100644 kontor-model/src/kontor_model/__init__.py rename {kontor-api/src/db/repository => kontor-model/src/kontor_model/db}/__init__.py (100%) rename {kontor-scripts => kontor-model/src/kontor_model}/db/models/__init__.py (87%) rename {kontor-scripts => kontor-model/src/kontor_model}/db/models/admin.py (99%) rename {kontor-scripts => kontor-model/src/kontor_model}/db/models/base.py (100%) rename {kontor-scripts => kontor-model/src/kontor_model}/db/models/bookshelf.py (98%) rename {kontor-scripts => kontor-model/src/kontor_model}/db/models/comic.py (99%) rename {kontor-scripts => kontor-model/src/kontor_model}/db/models/media.py (76%) rename {kontor-scripts => kontor-model/src/kontor_model}/db/models/tysc.py (99%) rename {kontor-api/src/db/repository/comics => kontor-model/src/kontor_model/db/repository}/__init__.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/db/repository/admin.py (91%) rename {kontor-api/src/schema => kontor-model/src/kontor_model/db/repository/comics}/__init__.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/db/repository/comics/artist.py (61%) rename {kontor-api/src => kontor-model/src/kontor_model}/db/repository/comics/comic.py (73%) create mode 100644 kontor-model/src/kontor_model/db/repository/comics/publisher.py rename {kontor-api/src => kontor-model/src/kontor_model}/db/repository/comics/worktype.py (78%) rename {kontor-api/src => kontor-model/src/kontor_model}/db/repository/media/actor.py (81%) rename {kontor-api/src => kontor-model/src/kontor_model}/db/repository/media/actorfile.py (83%) rename {kontor-api/src => kontor-model/src/kontor_model}/db/repository/media/file.py (85%) create mode 100644 kontor-model/src/kontor_model/db/repository/media/lofi.py rename {kontor-api/src => kontor-model/src/kontor_model}/db/repository/media/video.py (66%) create mode 100644 kontor-model/src/kontor_model/db/repository/user.py rename kontor-api/src/schema/comics/__init__.py => kontor-model/src/kontor_model/py.typed (100%) rename {kontor-api/src/schema/media => kontor-model/src/kontor_model/schema}/__init__.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/admin/healthcheck.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/admin/login.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/admin/mailaccount.py (71%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/admin/token.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/bookshelf/article.py (84%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/bookshelf/articleauthor.py (78%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/bookshelf/author.py (78%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/bookshelf/book.py (76%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/bookshelf/bookauthor.py (78%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/bookshelf/publisher.py (84%) rename {kontor-api/src/schema/tysc => kontor-model/src/kontor_model/schema/comics}/__init__.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/artist.py (93%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/artist_details.py (70%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/comic.py (77%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/comic_details.py (59%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/comicwork.py (76%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/issue.py (69%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/issue_details.py (62%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/issuework.py (76%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/publisher.py (83%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/publisher_details.py (66%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/storyarc.py (78%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/volume.py (81%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/comics/worktype.py (87%) rename {kontor-scripts/db => kontor-model/src/kontor_model/schema/media}/__init__.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/media/actor.py (86%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/media/actorfile.py (82%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/media/article.py (81%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/media/file.py (97%) create mode 100644 kontor-model/src/kontor_model/schema/media/lofi.py rename {kontor-api/src => kontor-model/src/kontor_model}/schema/media/video.py (71%) rename {kontor-scripts/db/repository => kontor-model/src/kontor_model/schema/tysc}/__init__.py (100%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/tysc/card.py (77%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/tysc/cardset.py (71%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/tysc/fieldposition.py (75%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/tysc/player.py (78%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/tysc/rooster.py (80%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/tysc/sport.py (86%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/tysc/team.py (76%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/tysc/vendor.py (89%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/user/assignment.py (78%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/user/permission.py (85%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/user/profile.py (77%) rename {kontor-api/src => kontor-model/src/kontor_model}/schema/user/token.py (76%) create mode 100644 kontor-model/uv.lock delete mode 100644 kontor-scripts/db/models/database.py diff --git a/kontor-api/Containerfile b/kontor-api/Containerfile index bb031b5..7690598 100644 --- a/kontor-api/Containerfile +++ b/kontor-api/Containerfile @@ -14,7 +14,7 @@ ENV PATH="/root/.local/bin:${PATH}" WORKDIR /app COPY ./pyproject.toml . - +RUN --mount=type=bind,source=/home/tpeetz/projects/kontor/kontor-model,target=/container/kontor-model uv add /container/kontor-model RUN uv sync # ------------------------------- Production Stage ------------------------------ ## diff --git a/kontor-api/pyproject.toml b/kontor-api/pyproject.toml index 87b0c49..dd68147 100644 --- a/kontor-api/pyproject.toml +++ b/kontor-api/pyproject.toml @@ -24,10 +24,13 @@ dependencies = [ "psycopg2-binary>=2.9.10", "pytest-cov>=6.1.1", "databases[sqlite]>=0.9.0", - "pydantic[email]>=2.11.3", "jinja2>=3.1.6", "asyncpg>=0.30.0", "bcrypt>=4.3.0", "fastapi-jwt-auth>=0.5.0", "msgspec[toml,yaml]>=0.21.1", + "kontor-model", ] + +[tool.uv.sources] +kontor-model = { path = "../kontor-model", editable = true } diff --git a/kontor-api/src/apis/base.py b/kontor-api/src/apis/base.py index ed508e7..6002400 100644 --- a/kontor-api/src/apis/base.py +++ b/kontor-api/src/apis/base.py @@ -18,6 +18,7 @@ from src.apis.version1.comics import ( from src.apis.version1.media import ( actor, file, + lofi, mediaactorfile, mediavideo, mediaarticle, @@ -104,6 +105,12 @@ api_router.include_router( tags=["media"], dependencies=[Depends(get_current_user_from_token)], ) +api_router.include_router( + lofi.router, + prefix="/media", + tags=["media"], + dependencies=[Depends(get_current_user_from_token)], +) api_router.include_router( mediaarticle.router, prefix="/media", diff --git a/kontor-api/src/apis/version1/admin/login.py b/kontor-api/src/apis/version1/admin/login.py index 22bbc93..bbf743f 100644 --- a/kontor-api/src/apis/version1/admin/login.py +++ b/kontor-api/src/apis/version1/admin/login.py @@ -9,8 +9,8 @@ from src.core.security import ( authenticate_user_by_username, create_access_token, ) -from src.schema.admin.login import LoginRequest -from src.schema.admin.token import Token +from kontor_model.schema.admin.login import LoginRequest +from kontor_model.schema.admin.token import Token from src.webapps.auth.forms import LoginForm login_router = APIRouter() diff --git a/kontor-api/src/apis/version1/admin/mailaccount.py b/kontor-api/src/apis/version1/admin/mailaccount.py index 9bfb890..4a3bdbe 100644 --- a/kontor-api/src/apis/version1/admin/mailaccount.py +++ b/kontor-api/src/apis/version1/admin/mailaccount.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.admin import MailAccount +from kontor_model.db.models.admin import MailAccount from src.db.session import SessionDep -from src.schema.admin.mailaccount import MailAccountResponse, to_response +from kontor_model.schema.admin.mailaccount import MailAccountResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/bookshelf/article.py b/kontor-api/src/apis/version1/bookshelf/article.py index b985b36..64646e1 100644 --- a/kontor-api/src/apis/version1/bookshelf/article.py +++ b/kontor-api/src/apis/version1/bookshelf/article.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter -from src.db.models.bookshelf import Article +from kontor_model.db.models.bookshelf import Article from src.db.session import SessionDep -from src.schema.bookshelf.article import ArticleResponse, to_response +from kontor_model.schema.bookshelf.article import ArticleResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/bookshelf/articleauthor.py b/kontor-api/src/apis/version1/bookshelf/articleauthor.py index 8ebb982..0addeb9 100644 --- a/kontor-api/src/apis/version1/bookshelf/articleauthor.py +++ b/kontor-api/src/apis/version1/bookshelf/articleauthor.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter -from src.db.models.bookshelf import ArticleAuthor +from kontor_model.db.models.bookshelf import ArticleAuthor from src.db.session import SessionDep -from src.schema.bookshelf.articleauthor import ArticleAuthorResponse, to_response +from kontor_model.schema.bookshelf.articleauthor import ArticleAuthorResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/bookshelf/author.py b/kontor-api/src/apis/version1/bookshelf/author.py index e4bc73c..9bbb9a7 100644 --- a/kontor-api/src/apis/version1/bookshelf/author.py +++ b/kontor-api/src/apis/version1/bookshelf/author.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.bookshelf import Author +from kontor_model.db.models.bookshelf import Author from src.db.session import SessionDep -from src.schema.bookshelf.author import AuthorResponse, to_response +from kontor_model.schema.bookshelf.author import AuthorResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/bookshelf/book.py b/kontor-api/src/apis/version1/bookshelf/book.py index 5c12f16..55345a0 100644 --- a/kontor-api/src/apis/version1/bookshelf/book.py +++ b/kontor-api/src/apis/version1/bookshelf/book.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter -from src.db.models.bookshelf import Book +from kontor_model.db.models.bookshelf import Book from src.db.session import SessionDep -from src.schema.bookshelf.book import BookResponse, to_response +from kontor_model.schema.bookshelf.book import BookResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/bookshelf/bookauthor.py b/kontor-api/src/apis/version1/bookshelf/bookauthor.py index 8ecc856..4150bf2 100644 --- a/kontor-api/src/apis/version1/bookshelf/bookauthor.py +++ b/kontor-api/src/apis/version1/bookshelf/bookauthor.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter -from src.db.models.bookshelf import BookAuthor +from kontor_model.db.models.bookshelf import BookAuthor from src.db.session import SessionDep -from src.schema.bookshelf.bookauthor import BookAuthorResponse, to_response +from kontor_model.schema.bookshelf.bookauthor import BookAuthorResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/bookshelf/bookshelf_publisher.py b/kontor-api/src/apis/version1/bookshelf/bookshelf_publisher.py index 74859ad..94898a6 100644 --- a/kontor-api/src/apis/version1/bookshelf/bookshelf_publisher.py +++ b/kontor-api/src/apis/version1/bookshelf/bookshelf_publisher.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter -from src.db.models.bookshelf import BookshelfPublisher +from kontor_model.db.models.bookshelf import BookshelfPublisher from src.db.session import SessionDep -from src.schema.bookshelf.publisher import PublisherResponse, to_response +from kontor_model.schema.bookshelf.publisher import PublisherResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/artist.py b/kontor-api/src/apis/version1/comics/artist.py index a126688..cc329b7 100644 --- a/kontor-api/src/apis/version1/comics/artist.py +++ b/kontor-api/src/apis/version1/comics/artist.py @@ -2,11 +2,11 @@ from typing import List from fastapi import APIRouter, HTTPException, status -from src.db.models.comic import Artist -from src.db.repository.comics.artist import get_artist_details +from kontor_model.db.models.comic import Artist +from kontor_model.db.repository.comics.artist import get_artist_details from src.db.session import SessionDep -from src.schema.comics.artist import ArtistCreation, ArtistResponse, artist_to_response -from src.schema.comics.artist_details import ArtistDetailResponse +from kontor_model.schema.comics.artist import ArtistCreation, ArtistResponse, artist_to_response +from kontor_model.schema.comics.artist_details import ArtistDetailResponse router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/comic.py b/kontor-api/src/apis/version1/comics/comic.py index bca4acc..823c198 100644 --- a/kontor-api/src/apis/version1/comics/comic.py +++ b/kontor-api/src/apis/version1/comics/comic.py @@ -3,13 +3,13 @@ from typing import List from fastapi import APIRouter, HTTPException from src.core.log_conf import logger -from src.db.models.comic import Comic -from src.db.repository.comics.comic import ( +from kontor_model.db.models.comic import Comic +from kontor_model.db.repository.comics.comic import ( get_comic_details, ) from src.db.session import SessionDep -from src.schema.comics.comic import ComicResponse, comic_to_response -from src.schema.comics.comic_details import ComicDetailsResponse +from kontor_model.schema.comics.comic import ComicResponse, comic_to_response +from kontor_model.schema.comics.comic_details import ComicDetailsResponse router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/comicwork.py b/kontor-api/src/apis/version1/comics/comicwork.py index 650c36c..2dcd441 100644 --- a/kontor-api/src/apis/version1/comics/comicwork.py +++ b/kontor-api/src/apis/version1/comics/comicwork.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.comic import ComicWork +from kontor_model.db.models.comic import ComicWork from src.db.session import SessionDep -from src.schema.comics.comicwork import ComicWorkResponse, comicwork_to_response +from kontor_model.schema.comics.comicwork import ComicWorkResponse, comicwork_to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/issue.py b/kontor-api/src/apis/version1/comics/issue.py index 78c6245..8af3fb7 100644 --- a/kontor-api/src/apis/version1/comics/issue.py +++ b/kontor-api/src/apis/version1/comics/issue.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.comic import Issue +from kontor_model.db.models.comic import Issue from src.db.session import SessionDep -from src.schema.comics.issue import IssueResponse, issue_to_response +from kontor_model.schema.comics.issue import IssueResponse, issue_to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/issuework.py b/kontor-api/src/apis/version1/comics/issuework.py index a5465a4..078a8ec 100644 --- a/kontor-api/src/apis/version1/comics/issuework.py +++ b/kontor-api/src/apis/version1/comics/issuework.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.comic import IssueWork +from kontor_model.db.models.comic import IssueWork from src.db.session import SessionDep -from src.schema.comics.issuework import IssueWorkResponse, issuework_to_response +from kontor_model.schema.comics.issuework import IssueWorkResponse, issuework_to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/publisher.py b/kontor-api/src/apis/version1/comics/publisher.py index bdafb7b..4780877 100644 --- a/kontor-api/src/apis/version1/comics/publisher.py +++ b/kontor-api/src/apis/version1/comics/publisher.py @@ -2,11 +2,11 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.comic import Publisher -from src.db.repository.comics.publisher import get_publisher_details +from kontor_model.db.models.comic import Publisher +from kontor_model.db.repository.comics.publisher import get_publisher_details from src.db.session import SessionDep -from src.schema.comics.publisher import PublisherResponse, publisher_to_response -from src.schema.comics.publisher_details import PublisherDetailsResponse +from kontor_model.schema.comics.publisher import PublisherResponse, publisher_to_response +from kontor_model.schema.comics.publisher_details import PublisherDetailsResponse router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/storyarc.py b/kontor-api/src/apis/version1/comics/storyarc.py index 6347187..2ae6239 100644 --- a/kontor-api/src/apis/version1/comics/storyarc.py +++ b/kontor-api/src/apis/version1/comics/storyarc.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.comic import StoryArc +from kontor_model.db.models.comic import StoryArc from src.db.session import SessionDep -from src.schema.comics.storyarc import StoryArcResponse, storyarc_to_response +from kontor_model.schema.comics.storyarc import StoryArcResponse, storyarc_to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/volume.py b/kontor-api/src/apis/version1/comics/volume.py index b538136..faab88f 100644 --- a/kontor-api/src/apis/version1/comics/volume.py +++ b/kontor-api/src/apis/version1/comics/volume.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.comic import Volume +from kontor_model.db.models.comic import Volume from src.db.session import SessionDep -from src.schema.comics.volume import VolumeResponse, volume_to_response +from kontor_model.schema.comics.volume import VolumeResponse, volume_to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/comics/worktype.py b/kontor-api/src/apis/version1/comics/worktype.py index 39c6285..a06df0f 100644 --- a/kontor-api/src/apis/version1/comics/worktype.py +++ b/kontor-api/src/apis/version1/comics/worktype.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.comic import WorkType +from kontor_model.db.models.comic import WorkType from src.db.session import SessionDep -from src.schema.comics.worktype import WorktypeResponse, worktype_to_response +from kontor_model.schema.comics.worktype import WorktypeResponse, worktype_to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/healthcheck.py b/kontor-api/src/apis/version1/healthcheck.py index 33d1e7e..aec2131 100644 --- a/kontor-api/src/apis/version1/healthcheck.py +++ b/kontor-api/src/apis/version1/healthcheck.py @@ -1,6 +1,6 @@ from fastapi import APIRouter, status -from src.schema.admin.healthcheck import HealthCheck +from kontor_model.schema.admin.healthcheck import HealthCheck health_router = APIRouter() diff --git a/kontor-api/src/apis/version1/media/actor.py b/kontor-api/src/apis/version1/media/actor.py index 86c5bd1..222e236 100644 --- a/kontor-api/src/apis/version1/media/actor.py +++ b/kontor-api/src/apis/version1/media/actor.py @@ -2,10 +2,10 @@ from typing import List from fastapi import APIRouter, status, HTTPException from src.core.log_conf import logger -from src.db.repository.media.actor import delete_mediaactor, import_mediaactor +from kontor_model.db.repository.media.actor import delete_mediaactor, import_mediaactor from src.db.session import SessionDep -from src.schema.media.actor import MediaActorModel, MediaActorResponse, actor_to_response -from src.db.models.media import MediaActor +from kontor_model.schema.media.actor import MediaActorModel, MediaActorResponse, actor_to_response +from kontor_model.db.models.media import MediaActor router = APIRouter() diff --git a/kontor-api/src/apis/version1/media/file.py b/kontor-api/src/apis/version1/media/file.py index de2a664..3c695e0 100644 --- a/kontor-api/src/apis/version1/media/file.py +++ b/kontor-api/src/apis/version1/media/file.py @@ -2,21 +2,21 @@ from typing import List from fastapi import APIRouter, status, HTTPException from src.core.log_conf import logger -from src.db.repository.media.actorfile import ( +from kontor_model.db.repository.media.actorfile import ( create_new_mediaactorfile, delete_mediaactorfile, ) -from src.db.repository.media.file import delete_mediafile, import_mediafile +from kontor_model.db.repository.media.file import delete_mediafile, import_mediafile from src.db.session import SessionDep -from src.schema.media.actor import MediaActorResponse, actor_to_response -from src.schema.media.actorfile import MediaActorFileResponse, actorfile_to_response -from src.schema.media.file import ( +from kontor_model.schema.media.actor import MediaActorResponse, actor_to_response +from kontor_model.schema.media.actorfile import MediaActorFileResponse, actorfile_to_response +from kontor_model.schema.media.file import ( MediaFileModel, MediaFileResponse, file_to_response, file_to_model, ) -from src.db.models.media import MediaFile +from kontor_model.db.models.media import MediaFile router = APIRouter() diff --git a/kontor-api/src/apis/version1/media/lofi.py b/kontor-api/src/apis/version1/media/lofi.py new file mode 100644 index 0000000..8f7e356 --- /dev/null +++ b/kontor-api/src/apis/version1/media/lofi.py @@ -0,0 +1,42 @@ + +from typing import List + +from fastapi import APIRouter, HTTPException + +from kontor_model.db.models.media import MediaLofi +from src.db.session import SessionDep +from kontor_model.schema.media.lofi import MediaLofiResponse, lofi_to_response + + +router = APIRouter() + +@router.get("/lofi", response_model=List[MediaLofiResponse]) +def get_all_lofis( + db: SessionDep, review: bool = False, download: bool = False +) -> List[MediaLofiResponse]: + """ + Get all MediaLofis. + """ + results: List[MediaLofiResponse] = [] + lofis: List[MediaLofi] + if review: + lofis = db.query(MediaLofi).filter(MediaLofi.review.is_(True)).all() + elif download: + lofis = db.query(MediaLofi).filter(MediaLofi.should_download.is_(True)).all() + else: + lofis = db.query(MediaLofi).all() + for medialofi in lofis: + response = lofi_to_response(medialofi) + results.append(response) + return results + +@router.get("/lofi/{lofi_id}", response_model=MediaLofiResponse) +def get_lofi(lofi_id: str, db: SessionDep) -> MediaLofiResponse: + """ + Get MediaLofi by id. + """ + lofi = db.get(MediaLofi, lofi_id) + if lofi is None: + raise HTTPException(status_code=404, detail="MediaLofi could not be found") + response = lofi_to_response(lofi) + return response diff --git a/kontor-api/src/apis/version1/media/mediaactorfile.py b/kontor-api/src/apis/version1/media/mediaactorfile.py index 4748c93..97f436b 100644 --- a/kontor-api/src/apis/version1/media/mediaactorfile.py +++ b/kontor-api/src/apis/version1/media/mediaactorfile.py @@ -1,10 +1,10 @@ from typing import List from fastapi import APIRouter, status, HTTPException from src.core.log_conf import logger -from src.db.models.media import MediaActorFile -from src.db.repository.media.actorfile import delete_mediaactorfile, import_mediaactorfile +from kontor_model.db.models.media import MediaActorFile +from kontor_model.db.repository.media.actorfile import delete_mediaactorfile, import_mediaactorfile from src.db.session import SessionDep -from src.schema.media.actorfile import MediaActorFileModel, MediaActorFileResponse, actorfile_to_response +from kontor_model.schema.media.actorfile import MediaActorFileModel, MediaActorFileResponse, actorfile_to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/media/mediaarticle.py b/kontor-api/src/apis/version1/media/mediaarticle.py index cb19dc8..4c0b89d 100644 --- a/kontor-api/src/apis/version1/media/mediaarticle.py +++ b/kontor-api/src/apis/version1/media/mediaarticle.py @@ -3,9 +3,9 @@ from typing import List from fastapi import APIRouter -from src.db.models.media import MediaArticle +from kontor_model.db.models.media import MediaArticle from src.db.session import SessionDep -from src.schema.media.article import MediaArticleResponse, to_response +from kontor_model.schema.media.article import MediaArticleResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/media/mediavideo.py b/kontor-api/src/apis/version1/media/mediavideo.py index 5d57434..2dba52c 100644 --- a/kontor-api/src/apis/version1/media/mediavideo.py +++ b/kontor-api/src/apis/version1/media/mediavideo.py @@ -3,9 +3,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.media import MediaVideo +from kontor_model.db.models.media import MediaVideo from src.db.session import SessionDep -from src.schema.media.video import MediaVideoResponse, video_to_response +from kontor_model.schema.media.video import MediaVideoResponse, video_to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/tysc/card.py b/kontor-api/src/apis/version1/tysc/card.py index 98606d0..9449f34 100644 --- a/kontor-api/src/apis/version1/tysc/card.py +++ b/kontor-api/src/apis/version1/tysc/card.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.tysc import Card +from kontor_model.db.models.tysc import Card from src.db.session import SessionDep -from src.schema.tysc.card import CardResponse, to_response +from kontor_model.schema.tysc.card import CardResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/tysc/cardset.py b/kontor-api/src/apis/version1/tysc/cardset.py index a952d6c..3faa267 100644 --- a/kontor-api/src/apis/version1/tysc/cardset.py +++ b/kontor-api/src/apis/version1/tysc/cardset.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.tysc import CardSet +from kontor_model.db.models.tysc import CardSet from src.db.session import SessionDep -from src.schema.tysc.cardset import CardSetResponse, to_response +from kontor_model.schema.tysc.cardset import CardSetResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/tysc/fieldposition.py b/kontor-api/src/apis/version1/tysc/fieldposition.py index e46cf2e..d613940 100644 --- a/kontor-api/src/apis/version1/tysc/fieldposition.py +++ b/kontor-api/src/apis/version1/tysc/fieldposition.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.tysc import FieldPosition +from kontor_model.db.models.tysc import FieldPosition from src.db.session import SessionDep -from src.schema.tysc.fieldposition import FieldPositionResponse, to_response +from kontor_model.schema.tysc.fieldposition import FieldPositionResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/tysc/player.py b/kontor-api/src/apis/version1/tysc/player.py index d255166..c91296a 100644 --- a/kontor-api/src/apis/version1/tysc/player.py +++ b/kontor-api/src/apis/version1/tysc/player.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.tysc import Player +from kontor_model.db.models.tysc import Player from src.db.session import SessionDep -from src.schema.tysc.player import PlayerResponse, to_response +from kontor_model.schema.tysc.player import PlayerResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/tysc/rooster.py b/kontor-api/src/apis/version1/tysc/rooster.py index b6ee70c..7fd3187 100644 --- a/kontor-api/src/apis/version1/tysc/rooster.py +++ b/kontor-api/src/apis/version1/tysc/rooster.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.tysc import Rooster +from kontor_model.db.models.tysc import Rooster from src.db.session import SessionDep -from src.schema.tysc.rooster import RoosterResponse, to_response +from kontor_model.schema.tysc.rooster import RoosterResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/tysc/sport.py b/kontor-api/src/apis/version1/tysc/sport.py index 26ca581..1c712cc 100644 --- a/kontor-api/src/apis/version1/tysc/sport.py +++ b/kontor-api/src/apis/version1/tysc/sport.py @@ -3,8 +3,8 @@ from fastapi import APIRouter, HTTPException from src.core.log_conf import logger from src.db.session import SessionDep -from src.schema.tysc.sport import SportResponse, to_response -from src.db.models.tysc import Sport +from kontor_model.schema.tysc.sport import SportResponse, to_response +from kontor_model.db.models.tysc import Sport router = APIRouter() diff --git a/kontor-api/src/apis/version1/tysc/team.py b/kontor-api/src/apis/version1/tysc/team.py index 78acecc..d1a047e 100644 --- a/kontor-api/src/apis/version1/tysc/team.py +++ b/kontor-api/src/apis/version1/tysc/team.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.tysc import Team +from kontor_model.db.models.tysc import Team from src.db.session import SessionDep -from src.schema.tysc.team import TeamResponse, to_response +from kontor_model.schema.tysc.team import TeamResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/tysc/vendor.py b/kontor-api/src/apis/version1/tysc/vendor.py index a074d87..e86752b 100644 --- a/kontor-api/src/apis/version1/tysc/vendor.py +++ b/kontor-api/src/apis/version1/tysc/vendor.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.tysc import Vendor +from kontor_model.db.models.tysc import Vendor from src.db.session import SessionDep -from src.schema.tysc.vendor import VendorResponse, to_response +from kontor_model.schema.tysc.vendor import VendorResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/user/assignment.py b/kontor-api/src/apis/version1/user/assignment.py index 8a01556..64ee2e4 100644 --- a/kontor-api/src/apis/version1/user/assignment.py +++ b/kontor-api/src/apis/version1/user/assignment.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.admin import Assignment +from kontor_model.db.models.admin import Assignment from src.db.session import SessionDep -from src.schema.user.assignment import AssignmentResponse, to_response +from kontor_model.schema.user.assignment import AssignmentResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/user/permission.py b/kontor-api/src/apis/version1/user/permission.py index 6057b5f..4c99faa 100644 --- a/kontor-api/src/apis/version1/user/permission.py +++ b/kontor-api/src/apis/version1/user/permission.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter, HTTPException -from src.db.models.admin import Permission +from kontor_model.db.models.admin import Permission from src.db.session import SessionDep -from src.schema.user.permission import PermissionResponse, to_response +from kontor_model.schema.user.permission import PermissionResponse, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/user/profile.py b/kontor-api/src/apis/version1/user/profile.py index 2d7a768..7187d6d 100644 --- a/kontor-api/src/apis/version1/user/profile.py +++ b/kontor-api/src/apis/version1/user/profile.py @@ -4,10 +4,10 @@ from sqlalchemy import select from src.core.log_conf import logger from src.core.security import CurrentUser -from src.db.models.admin import Profile +from kontor_model.db.models.admin import Profile from src.db.repository.user import create_new_profile from src.db.session import SessionDep -from src.schema.user.profile import ProfileResponse, ProfileModel, to_response +from kontor_model.schema.user.profile import ProfileResponse, ProfileModel, to_response router = APIRouter() diff --git a/kontor-api/src/apis/version1/user/token.py b/kontor-api/src/apis/version1/user/token.py index f3a18ba..9a53e25 100644 --- a/kontor-api/src/apis/version1/user/token.py +++ b/kontor-api/src/apis/version1/user/token.py @@ -2,9 +2,9 @@ from typing import List from fastapi import APIRouter -from src.db.models.admin import Token +from kontor_model.db.models.admin import Token from src.db.session import SessionDep -from src.schema.user.token import TokenResponse, to_response +from kontor_model.schema.user.token import TokenResponse, to_response router = APIRouter() diff --git a/kontor-api/src/core/security.py b/kontor-api/src/core/security.py index aae17f0..3567de6 100644 --- a/kontor-api/src/core/security.py +++ b/kontor-api/src/core/security.py @@ -15,15 +15,15 @@ from pydantic import ValidationError from src.core.config import settings from src.core.log_conf import logger -from src.db.models.admin import Profile -from src.db.repository.admin import ( +from kontor_model.db.models.admin import Profile +from kontor_model.db.repository.admin import ( get_profile_by_username, get_profile_by_email, is_database_empty, ) from src.db.session import SessionLocal -from src.schema.admin.token import TokenData -from src.schema.user.profile import ProfileModel, to_model +from kontor_model.schema.admin.token import TokenData +from kontor_model.schema.user.profile import ProfileModel, to_model oauth2_scheme = OAuth2PasswordBearer( tokenUrl="/token", @@ -163,7 +163,7 @@ async def get_current_user( async def get_current_active_user( current_user: Annotated[Profile, Security(get_current_user, scopes=["me"])], ) -> ProfileModel: - if not current_user.enabled: + if not bool(current_user.enabled): raise HTTPException(status_code=400, detail="Inactive user") user_model = to_model(current_user) return user_model diff --git a/kontor-api/src/db/models/admin.py b/kontor-api/src/db/models/admin.py deleted file mode 100644 index 0640429..0000000 --- a/kontor-api/src/db/models/admin.py +++ /dev/null @@ -1,75 +0,0 @@ -from datetime import datetime -from typing import List - -from sqlalchemy import ForeignKey -from sqlalchemy.orm import relationship, mapped_column, Mapped - -from src.db.models.base import Base, BaseMixin - - -class Profile(Base, BaseMixin): - __tablename__ = 'profile' - first_name: Mapped[str] - last_name: Mapped[str] - user_name: Mapped[str] = mapped_column(nullable=False) - email: Mapped[str] - password: Mapped[str] - enabled: Mapped[bool] - assignments: Mapped[List["Assignment"]] = relationship(back_populates="profile") - tokens: Mapped[List["Token"]] = relationship(back_populates="profile") - - def get_full_name(self) -> str: - full_name: str = "" - if self.first_name is not None: - full_name += str(self.first_name) - if self.last_name is not None: - if len(full_name) > 0: - full_name += " " - full_name += str(self.last_name) - return full_name - - def __str__(self): - return f"Profile({self.id} {self.user_name}, {self.email})" - - -class Token(Base, BaseMixin): - __tablename__ = "token" - token: Mapped[str] = mapped_column(nullable=False, unique=True) - name: Mapped[str] - last_used_date: Mapped[datetime] - enabled: Mapped[bool] - profile_id = mapped_column(ForeignKey("profile.id"), nullable=False) - profile: Mapped[Profile] = relationship(back_populates="tokens") - - -class Permission(Base, BaseMixin): - __tablename__ = "permission" - name: Mapped[str] = mapped_column(nullable=False) - assignments: Mapped[List["Assignment"]] = relationship(back_populates="permission") - - -class Assignment(Base, BaseMixin): - __tablename__ = "assignment" - profile_id = mapped_column(ForeignKey("profile.id"), nullable=False) - profile: Mapped[Profile] = relationship(back_populates="assignments") - permission_id = mapped_column(ForeignKey("permission.id"), nullable=False) - permission: Mapped[Permission] = relationship(back_populates="assignments") - - -class MailAccount(Base, BaseMixin): - __tablename__ = "mail_account" - host: Mapped[str] - port: Mapped[int] - protocol: Mapped[str] - user_name: Mapped[str] - password: Mapped[str] - start_tls: Mapped[bool] - - -class Mail(Base, BaseMixin): - __tablename__ = "mail" - folder: Mapped[str] - subject: Mapped[str] - body: Mapped[str] - sent_date: Mapped[datetime] - received_date: Mapped[datetime] diff --git a/kontor-api/src/db/models/base.py b/kontor-api/src/db/models/base.py deleted file mode 100644 index cd7b6e2..0000000 --- a/kontor-api/src/db/models/base.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Optional -import uuid -from datetime import datetime - -from sqlalchemy import func -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column - - -class Base(DeclarativeBase): - pass - - -class BaseMixin: - id: Mapped[str] = mapped_column(primary_key=True, default=str(uuid.uuid4())) - created_date: Mapped[datetime] = mapped_column(default=func.now()) - last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) - version: Mapped[int] = mapped_column(default=0) - - -class BaseVideoMixin: - cloud_link: Mapped[Optional[str]] - file_name: Mapped[Optional[str]] - path: Mapped[str] - review: Mapped[bool] - title: Mapped[str] - url: Mapped[str] - should_download: Mapped[bool] diff --git a/kontor-api/src/db/models/bookshelf.py b/kontor-api/src/db/models/bookshelf.py deleted file mode 100644 index 8f9f25d..0000000 --- a/kontor-api/src/db/models/bookshelf.py +++ /dev/null @@ -1,52 +0,0 @@ -from typing import List - -from sqlalchemy import Column, ForeignKey, Integer, String -from sqlalchemy.orm import Mapped, mapped_column, relationship - -from src.db.models.base import Base, BaseMixin - - -class Article(Base, BaseMixin): - __tablename__ = 'article' - title: Mapped[str] = mapped_column(unique=True) - article_authors = relationship("ArticleAuthor") - - -class Author(Base, BaseMixin): - __tablename__ = 'author' - first_name: Mapped[str] - last_name: Mapped[str] - article_authors: Mapped[List["ArticleAuthor"]] = relationship(back_populates="author") - book_authors: Mapped[List["BookAuthor"]] = relationship(back_populates="author") - - -class BookshelfPublisher(Base, BaseMixin): - __tablename__ = 'bookshelf_publisher' - name: Mapped[str] = mapped_column(unique=True) - books: Mapped[List["Book"]] = relationship(back_populates="publisher") - - -class Book(Base, BaseMixin): - __tablename__ = 'book' - isbn: Mapped[str] = mapped_column(unique=True) - title: Mapped[str] - year: Mapped[int] = mapped_column(nullable=False) - publisher_id: Mapped[str] = mapped_column(ForeignKey("bookshelf_publisher.id"), nullable=False) - publisher: Mapped[BookshelfPublisher] = relationship(back_populates="books") - book_authors: Mapped[List["BookAuthor"]] = relationship(back_populates="book") - - -class ArticleAuthor(Base, BaseMixin): - __tablename__ = 'article_author' - article_id: Mapped[str] = mapped_column(ForeignKey("article.id"), nullable=False) - article: Mapped[Article] = relationship(back_populates="article_authors") - author_id: Mapped[str] = mapped_column(ForeignKey("author.id"), nullable=False) - author: Mapped[Author] = relationship(back_populates="article_authors") - - -class BookAuthor(Base, BaseMixin): - __tablename__ = 'book_author' - author_id: Mapped[str] = mapped_column(ForeignKey("author.id"), nullable=False) - author: Mapped[Author] = relationship(back_populates="book_authors") - book_id: Mapped[str] = mapped_column(ForeignKey("book.id"), nullable=False) - book: Mapped[Book] = relationship(back_populates="book_authors") diff --git a/kontor-api/src/db/models/comic.py b/kontor-api/src/db/models/comic.py deleted file mode 100644 index 6ce3f6a..0000000 --- a/kontor-api/src/db/models/comic.py +++ /dev/null @@ -1,188 +0,0 @@ -import uuid -from datetime import datetime -from typing import Dict, List, Optional, Any -from natsort import natsorted -from sqlalchemy import ForeignKey, func -from sqlalchemy.orm import relationship, Mapped, mapped_column - -from src.db.models.base import Base, BaseMixin - - -class Publisher(Base): - __tablename__ = "publisher" - id: Mapped[str] = mapped_column(primary_key=True, default=uuid.uuid4) - created_date: Mapped[datetime] = mapped_column(default=func.now()) - last_modified_date: Mapped[datetime] = mapped_column(default=func.now()) - version: Mapped[int] = mapped_column(default=0) - name: Mapped[str] = mapped_column(unique=True) - weblink: Mapped[Optional[str]] - parent_publisher_id: Mapped[Optional[str]] = mapped_column(ForeignKey('publisher.id')) - parent_publisher: Mapped[Optional['Publisher']] = relationship(back_populates="imprints", remote_side=[id]) - imprints: Mapped[List['Publisher']] = relationship(back_populates="parent_publisher") - comics: Mapped[List["Comic"]] = relationship(back_populates="publisher") - - def __repr__(self): - return f'Publisher({self.id} {self.name})' - - def __str__(self): - return self.__repr__() - - -class Comic(Base, BaseMixin): - __tablename__ = 'comic' - title: Mapped[str] = mapped_column(unique=True) - publisher_id: Mapped[str] = mapped_column(ForeignKey('publisher.id'), nullable=False) - publisher: Mapped[Publisher] = relationship(back_populates="comics") - current_order: Mapped[bool] - completed: Mapped[bool] - weblink: Mapped[Optional[str]] - issues: Mapped[List["Issue"]] = relationship(back_populates="comic", order_by="Issue.issue_number") - story_arcs: Mapped[List["StoryArc"]] = relationship(back_populates="comic") - trade_paperbacks: Mapped[List["TradePaperback"]] = relationship(back_populates="comic") - volumes: Mapped[List["Volume"]] = relationship(back_populates="comic") - comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="comic") - - def __repr__(self): - return f'Comic({self.id} {self.version} {self.title} {self.publisher.name})' - - def __str__(self): - return f'{self.title}({self.id})' - - def get_artists(self) -> Dict[Any, List[Any]]: - works: Dict[Any, List[Any]] = {} - for work in self.comic_works: - work_type = work.work_type - artist = work.artist - if work_type in works: - works[work_type].append(artist) - else: - works[work_type] = [artist] - return works - - def sorted_issues(self): - sorted_issues = natsorted(self.issues, key=lambda x: getattr(x, 'issue_number')) - return sorted_issues - - -class Volume(Base, BaseMixin): - __tablename__ = "volume" - name: Mapped[str] = mapped_column(nullable=False) - comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False) - comic: Mapped[Comic] = relationship(back_populates="volumes") - story_arcs: Mapped[List["StoryArc"]] = relationship(back_populates="volume") - issues: Mapped[List["Issue"]] = relationship(back_populates="volume") - - -class TradePaperback(Base, BaseMixin): - __tablename__ = "trade_paperback" - name: Mapped[str] = mapped_column(nullable=False) - issue_start: Mapped[int] - issue_end: Mapped[int] - comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False) - comic: Mapped[Comic] = relationship(back_populates="trade_paperbacks") - - -class StoryArc(Base, BaseMixin): - __tablename__ = "story_arc" - name: Mapped[str] = mapped_column(nullable=False) - comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False) - comic: Mapped[Comic] = relationship(back_populates="story_arcs") - volume_id: Mapped[str] = mapped_column(ForeignKey("volume.id"), nullable=True) - volume: Mapped[Volume] = relationship(back_populates="story_arcs") - issues: Mapped[List["Issue"]] = relationship(back_populates="story_arc") - - -class Issue(Base, BaseMixin): - __tablename__ = "issue" - issue_number: Mapped[str] - title: Mapped[Optional[str]] - published_on: Mapped[Optional[datetime]] - in_stock: Mapped[bool] - is_read: Mapped[bool] - comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False) - comic: Mapped[Comic] = relationship(back_populates="issues") - volume_id: Mapped[str] = mapped_column(ForeignKey("volume.id"), nullable=True) - volume: Mapped[Volume] = relationship(back_populates="issues") - story_arc_id: Mapped[str] = mapped_column(ForeignKey("story_arc.id"), nullable=True) - story_arc: Mapped[StoryArc] = relationship(back_populates="issues") - issue_works: Mapped[List["IssueWork"]] = relationship(back_populates="issue") - - def get_full_title(self) -> str: - full_title: str = str(self.issue_number) - if self.title: - full_title += str(": " + self.title) - return full_title - - def get_artists(self) -> Dict[Any, List[Any]]: - works: Dict[Any, List[Any]] = {} - for work in self.issue_works: - work_type = work.work_type - artist = work.artist - if work_type in works: - works[work_type].append(artist) - else: - works[work_type] = [artist] - return works - - -class Artist(Base, BaseMixin): - __tablename__ = "artist" - name: Mapped[str] = mapped_column(nullable=False) - weblink: Mapped[str] = mapped_column(nullable=True) - comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="artist") - issue_works: Mapped[List["IssueWork"]] = relationship(back_populates="artist") - - def get_comics(self) -> Dict[Any, List[Comic]]: - works: Dict[Any, List[Comic]] = {} - for work in self.comic_works: - work_type = work.work_type - comic = work.comic - if work_type in works: - works[work_type].append(comic) - else: - works[work_type] = [comic] - return works - - -class WorkType(Base, BaseMixin): - __tablename__ = "worktype" - name: Mapped[str] = mapped_column(nullable=False, unique=True) - comic_works: Mapped[List["ComicWork"]] = relationship(back_populates="work_type") - issue_works: Mapped[List["IssueWork"]] = relationship(back_populates="work_type") - - def get_artists(self) -> Dict[str, List[Artist]]: - works: Dict[str, List[Artist]] = {} - for work in self.comic_works: - comic = work.comic.title - artist = work.artist - if comic in works: - works[comic].append(artist) - else: - works[comic] = [artist] - return works - - def __repr__(self): - return f'Worktype({self.id} {self.version} {self.name} {len(self.comic_works)})' - - def __str__(self): - return f'{self.name}({self.id})' - - -class ComicWork(Base, BaseMixin): - __tablename__ = "comic_work" - comic_id: Mapped[str] = mapped_column(ForeignKey("comic.id"), nullable=False) - comic: Mapped[Comic] = relationship(back_populates="comic_works") - artist_id: Mapped[str] = mapped_column(ForeignKey("artist.id"), nullable=False) - artist: Mapped[Artist] = relationship(back_populates="comic_works") - work_type_id: Mapped[str] = mapped_column(ForeignKey("worktype.id"), nullable=False) - work_type: Mapped[WorkType] = relationship(back_populates="comic_works") - - -class IssueWork(Base, BaseMixin): - __tablename__ = "issue_work" - issue_id: Mapped[str] = mapped_column(ForeignKey("issue.id"), nullable=False) - issue: Mapped[Issue] = relationship(back_populates="issue_works") - artist_id: Mapped[str] = mapped_column(ForeignKey("artist.id"), nullable=False) - artist: Mapped[Artist] = relationship(back_populates="issue_works") - work_type_id: Mapped[str] = mapped_column(ForeignKey("worktype.id"), nullable=False) - work_type: Mapped[WorkType] = relationship(back_populates="issue_works") diff --git a/kontor-api/src/db/models/media.py b/kontor-api/src/db/models/media.py deleted file mode 100644 index 3cee822..0000000 --- a/kontor-api/src/db/models/media.py +++ /dev/null @@ -1,97 +0,0 @@ -import logging -import re -import subprocess -from datetime import datetime -from pathlib import Path -from typing import List, Optional - -import requests -from bs4 import BeautifulSoup -from sqlalchemy import ForeignKey -from sqlalchemy.orm import Mapped, relationship, mapped_column - -from src.db.models.base import Base, BaseMixin, BaseVideoMixin - - -class MediaFile(Base, BaseMixin, BaseVideoMixin): - """ - MediaFile represents video link. - """ - - __tablename__ = "media_file" - media_actor_files: Mapped[List["MediaActorFile"]] = relationship( - back_populates="media_file" - ) - - def __repr__(self): - return f"MediaFile({self.id} {self.title} {self.title})" - - def __str__(self): - return f"{self.title}({self.id})" - - def update_title(self): - """ - Update title from url. - """ - - -class MediaActor(Base, BaseMixin): - __tablename__ = "media_actor" - name: Mapped[str] - url: Mapped[Optional[str]] = mapped_column(unique=True) - media_actor_files = relationship("MediaActorFile") - - def __repr__(self) -> str: - return f"MediaActor({self.id} {self.name} {self.url})" - - def __str__(self) -> str: - return f"{self.url}({self.id})" - - -class MediaActorFile(Base, BaseMixin): - __tablename__ = "media_actor_file" - media_actor_id: Mapped[str] = mapped_column( - ForeignKey("media_actor.id"), nullable=False - ) - media_actor: Mapped[MediaActor] = relationship(back_populates="media_actor_files") - media_file_id: Mapped[str] = mapped_column( - ForeignKey("media_file.id"), nullable=True - ) - media_file: Mapped[MediaFile] = relationship(back_populates="media_actor_files") - - def __repr__(self): - return f"MediaActorFile({self.id} {self.media_actor_id} {self.media_file_id})" - - def __str__(self) -> str: - return f"{self.id} {self.media_actor_id} {self.media_file_id}" - - -class MediaArticle(Base, BaseMixin): - __tablename__ = "media_article" - review: Mapped[bool] - title: Mapped[str] - url: Mapped[str] = mapped_column(unique=True) - - -class MediaVideo(Base, BaseMixin): - """ - MediaFile represents video link. - """ - - __tablename__ = "media_video" - cloud_link: Mapped[str] - file_name: Mapped[str] - path: Mapped[str] - review: Mapped[bool] - title: Mapped[str] - url: Mapped[str] = mapped_column(unique=True) - should_download: Mapped[bool] - - def __repr__(self): - return f"MediaFile({self.id} {self.title} {self.url})" - - def __str__(self): - if self.title is None: - return f"{self.url}({self.id})" - else: - return f"{self.title}({self.id})" diff --git a/kontor-api/src/db/models/tysc.py b/kontor-api/src/db/models/tysc.py deleted file mode 100644 index 635c3ea..0000000 --- a/kontor-api/src/db/models/tysc.py +++ /dev/null @@ -1,100 +0,0 @@ -from typing import List -from sqlalchemy import ForeignKey, UniqueConstraint -from sqlalchemy.orm import relationship, mapped_column, Mapped - -from src.db.models.base import Base, BaseMixin - - -class Sport(Base, BaseMixin): - __tablename__ = "sport" - __table_args__ = ( - UniqueConstraint("name"), - ) - name: Mapped[str] = mapped_column(nullable=False, index=True, unique=True) - teams: Mapped[List["Team"]] = relationship(back_populates="sport") - positions: Mapped[List["FieldPosition"]] = relationship(back_populates="sport") - - -class Team(Base, BaseMixin): - __tablename__ = "team" - name: Mapped[str] = mapped_column(nullable=False, index=True, unique=True) - short_name: Mapped[str] = mapped_column(nullable=False) - sport_id: Mapped[str] = mapped_column(ForeignKey("sport.id"), nullable=False) - sport: Mapped[Sport] = relationship(back_populates="teams") - roosters: Mapped[List["Rooster"]] = relationship(back_populates="team") - - -class FieldPosition(Base, BaseMixin): - __tablename__ = "field_position" - __table_args__ = ( - UniqueConstraint("name", "sport_id"), - UniqueConstraint("short_name", "sport_id"), - ) - name: Mapped[str] = mapped_column(nullable=False, index=True) - short_name: Mapped[str] = mapped_column(nullable=False) - sport_id: Mapped[str] = mapped_column(ForeignKey("sport.id"), nullable=False, index=True) - sport: Mapped[Sport] = relationship(back_populates="positions") - roosters: Mapped[List["Rooster"]] = relationship(back_populates="position") - - -class Player(Base, BaseMixin): - __tablename__ = "player" - __table_args__ = ( - UniqueConstraint("first_name", "last_name"), - ) - first_name: Mapped[str] = mapped_column(nullable=False, index=True) - last_name: Mapped[str] = mapped_column(nullable=False, index=True) - roosters: Mapped[List["Rooster"]] = relationship(back_populates="player") - - def get_full_name(self) -> str: - return f"{self.last_name}, {self.first_name}" - - -class Rooster(Base, BaseMixin): - __tablename__ = "rooster" - __table_args__ = ( - UniqueConstraint("year", "team_id", "player_id", "position_id"), - ) - year: Mapped[int] - team_id: Mapped[str] = mapped_column(ForeignKey("team.id"), nullable=False, index=True) - team: Mapped[Team] = relationship(back_populates="roosters") - player_id: Mapped[str] = mapped_column(ForeignKey("player.id"), nullable=False, index=True) - player: Mapped[Player] = relationship(back_populates="roosters") - position_id: Mapped[str] = mapped_column(ForeignKey("field_position.id"), nullable=False, index=True) - position: Mapped[FieldPosition] = relationship(back_populates="roosters") - cards: Mapped[List["Card"]] = relationship(back_populates="rooster") - - -class Vendor(Base, BaseMixin): - __tablename__ = "vendor" - name: Mapped[str] = mapped_column(nullable=False, unique=True, index=True) - card_sets: Mapped[List["CardSet"]] = relationship(back_populates="vendor") - cards: Mapped[List["Card"]] = relationship(back_populates="vendor") - - -class CardSet(Base, BaseMixin): - __tablename__ = "card_set" - __table_args__ = ( - UniqueConstraint("name", "vendor_id"), - ) - name: Mapped[str] = mapped_column(index=True) - parallel_set: Mapped[bool] - insert_set: Mapped[bool] - vendor_id: Mapped[str] = mapped_column(ForeignKey("vendor.id"), nullable=False, index=True) - vendor: Mapped[Vendor] = relationship(back_populates="card_sets") - cards: Mapped[List["Card"]] = relationship(back_populates="card_set") - - -class Card(Base, BaseMixin): - __tablename__ = "card" - __table_args__ = ( - UniqueConstraint("card_number", "year", "vendor_id", "card_set_id"), - ) - card_number: Mapped[int] = mapped_column(index=True) - year: Mapped[int] = mapped_column(index=True) - card_set_id: Mapped[str] = mapped_column(ForeignKey("card_set.id"), nullable=False) - card_set: Mapped[CardSet] = relationship(back_populates="cards") - rooster_id: Mapped[str] = mapped_column(ForeignKey("rooster.id"), nullable=False) - rooster: Mapped[Rooster] = relationship(back_populates="cards") - vendor_id: Mapped[str] = mapped_column(ForeignKey("vendor.id"), nullable=False) - vendor: Mapped[Vendor] = relationship(back_populates="cards") diff --git a/kontor-api/src/db/repository/comics/publisher.py b/kontor-api/src/db/repository/comics/publisher.py deleted file mode 100644 index a17da64..0000000 --- a/kontor-api/src/db/repository/comics/publisher.py +++ /dev/null @@ -1,24 +0,0 @@ -from typing import List - -from src.db.models.comic import Publisher -from src.schema.comics.comic import ComicResponse -from src.schema.comics.publisher import PublisherResponse -from src.schema.comics.publisher_details import PublisherDetailsResponse - - -def get_publisher_details(publisher: Publisher) -> PublisherDetailsResponse: - imprints: List[PublisherResponse] = [] - for imprint in publisher.imprints: - imprints.append(PublisherResponse(id=imprint.id, name=str(imprint.name))) - comics: List[ComicResponse] = [] - for comic in publisher.comics: - comics.append( - ComicResponse(id=comic.id, title=comic.title, completed=comic.completed) - ) - parent_publisher: PublisherResponse | None = None - if publisher.parent_publisher: - parent_publisher = PublisherResponse(id=publisher.parent_publisher.id, name=str(publisher.parent_publisher.name)) - response: PublisherDetailsResponse = PublisherDetailsResponse( - id=publisher.id, name=str(publisher.name), parent_publisher=parent_publisher, imprints=imprints, comics=comics - ) - return response diff --git a/kontor-api/src/db/repository/user.py b/kontor-api/src/db/repository/user.py index 597f262..96deafa 100644 --- a/kontor-api/src/db/repository/user.py +++ b/kontor-api/src/db/repository/user.py @@ -2,10 +2,10 @@ from datetime import datetime from typing import Optional import uuid from src.core.log_conf import logger -from src.db.models.admin import Assignment, Profile +from kontor_model.db.models.admin import Assignment, Profile from sqlalchemy.orm import Session -from src.schema.user.profile import ProfileModel +from kontor_model.schema.user.profile import ProfileModel def create_new_profile(new_profile: ProfileModel, db: Session) -> Profile: diff --git a/kontor-api/src/main.py b/kontor-api/src/main.py index f090518..f1e715d 100644 --- a/kontor-api/src/main.py +++ b/kontor-api/src/main.py @@ -10,7 +10,7 @@ from src.apis.version1.admin.login import login_router from src.core.config import settings from src.core.log_conf import logger from src.core.middleware import RequestLoggingMiddleware -from src.db.models.base import Base +from kontor_model.db.models.base import Base from src.db.session import engine from src.db.utils import check_db_connected, check_db_disconnected from src.webapps.base import api_router as web_app_router diff --git a/kontor-api/src/templates/media/add_lofi_link.html b/kontor-api/src/templates/media/add_lofi_link.html new file mode 100644 index 0000000..f38bbb1 --- /dev/null +++ b/kontor-api/src/templates/media/add_lofi_link.html @@ -0,0 +1,29 @@ +{% extends "shared/base.html" %} + + +{% block title %} + Add a Lofi Link +{% endblock %} + +{% block content %} +
+
+
+ {% for error in errors %} +
  • {{error}}
  • + {% endfor %} +
    +
    + +
    +

    Add a Lofi Link

    +
    +
    + +
    + +
    +
    +
    +{% endblock %} + diff --git a/kontor-api/src/templates/media/lofi_detail.html b/kontor-api/src/templates/media/lofi_detail.html new file mode 100644 index 0000000..e6397db --- /dev/null +++ b/kontor-api/src/templates/media/lofi_detail.html @@ -0,0 +1,51 @@ +{% extends "shared/base.html" %} + + +{% block title %} + MediaLofi Detail +{% endblock %} + +{% block content %} +
    +
    +
    +

    MediaLofi Detail

    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MediaLofi Title{{medialofi.title}}
    MediaLofi URL{{medialofi.url}}
    MediaLofi Download?{{medialofi.should_download}}
    MediaLofi Review?{{medialofi.review}}
    Data Created{{medialofi.created_date}}
    Data Modified{{medialofi.last_modified_date}}
    Data Version{{medialofi.version}}
    +
    +
    +{% endblock %} diff --git a/kontor-api/src/templates/media/lofi_list.html b/kontor-api/src/templates/media/lofi_list.html new file mode 100644 index 0000000..76d3de4 --- /dev/null +++ b/kontor-api/src/templates/media/lofi_list.html @@ -0,0 +1,29 @@ +{% extends "shared/base.html" %} + +{% block title %} + Lofi Links +{% endblock %} + +{% block content %} + {% with msg=msg %} + {% include "components/alerts.html" %} + {% endwith %} +
    + + + + + + + + {% for medialofi in medialofis %} + + + + + + {% endfor %} + +
    TitelReviewDownload
    {{medialofi.title}}{% with check=medialofi.review %}{% include "components/check.html" %}{% endwith %}{% with check=medialofi.should_download %}{% include "components/check.html" %}{% endwith %}
    +
    +{% endblock %} diff --git a/kontor-api/src/templates/media/media_nav.html b/kontor-api/src/templates/media/media_nav.html index 104176b..a9758ac 100644 --- a/kontor-api/src/templates/media/media_nav.html +++ b/kontor-api/src/templates/media/media_nav.html @@ -2,4 +2,5 @@ MediaFiles MediaActors MediaVideos + MediaLofi diff --git a/kontor-api/src/webapps/admin/route_admin.py b/kontor-api/src/webapps/admin/route_admin.py index 0e7f611..114ad09 100644 --- a/kontor-api/src/webapps/admin/route_admin.py +++ b/kontor-api/src/webapps/admin/route_admin.py @@ -2,7 +2,7 @@ from typing import Optional from fastapi import APIRouter, Request from fastapi.templating import Jinja2Templates -from src.db.models.admin import Permission, Profile +from kontor_model.db.models.admin import Permission, Profile from src.db.session import SessionDep templates = Jinja2Templates(directory="src/templates") diff --git a/kontor-api/src/webapps/base.py b/kontor-api/src/webapps/base.py index 42ba071..16a1ad0 100644 --- a/kontor-api/src/webapps/base.py +++ b/kontor-api/src/webapps/base.py @@ -4,7 +4,7 @@ from fastapi.templating import Jinja2Templates from src.webapps.admin import route_admin from src.webapps.auth import route_login from src.webapps.comic import route_comics, route_worktype, route_artists -from src.webapps.media import route_actors, route_media, route_videos +from src.webapps.media import route_actors, route_lofi, route_media, route_videos templates = Jinja2Templates(directory="src/templates") @@ -15,6 +15,7 @@ api_router.include_router(route_worktype.router, tags=["webapp"]) api_router.include_router(route_media.router, tags=["webapp"]) api_router.include_router(route_actors.router, tags=["webapp"]) api_router.include_router(route_videos.router, tags=["webapp"]) +api_router.include_router(route_lofi.router, tags=["webapp"]) api_router.include_router(route_login.router, tags=["webapp"]) api_router.include_router(route_admin.router, tags=["webapp"]) diff --git a/kontor-api/src/webapps/comic/route_artists.py b/kontor-api/src/webapps/comic/route_artists.py index d6735d9..94d2729 100644 --- a/kontor-api/src/webapps/comic/route_artists.py +++ b/kontor-api/src/webapps/comic/route_artists.py @@ -2,14 +2,13 @@ from fastapi import APIRouter, Request, status, Form from fastapi.templating import Jinja2Templates from fastapi.responses import RedirectResponse -from src.db.models.comic import Artist +from kontor_model.db.models.comic import Artist from typing import AnyStr -from src.db.repository.comics.artist import update_artist +from kontor_model.db.repository.comics.artist import update_artist from src.db.session import SessionDep #from src.db.repository.comic import create_new_worktype, update_worktype -from src.main import logger -from src.schema.comics.artist import AddArtist +from kontor_model.schema.comics.artist import AddArtist from src.webapps.comic.forms.artist import AddArtistForm #from src.schema.comics.worktype import AddWorkType @@ -35,7 +34,7 @@ def edit_artist(db: SessionDep, request: Request, artist_id: str): return templates.TemplateResponse("comic/artist_edit.html", {"request": request, "artist_name": artist.name, "artist_link": artist.weblink}) @router.post("/artist/edit/{artist_id}") -async def edit_artist(request: Request, db: SessionDep, artist_id: str, action: str = Form(...), artist_name: str = Form(...), artist_link: str = Form(...)): +async def edit_artist_post(request: Request, db: SessionDep, artist_id: str, action: str = Form(...), artist_name: str = Form(...), artist_link: str = Form(...)): if action == "cancel": return RedirectResponse(f"/comic/artists/{artist_id}", status_code=status.HTTP_303_SEE_OTHER) form = AddArtistForm(request, artist_id, artist_name, artist_link) diff --git a/kontor-api/src/webapps/comic/route_comics.py b/kontor-api/src/webapps/comic/route_comics.py index 9285273..cb1c572 100644 --- a/kontor-api/src/webapps/comic/route_comics.py +++ b/kontor-api/src/webapps/comic/route_comics.py @@ -2,12 +2,12 @@ from fastapi import APIRouter, Form, Request, status from fastapi.templating import Jinja2Templates from fastapi.responses import RedirectResponse -from src.db.models.comic import Comic, Publisher, Issue +from kontor_model.db.models.comic import Comic, Publisher, Issue from typing import AnyStr from src.core.log_conf import logger -from src.db.repository.comics.comic import update_comic +from kontor_model.db.repository.comics.comic import update_comic from src.db.session import SessionDep -from src.schema.comics.comic import ComicSchema +from kontor_model.schema.comics.comic import ComicSchema from src.webapps.comic.forms.comic import ValidateComicForm templates = Jinja2Templates(directory="src/templates") diff --git a/kontor-api/src/webapps/comic/route_worktype.py b/kontor-api/src/webapps/comic/route_worktype.py index 365dc76..bff9025 100644 --- a/kontor-api/src/webapps/comic/route_worktype.py +++ b/kontor-api/src/webapps/comic/route_worktype.py @@ -2,13 +2,13 @@ from fastapi import APIRouter, Request, status from fastapi.templating import Jinja2Templates from fastapi.responses import RedirectResponse -from src.db.models.comic import WorkType +from kontor_model.db.models.comic import WorkType from typing import AnyStr -from src.db.repository.comics.worktype import create_new_worktype, update_worktype +from kontor_model.db.repository.comics.worktype import create_new_worktype, update_worktype from src.db.session import SessionDep from src.main import logger -from src.schema.comics.worktype import AddWorkType +from kontor_model.schema.comics.worktype import AddWorkType from src.webapps.comic.forms.worktype import AddWorktypeForm templates = Jinja2Templates(directory="src/templates") diff --git a/kontor-api/src/webapps/media/route_actors.py b/kontor-api/src/webapps/media/route_actors.py index 63bcce8..9624e3a 100644 --- a/kontor-api/src/webapps/media/route_actors.py +++ b/kontor-api/src/webapps/media/route_actors.py @@ -2,7 +2,7 @@ from typing import AnyStr from fastapi import APIRouter, Request from fastapi.templating import Jinja2Templates -from src.db.models.media import MediaActor +from kontor_model.db.models.media import MediaActor from src.db.session import SessionDep templates = Jinja2Templates(directory="src/templates") diff --git a/kontor-api/src/webapps/media/route_lofi.py b/kontor-api/src/webapps/media/route_lofi.py new file mode 100644 index 0000000..9b934a7 --- /dev/null +++ b/kontor-api/src/webapps/media/route_lofi.py @@ -0,0 +1,51 @@ +from typing import Optional + +from fastapi import APIRouter, Request, status, responses +from fastapi.security.utils import get_authorization_scheme_param +from fastapi.templating import Jinja2Templates + +from src.core.security import get_current_user_from_token +from kontor_model.db.models.media import MediaLofi +from kontor_model.db.models.admin import Profile +from kontor_model.db.repository.media.lofi import create_new_lofi +from src.db.session import SessionDep +from src.webapps.media.forms import AddLinkForm + +templates = Jinja2Templates(directory="src/templates") +router = APIRouter(include_in_schema=False, prefix="/media") + +@router.get("/lofi") +def get_medialofis(db: SessionDep, request: Request, msg: Optional[str] = None): + medialofis = db.query(MediaLofi).all() + try: + token = request.cookies.get("access_token") + _, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value + current_user: Profile = get_current_user_from_token(token=param) + return templates.TemplateResponse("media/lofi_list.html", {"request": request, "msg": msg, "user": current_user, "medialofis": medialofis}) + except Exception as e: + print(e) + return templates.TemplateResponse("media/lofi_list.html", {"request": request, "msg": msg, "user": None, "medialofis": medialofis}) + +@router.get("/lofi/{lofi_id}") +def lofi_details(lofi_id: str, request: Request, db: SessionDep): + medialofi = db.get(MediaLofi, lofi_id) + return templates.TemplateResponse("media/lofi_detail.html", {"request": request, "medialofi":medialofi}) + +@router.get("/add-lofi") +def add_lofi_link(request: Request, db: SessionDep): + return templates.TemplateResponse("media/add_lofi_link.html", {"request": request}) + +@router.post("/add-lofi") +async def post_lofi_link(request: Request, db: SessionDep): + form = AddLinkForm(request) + await form.load_data() + if form.is_valid(): + try: + #video = AddLink(**form.__dict__) + medialofi = create_new_lofi(url=str(form.url), db=db) + return responses.RedirectResponse(f"media/lofi/{medialofi.id}", status_code=status.HTTP_302_FOUND) + except Exception as e: + print(e) + form.__dict__.get("errors").append("Link already added") + return templates.TemplateResponse("media/add_lofi_link.html", form.__dict__) + return templates.TemplateResponse("media/add_lofi_link.html", form.__dict__) diff --git a/kontor-api/src/webapps/media/route_media.py b/kontor-api/src/webapps/media/route_media.py index 9b1e7a8..1ffbefd 100644 --- a/kontor-api/src/webapps/media/route_media.py +++ b/kontor-api/src/webapps/media/route_media.py @@ -6,8 +6,8 @@ from fastapi.templating import Jinja2Templates from sqlalchemy import or_ from src.core.security import get_current_user_from_token -from src.db.models.admin import Profile -from src.db.models.media import MediaFile +from kontor_model.db.models.admin import Profile +from kontor_model.db.models.media import MediaFile from src.core.log_conf import logger from src.db.session import SessionDep @@ -37,7 +37,7 @@ def get_mediafiles(db: SessionDep, request: Request, msg: str | None = None): try: token = request.cookies.get("access_token") scheme, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value - current_user: Profile = get_current_user_from_token(token=param) + #current_user: Profile = get_current_user_from_token(token=param) return templates.TemplateResponse("media/files.html", {"request": request, "msg": msg, "mediafiles": mediafiles}) except Exception as e: print(e) diff --git a/kontor-api/src/webapps/media/route_videos.py b/kontor-api/src/webapps/media/route_videos.py index f147306..b4c3cd2 100644 --- a/kontor-api/src/webapps/media/route_videos.py +++ b/kontor-api/src/webapps/media/route_videos.py @@ -1,11 +1,13 @@ +from typing import Optional + from fastapi import APIRouter, Request, status, responses from fastapi.security.utils import get_authorization_scheme_param from fastapi.templating import Jinja2Templates from src.core.security import get_current_user_from_token -from src.db.models.media import MediaVideo -from src.db.models.admin import Profile -from src.db.repository.media.video import create_new_video +from kontor_model.db.models.media import MediaVideo +from kontor_model.db.models.admin import Profile +from kontor_model.db.repository.media.video import create_new_video from src.db.session import SessionDep from src.webapps.media.forms import AddLinkForm @@ -13,12 +15,12 @@ templates = Jinja2Templates(directory="src/templates") router = APIRouter(include_in_schema=False, prefix="/media") @router.get("/videos") -def get_mediavideos(db: SessionDep, request: Request, msg: str = None): +def get_mediavideos(db: SessionDep, request: Request, msg: Optional[str] = None): mediavideos = db.query(MediaVideo).all() try: token = request.cookies.get("access_token") _, param = get_authorization_scheme_param(token) # scheme will hold "Bearer" and param will hold actual token value - current_user: Profile = get_current_user_from_token(token=param, db=db) + current_user: Profile = get_current_user_from_token(token=param) return templates.TemplateResponse("media/videos.html", {"request": request, "msg": msg, "user": current_user, "mediavideos": mediavideos}) except Exception as e: print(e) @@ -40,7 +42,7 @@ async def post_video_link(request: Request, db: SessionDep): if form.is_valid(): try: #video = AddLink(**form.__dict__) - mediavideo = create_new_video(video=form, db=db) + mediavideo = create_new_video(url=str(form.url), db=db) return responses.RedirectResponse(f"media/videos/{mediavideo.id}", status_code=status.HTTP_302_FOUND) except Exception as e: print(e) diff --git a/kontor-api/tests/conftest.py b/kontor-api/tests/conftest.py index d3afb43..ffb24d6 100644 --- a/kontor-api/tests/conftest.py +++ b/kontor-api/tests/conftest.py @@ -11,7 +11,7 @@ from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker from src.apis.base import api_router -from src.db.models.base import Base +from kontor_model.db.models.base import Base from src.db.session import get_db sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/kontor-api/uv.lock b/kontor-api/uv.lock index 26dd456..0669c43 100644 --- a/kontor-api/uv.lock +++ b/kontor-api/uv.lock @@ -524,12 +524,12 @@ dependencies = [ { name = "fastapi-jwt-auth" }, { name = "httpx" }, { name = "jinja2" }, + { name = "kontor-model" }, { name = "msgspec", extra = ["toml", "yaml"] }, { name = "natsort" }, { name = "pathlib" }, { name = "platformdirs" }, { name = "psycopg2-binary" }, - { name = "pydantic", extra = ["email"] }, { name = "pytest" }, { name = "pytest-cov" }, { name = "python-dotenv" }, @@ -551,12 +551,12 @@ requires-dist = [ { name = "fastapi-jwt-auth", specifier = ">=0.5.0" }, { name = "httpx", specifier = "==0.24.1" }, { name = "jinja2", specifier = ">=3.1.6" }, + { name = "kontor-model", editable = "../kontor-model" }, { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, { name = "natsort", specifier = ">=8.4.0" }, { name = "pathlib", specifier = ">=1.0.1" }, { name = "platformdirs", specifier = ">=4.3.7" }, { name = "psycopg2-binary", specifier = ">=2.9.10" }, - { name = "pydantic", extras = ["email"], specifier = ">=2.11.3" }, { name = "pytest", specifier = "==7.4.0" }, { name = "pytest-cov", specifier = ">=6.1.1" }, { name = "python-dotenv", specifier = ">=1.1.0" }, @@ -568,6 +568,23 @@ requires-dist = [ { name = "sqlmodel", specifier = ">=0.0.24" }, ] +[[package]] +name = "kontor-model" +version = "0.3.0" +source = { editable = "../kontor-model" } +dependencies = [ + { name = "msgspec", extra = ["toml", "yaml"] }, + { name = "pydantic", extra = ["email"] }, + { name = "sqlalchemy" }, +] + +[package.metadata] +requires-dist = [ + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, + { name = "pydantic", extras = ["email"], specifier = ">=2.13.4" }, + { name = "sqlalchemy", specifier = ">=2.0.52" }, +] + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -741,7 +758,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.3" +version = "2.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -749,9 +766,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/10/2e/ca897f093ee6c5f3b0bee123ee4465c50e75431c3d5b6a3b44a47134e891/pydantic-2.11.3.tar.gz", hash = "sha256:7471657138c16adad9322fe3070c0116dd6c3ad8d649300e3cbdfe91f4db4ec3", size = 785513, upload-time = "2025-04-08T13:27:06.399Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b0/1d/407b29780a289868ed696d1616f4aad49d6388e5a77f567dcd2629dcd7b8/pydantic-2.11.3-py3-none-any.whl", hash = "sha256:a082753436a07f9ba1289c6ffa01cd93db3548776088aa917cc43b63f68fa60f", size = 443591, upload-time = "2025-04-08T13:27:03.789Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, ] [package.optional-dependencies] @@ -761,30 +778,58 @@ email = [ [[package]] name = "pydantic-core" -version = "2.33.1" +version = "2.46.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/19/ed6a078a5287aea7922de6841ef4c06157931622c89c2a47940837b5eecd/pydantic_core-2.33.1.tar.gz", hash = "sha256:bcc9c6fdb0ced789245b02b7d6603e17d1563064ddcfc36f046b61c0c05dd9df", size = 434395, upload-time = "2025-04-02T09:49:41.8Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/24/eed3466a4308d79155f1cdd5c7432c80ddcc4530ba8623b79d5ced021641/pydantic_core-2.33.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70af6a21237b53d1fe7b9325b20e65cbf2f0a848cf77bed492b029139701e66a", size = 2033551, upload-time = "2025-04-02T09:47:51.648Z" }, - { url = "https://files.pythonhosted.org/packages/ab/14/df54b1a0bc9b6ded9b758b73139d2c11b4e8eb43e8ab9c5847c0a2913ada/pydantic_core-2.33.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:282b3fe1bbbe5ae35224a0dbd05aed9ccabccd241e8e6b60370484234b456266", size = 1852785, upload-time = "2025-04-02T09:47:53.149Z" }, - { url = "https://files.pythonhosted.org/packages/fa/96/e275f15ff3d34bb04b0125d9bc8848bf69f25d784d92a63676112451bfb9/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b315e596282bbb5822d0c7ee9d255595bd7506d1cb20c2911a4da0b970187d3", size = 1897758, upload-time = "2025-04-02T09:47:55.006Z" }, - { url = "https://files.pythonhosted.org/packages/b7/d8/96bc536e975b69e3a924b507d2a19aedbf50b24e08c80fb00e35f9baaed8/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dfae24cf9921875ca0ca6a8ecb4bb2f13c855794ed0d468d6abbec6e6dcd44a", size = 1986109, upload-time = "2025-04-02T09:47:56.532Z" }, - { url = "https://files.pythonhosted.org/packages/90/72/ab58e43ce7e900b88cb571ed057b2fcd0e95b708a2e0bed475b10130393e/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6dd8ecfde08d8bfadaea669e83c63939af76f4cf5538a72597016edfa3fad516", size = 2129159, upload-time = "2025-04-02T09:47:58.088Z" }, - { url = "https://files.pythonhosted.org/packages/dc/3f/52d85781406886c6870ac995ec0ba7ccc028b530b0798c9080531b409fdb/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f593494876eae852dc98c43c6f260f45abdbfeec9e4324e31a481d948214764", size = 2680222, upload-time = "2025-04-02T09:47:59.591Z" }, - { url = "https://files.pythonhosted.org/packages/f4/56/6e2ef42f363a0eec0fd92f74a91e0ac48cd2e49b695aac1509ad81eee86a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948b73114f47fd7016088e5186d13faf5e1b2fe83f5e320e371f035557fd264d", size = 2006980, upload-time = "2025-04-02T09:48:01.397Z" }, - { url = "https://files.pythonhosted.org/packages/4c/c0/604536c4379cc78359f9ee0aa319f4aedf6b652ec2854953f5a14fc38c5a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e11f3864eb516af21b01e25fac915a82e9ddad3bb0fb9e95a246067398b435a4", size = 2120840, upload-time = "2025-04-02T09:48:03.056Z" }, - { url = "https://files.pythonhosted.org/packages/1f/46/9eb764814f508f0edfb291a0f75d10854d78113fa13900ce13729aaec3ae/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:549150be302428b56fdad0c23c2741dcdb5572413776826c965619a25d9c6bde", size = 2072518, upload-time = "2025-04-02T09:48:04.662Z" }, - { url = "https://files.pythonhosted.org/packages/42/e3/fb6b2a732b82d1666fa6bf53e3627867ea3131c5f39f98ce92141e3e3dc1/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:495bc156026efafd9ef2d82372bd38afce78ddd82bf28ef5276c469e57c0c83e", size = 2248025, upload-time = "2025-04-02T09:48:06.226Z" }, - { url = "https://files.pythonhosted.org/packages/5c/9d/fbe8fe9d1aa4dac88723f10a921bc7418bd3378a567cb5e21193a3c48b43/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ec79de2a8680b1a67a07490bddf9636d5c2fab609ba8c57597e855fa5fa4dacd", size = 2254991, upload-time = "2025-04-02T09:48:08.114Z" }, - { url = "https://files.pythonhosted.org/packages/aa/99/07e2237b8a66438d9b26482332cda99a9acccb58d284af7bc7c946a42fd3/pydantic_core-2.33.1-cp313-cp313-win32.whl", hash = "sha256:ee12a7be1742f81b8a65b36c6921022301d466b82d80315d215c4c691724986f", size = 1915262, upload-time = "2025-04-02T09:48:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/8a/f4/e457a7849beeed1e5defbcf5051c6f7b3c91a0624dd31543a64fc9adcf52/pydantic_core-2.33.1-cp313-cp313-win_amd64.whl", hash = "sha256:ede9b407e39949d2afc46385ce6bd6e11588660c26f80576c11c958e6647bc40", size = 1956626, upload-time = "2025-04-02T09:48:11.288Z" }, - { url = "https://files.pythonhosted.org/packages/20/d0/e8d567a7cff7b04e017ae164d98011f1e1894269fe8e90ea187a3cbfb562/pydantic_core-2.33.1-cp313-cp313-win_arm64.whl", hash = "sha256:aa687a23d4b7871a00e03ca96a09cad0f28f443690d300500603bd0adba4b523", size = 1909590, upload-time = "2025-04-02T09:48:12.861Z" }, - { url = "https://files.pythonhosted.org/packages/ef/fd/24ea4302d7a527d672c5be06e17df16aabfb4e9fdc6e0b345c21580f3d2a/pydantic_core-2.33.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:401d7b76e1000d0dd5538e6381d28febdcacb097c8d340dde7d7fc6e13e9f95d", size = 1812963, upload-time = "2025-04-02T09:48:14.553Z" }, - { url = "https://files.pythonhosted.org/packages/5f/95/4fbc2ecdeb5c1c53f1175a32d870250194eb2fdf6291b795ab08c8646d5d/pydantic_core-2.33.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aeb055a42d734c0255c9e489ac67e75397d59c6fbe60d155851e9782f276a9c", size = 1986896, upload-time = "2025-04-02T09:48:16.222Z" }, - { url = "https://files.pythonhosted.org/packages/71/ae/fe31e7f4a62431222d8f65a3bd02e3fa7e6026d154a00818e6d30520ea77/pydantic_core-2.33.1-cp313-cp313t-win_amd64.whl", hash = "sha256:338ea9b73e6e109f15ab439e62cb3b78aa752c7fd9536794112e14bee02c8d18", size = 1931810, upload-time = "2025-04-02T09:48:17.97Z" }, + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, ] [[package]] @@ -979,23 +1024,30 @@ wheels = [ [[package]] name = "sqlalchemy" -version = "2.0.40" +version = "2.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/c3/3f2bfa5e4dcd9938405fe2fab5b6ab94a9248a4f9536ea2fd497da20525f/sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00", size = 9664299, upload-time = "2025-03-27T17:52:31.876Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/21/77b4c147963073040dc3c3a5cb7a8c3001a1893c0209432cb77f9df836aa/sqlalchemy-2.0.52.tar.gz", hash = "sha256:5e2d46356ac2ccb7d268ab6c2319ac6a2b42f1b8d5fd8bd3d46855cd82abee97", size = 9945637, upload-time = "2026-08-11T19:07:09.829Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/18/4e3a86cc0232377bc48c373a9ba6a1b3fb79ba32dbb4eda0b357f5a2c59d/sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01", size = 2107887, upload-time = "2025-03-27T18:40:05.461Z" }, - { url = "https://files.pythonhosted.org/packages/cb/60/9fa692b1d2ffc4cbd5f47753731fd332afed30137115d862d6e9a1e962c7/sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705", size = 2098367, upload-time = "2025-03-27T18:40:07.182Z" }, - { url = "https://files.pythonhosted.org/packages/4c/9f/84b78357ca641714a439eb3fbbddb17297dacfa05d951dbf24f28d7b5c08/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364", size = 3184806, upload-time = "2025-03-27T18:51:29.356Z" }, - { url = "https://files.pythonhosted.org/packages/4b/7d/e06164161b6bfce04c01bfa01518a20cccbd4100d5c951e5a7422189191a/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0", size = 3198131, upload-time = "2025-03-27T18:50:31.616Z" }, - { url = "https://files.pythonhosted.org/packages/6d/51/354af20da42d7ec7b5c9de99edafbb7663a1d75686d1999ceb2c15811302/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db", size = 3131364, upload-time = "2025-03-27T18:51:31.336Z" }, - { url = "https://files.pythonhosted.org/packages/7a/2f/48a41ff4e6e10549d83fcc551ab85c268bde7c03cf77afb36303c6594d11/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26", size = 3159482, upload-time = "2025-03-27T18:50:33.201Z" }, - { url = "https://files.pythonhosted.org/packages/33/ac/e5e0a807163652a35be878c0ad5cfd8b1d29605edcadfb5df3c512cdf9f3/sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500", size = 2080704, upload-time = "2025-03-27T18:46:00.193Z" }, - { url = "https://files.pythonhosted.org/packages/1c/cb/f38c61f7f2fd4d10494c1c135ff6a6ddb63508d0b47bccccd93670637309/sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad", size = 2104564, upload-time = "2025-03-27T18:46:01.442Z" }, - { url = "https://files.pythonhosted.org/packages/d1/7c/5fc8e802e7506fe8b55a03a2e1dab156eae205c91bee46305755e086d2e2/sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a", size = 1903894, upload-time = "2025-03-27T18:40:43.796Z" }, + { url = "https://files.pythonhosted.org/packages/7f/18/e30c6fe1eca1bf34a39fbdd6066121cc9974c850faf6f349eac563697a26/sqlalchemy-2.0.52-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2eb3c6a64b1bfe6704777cfd504e7b8ad093a5f3e03ce67663a5e6742f294e43", size = 2167724, upload-time = "2026-08-11T20:58:12.679Z" }, + { url = "https://files.pythonhosted.org/packages/d0/56/2e17d161a4f7ecc1c2ffb93e607b4e1898bb551b451b283235acb8f6ce47/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:923bb183c1dc64fdf7b717965e3d59938ec4f8b8710b419a21ce403e5da9a9e1", size = 3321189, upload-time = "2026-08-11T21:02:41.932Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b8/8490916e893f3f8d74dc9cc54c078619364999dee37047a188e73abbc852/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:651d6d8782e80679e6151707c7b490834d46ada526328895abf567f25e63d29c", size = 3338185, upload-time = "2026-08-11T21:17:02.597Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f7/752cc8ee453da222829b3f5c4613614bf750d97429363b70414fa10478e4/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b08cddb8989775e3c88799d86704bdfc3ee6e9846118201aa5997f16f27e3a15", size = 3271698, upload-time = "2026-08-11T21:02:43.963Z" }, + { url = "https://files.pythonhosted.org/packages/51/e6/074ade0c07b9e4c8e8bca46820320ed94df9702afdb6f2af06623068d2e6/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab66fa9618269390d4dfa222f2f2f88f7bc4bf5da13905131b818217db7e8057", size = 3308936, upload-time = "2026-08-11T21:17:04.172Z" }, + { url = "https://files.pythonhosted.org/packages/66/07/557c0d04716705599227945ac14e0a17ad0338e899f37d8c2ddff4dcc663/sqlalchemy-2.0.52-cp313-cp313-win32.whl", hash = "sha256:c63bda077685c85ca513286547a531ba57e7a68cf0a7ed3bafcc2bbd18896f4d", size = 2127308, upload-time = "2026-08-11T21:14:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/96/4e/226eda27654318ce525d043025221f689abef883da2c7126f9065121618c/sqlalchemy-2.0.52-cp313-cp313-win_amd64.whl", hash = "sha256:9876b09b9f1ce7398b0ffece585c0a911244c53191187341f6bcae640e133751", size = 2153876, upload-time = "2026-08-11T21:14:55.527Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f5/71cb30af58c9b80a4e1fac0b73bb48f86d497a774a6a2eb6d2f1e657bb73/sqlalchemy-2.0.52-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:410d52be41d17f1a236d19520fbe776257dc16516ed06bd16d433311842aefd9", size = 2169537, upload-time = "2026-08-11T20:58:13.855Z" }, + { url = "https://files.pythonhosted.org/packages/4c/93/d07ebd645d1b07b6b5ed63450a70f063a346a7e0f2c8810daf2e532400cb/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfe9ce533dbe4d0a2ae1486546619bd30b76bcd670539a44d910361376175f5e", size = 3319606, upload-time = "2026-08-11T21:02:45.829Z" }, + { url = "https://files.pythonhosted.org/packages/ae/5c/290c84c7c2566ecd3b65baaae0fddec9bc33b033b398a06123bb86fbfc6e/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:812bae5138bfc0aa46fb0686da0fc7f581f68e2bbb05bc24c3713bebaedd1437", size = 3323642, upload-time = "2026-08-11T21:17:05.675Z" }, + { url = "https://files.pythonhosted.org/packages/13/f5/2cc160590ca49173359557880b92a0572293ccb899e8f6cedf150c5a3ddf/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:50bff43b632a56fbf5ed9afdd76307e1512b62051bcd5afb341ae67205bbb6c8", size = 3268125, upload-time = "2026-08-11T21:02:47.649Z" }, + { url = "https://files.pythonhosted.org/packages/35/f3/ea8933fc9f7d1353e9c2ff9965eae687c4cef181120574591ed2fa0633e1/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:49565daf5af554f538e23aef1fc81a95a4e49658f152285e45c02f5fc44f04cd", size = 3289516, upload-time = "2026-08-11T21:17:07.267Z" }, + { url = "https://files.pythonhosted.org/packages/45/67/05cf86541c1e1716fca1e4a996954a439cd74501707cda607fb7cb02ef50/sqlalchemy-2.0.52-cp314-cp314-win32.whl", hash = "sha256:ab9da41e61b9979b910499d633b241df20c51ee5037e5405b11c2faac3cbe1a2", size = 2130249, upload-time = "2026-08-11T21:14:57.273Z" }, + { url = "https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl", hash = "sha256:a593db51b3bae75db17a5738ad5f992244b3a03863f83c28117ee482c6a3f76d", size = 2156718, upload-time = "2026-08-11T21:14:58.667Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4b/e01a737eef378e734cc6394a82248a6ce13b167dfa36c731075ce9fc9c64/sqlalchemy-2.0.52-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1e61d08bdf4ee2f41024569e3400de7d6734ba498144766b11260936ccfa582", size = 2190344, upload-time = "2026-08-11T19:53:21.393Z" }, + { url = "https://files.pythonhosted.org/packages/b3/3f/3582293d1e185e71d19d7c731c3e2ee20ba21981c4a1115c0806c1f62120/sqlalchemy-2.0.52-py3-none-any.whl", hash = "sha256:3b81b8363a919ce53453591cdb93702e6bd54ade6c4fa2f468fc053baee5ed89", size = 1950700, upload-time = "2026-08-11T20:47:21.603Z" }, ] [[package]] @@ -1049,23 +1101,23 @@ wheels = [ [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, ] [[package]] diff --git a/kontor-model/.python-version b/kontor-model/.python-version new file mode 100644 index 0000000..24ee5b1 --- /dev/null +++ b/kontor-model/.python-version @@ -0,0 +1 @@ +3.13 diff --git a/kontor-api/src/db/models/__init__.py b/kontor-model/README.md similarity index 100% rename from kontor-api/src/db/models/__init__.py rename to kontor-model/README.md diff --git a/kontor-model/pyproject.toml b/kontor-model/pyproject.toml new file mode 100644 index 0000000..22eedda --- /dev/null +++ b/kontor-model/pyproject.toml @@ -0,0 +1,18 @@ +[project] +name = "kontor_model" +version = "0.3.0" +description = "Kontor Model" +readme = "README.md" +authors = [ + { name = "Thomas Peetz", email = "thomas.peetz@cimt-ag.de" } +] +requires-python = ">=3.13" +dependencies = [ + "sqlalchemy>=2.0.52", + "msgspec[toml,yaml]>=0.21.1", + "pydantic[email]>=2.13.4", +] + +[build-system] +requires = ["uv_build>=0.9.27,<0.10.0"] +build-backend = "uv_build" diff --git a/kontor-model/src/kontor_model/__init__.py b/kontor-model/src/kontor_model/__init__.py new file mode 100644 index 0000000..253334d --- /dev/null +++ b/kontor-model/src/kontor_model/__init__.py @@ -0,0 +1,2 @@ +def hello() -> str: + return "Hello from kontor-model!" diff --git a/kontor-api/src/db/repository/__init__.py b/kontor-model/src/kontor_model/db/__init__.py similarity index 100% rename from kontor-api/src/db/repository/__init__.py rename to kontor-model/src/kontor_model/db/__init__.py diff --git a/kontor-scripts/db/models/__init__.py b/kontor-model/src/kontor_model/db/models/__init__.py similarity index 87% rename from kontor-scripts/db/models/__init__.py rename to kontor-model/src/kontor_model/db/models/__init__.py index 05911d7..88d05c8 100644 --- a/kontor-scripts/db/models/__init__.py +++ b/kontor-model/src/kontor_model/db/models/__init__.py @@ -1,5 +1,5 @@ from typing import Any, Dict -from db.models.admin import ( +from kontor_model.db.models.admin import ( Assignment, Token, Profile, @@ -7,7 +7,7 @@ from db.models.admin import ( MailAccount, Mail, ) -from db.models.bookshelf import ( +from kontor_model.db.models.bookshelf import ( ArticleAuthor, BookAuthor, BookshelfPublisher, @@ -15,7 +15,7 @@ from db.models.bookshelf import ( Book, Author, ) -from db.models.comic import ( +from kontor_model.db.models.comic import ( Issue, StoryArc, TradePaperback, @@ -27,14 +27,15 @@ from db.models.comic import ( Publisher, WorkType, ) -from db.models.media import ( +from kontor_model.db.models.media import ( MediaFile, MediaActor, MediaActorFile, MediaArticle, MediaVideo, + MediaLofi, ) -from db.models.tysc import ( +from kontor_model.db.models.tysc import ( Card, CardSet, Rooster, @@ -72,6 +73,7 @@ registry: Dict[str, Any] = { BookAuthor.__tablename__: BookAuthor, MediaArticle.__tablename__: MediaArticle, MediaVideo.__tablename__: MediaVideo, + MediaLofi.__tablename__: MediaLofi, MediaFile.__tablename__: MediaFile, MediaActor.__tablename__: MediaActor, MediaActorFile.__tablename__: MediaActorFile, diff --git a/kontor-scripts/db/models/admin.py b/kontor-model/src/kontor_model/db/models/admin.py similarity index 99% rename from kontor-scripts/db/models/admin.py rename to kontor-model/src/kontor_model/db/models/admin.py index 6acfa58..78dbddb 100644 --- a/kontor-scripts/db/models/admin.py +++ b/kontor-model/src/kontor_model/db/models/admin.py @@ -4,7 +4,7 @@ from typing import Any, Dict from sqlalchemy import Column, ForeignKey, Integer, String, Boolean from sqlalchemy.orm import relationship, mapped_column, Mapped -from db.models.base import Base, BaseMixin +from kontor_model.db.models.base import Base, BaseMixin class Profile(Base, BaseMixin): diff --git a/kontor-scripts/db/models/base.py b/kontor-model/src/kontor_model/db/models/base.py similarity index 100% rename from kontor-scripts/db/models/base.py rename to kontor-model/src/kontor_model/db/models/base.py diff --git a/kontor-scripts/db/models/bookshelf.py b/kontor-model/src/kontor_model/db/models/bookshelf.py similarity index 98% rename from kontor-scripts/db/models/bookshelf.py rename to kontor-model/src/kontor_model/db/models/bookshelf.py index ee303c3..b55f429 100644 --- a/kontor-scripts/db/models/bookshelf.py +++ b/kontor-model/src/kontor_model/db/models/bookshelf.py @@ -2,7 +2,7 @@ from typing import Any, Dict from sqlalchemy import Column, ForeignKey, Integer, String from sqlalchemy.orm import relationship -from db.models.base import Base, BaseMixin +from kontor_model.db.models.base import Base, BaseMixin class Article(Base, BaseMixin): @@ -56,7 +56,7 @@ class Author(Base, BaseMixin): class BookshelfPublisher(Base, BaseMixin): __tablename__ = 'bookshelf_publisher' name = Column(String, unique=True) - books = relationship("Book") + books = relationship("Book", back_populates="publisher") def import_dict(self, import_data: Dict[str, Any]): self.id = import_data['id'] diff --git a/kontor-scripts/db/models/comic.py b/kontor-model/src/kontor_model/db/models/comic.py similarity index 99% rename from kontor-scripts/db/models/comic.py rename to kontor-model/src/kontor_model/db/models/comic.py index d430c36..136a5c0 100644 --- a/kontor-scripts/db/models/comic.py +++ b/kontor-model/src/kontor_model/db/models/comic.py @@ -4,7 +4,7 @@ from typing import Dict, List, Optional, Any from sqlalchemy import Column, ForeignKey, Integer, String, Boolean, func from sqlalchemy.orm import relationship, Mapped, mapped_column -from db.models.base import Base, BaseMixin +from kontor_model.db.models.base import Base, BaseMixin class Publisher(Base): diff --git a/kontor-scripts/db/models/media.py b/kontor-model/src/kontor_model/db/models/media.py similarity index 76% rename from kontor-scripts/db/models/media.py rename to kontor-model/src/kontor_model/db/models/media.py index 436df4b..a7678db 100644 --- a/kontor-scripts/db/models/media.py +++ b/kontor-model/src/kontor_model/db/models/media.py @@ -1,14 +1,8 @@ -import re -import subprocess -from datetime import datetime -from pathlib import Path from typing import Any, Dict -import requests -from bs4 import BeautifulSoup from sqlalchemy import Boolean, Column, String, ForeignKey from sqlalchemy.orm import relationship -from db.models.base import Base, BaseMixin, BaseVideoMixin +from kontor_model.db.models.base import Base, BaseMixin, BaseVideoMixin class MediaFile(Base, BaseMixin, BaseVideoMixin): @@ -21,6 +15,9 @@ class MediaFile(Base, BaseMixin, BaseVideoMixin): def __str__(self): return f'{self.title}({self.id})' + def update_title(self): + pass + def import_dict(self, import_data: Dict[str, Any]): self.id = import_data['id'] self.created_date = import_data['created_date'] @@ -49,52 +46,6 @@ class MediaFile(Base, BaseMixin, BaseVideoMixin): item['should_download'] = self.should_download return item - def update_title(self) -> None: - print(f"update title for {self.url}") - try: - r = requests.get(self.url) - soup = BeautifulSoup(r.content, "html.parser") - title_tag = soup.find('title') - if title_tag: - self.title = title_tag.get_text() - self.review = False - except: - self.title = None - self.review = True - self.last_modified_date = datetime.now() - - def download_file(self, download_dir: str, dl_tool: str): - print(f"download file for {self.url} to {download_dir}") - result = subprocess.run([dl_tool, self.url], cwd=download_dir, capture_output=True, text=True) - if result.returncode == 0: - output = result.stdout - output = re.sub(' +', ' ', output) - lines_list = output.splitlines() - file_name = self.__parse_output__(lines_list) - if file_name is None: - self.review = True - self.should_download = True - self.file_name = None - else: - download_file = Path(file_name) - self.should_download = False - self.file_name = download_file.name - self.cloud_link = str(download_file.absolute()) - self.last_modified_date = datetime.now() - - def __parse_output__(self, lines_list): - self.file_name = None - for line in lines_list: - if 'has already been downloaded' in line: - end_len = len(' has already been downloaded') - self.file_name = line[11:-end_len] - if 'Destination' in line: - line_len = len(line) - start_len = len('[download] Destination: ') - file_len = line_len - start_len - self.file_name = line[-file_len:] - return self.file_name - class MediaActor(Base, BaseMixin): __tablename__ = 'media_actor' @@ -222,3 +173,35 @@ class MediaVideo(Base, BaseMixin): item['url'] = self.url item['should_download'] = self.should_download return item + +class MediaLofi(Base, BaseMixin): + __tablename__ = 'media_lofi' + file_name = Column(String) + review = Column(Boolean) + should_download = Column(Boolean) + title = Column(String) + url = Column(String, unique=True) + + def import_dict(self, import_data: Dict[str, Any]): + self.id = import_data['id'] + self.created_date = import_data['created_date'] + self.last_modified_date = import_data['last_modified_date'] + self.version = import_data['version'] + self.file_name = import_data['file_name'] + self.review = import_data['review'] + self.should_download = import_data['should_download'] + self.title = import_data['title'] + self.url = import_data['url'] + + def export_dict(self) -> Dict[str, Any]: + item: Dict[str, Any] = {} + item['id'] = self.id + item['created_date'] = str(self.created_date) + item['last_modified_date'] = str(self.last_modified_date) + item['version'] = self.version + item['file_name'] = self.file_name + item['review'] = self.review + item['should_download'] = self.should_download + item['title'] = self.title + item['url'] = self.url + return item diff --git a/kontor-scripts/db/models/tysc.py b/kontor-model/src/kontor_model/db/models/tysc.py similarity index 99% rename from kontor-scripts/db/models/tysc.py rename to kontor-model/src/kontor_model/db/models/tysc.py index d937173..221df0c 100644 --- a/kontor-scripts/db/models/tysc.py +++ b/kontor-model/src/kontor_model/db/models/tysc.py @@ -2,7 +2,7 @@ from typing import Dict, Any from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Boolean from sqlalchemy.orm import relationship -from db.models.base import Base, BaseMixin +from kontor_model.db.models.base import Base, BaseMixin class Sport(Base, BaseMixin): diff --git a/kontor-api/src/db/repository/comics/__init__.py b/kontor-model/src/kontor_model/db/repository/__init__.py similarity index 100% rename from kontor-api/src/db/repository/comics/__init__.py rename to kontor-model/src/kontor_model/db/repository/__init__.py diff --git a/kontor-api/src/db/repository/admin.py b/kontor-model/src/kontor_model/db/repository/admin.py similarity index 91% rename from kontor-api/src/db/repository/admin.py rename to kontor-model/src/kontor_model/db/repository/admin.py index dbaa671..bca48c7 100644 --- a/kontor-api/src/db/repository/admin.py +++ b/kontor-model/src/kontor_model/db/repository/admin.py @@ -2,7 +2,7 @@ from typing import Optional from sqlalchemy.orm import Session -from src.db.models.admin import Profile +from kontor_model.db.models.admin import Profile def get_profile_by_username(username: str, db: Session) -> Optional[Profile]: diff --git a/kontor-api/src/schema/__init__.py b/kontor-model/src/kontor_model/db/repository/comics/__init__.py similarity index 100% rename from kontor-api/src/schema/__init__.py rename to kontor-model/src/kontor_model/db/repository/comics/__init__.py diff --git a/kontor-api/src/db/repository/comics/artist.py b/kontor-model/src/kontor_model/db/repository/comics/artist.py similarity index 61% rename from kontor-api/src/db/repository/comics/artist.py rename to kontor-model/src/kontor_model/db/repository/comics/artist.py index dd44211..a2bd1f0 100644 --- a/kontor-api/src/db/repository/comics/artist.py +++ b/kontor-model/src/kontor_model/db/repository/comics/artist.py @@ -1,14 +1,12 @@ -import uuid from typing import List, Optional from sqlalchemy.orm import Session -from src.core.log_conf import logger -from src.db.models.comic import Artist -from src.schema.comics.artist import AddArtist -from src.schema.comics.artist_details import ArtistDetailResponse, ArtistWorktypeComicResponse, ArtistWorktypeIssueResponse -from src.schema.comics.comic import ComicResponse -from src.schema.comics.worktype import WorktypeResponse +from kontor_model.db.models.comic import Artist +from kontor_model.schema.comics.artist import AddArtist +from kontor_model.schema.comics.artist_details import ArtistDetailResponse, ArtistWorktypeComicResponse, ArtistWorktypeIssueResponse +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.worktype import WorktypeResponse def get_artist_details(artist: Artist) -> ArtistDetailResponse: @@ -17,7 +15,17 @@ def get_artist_details(artist: Artist) -> ArtistDetailResponse: for work in artist.comic_works: worktype_id = work.work_type.id if worktype_id in comic_works_map: - comic = ComicResponse(id=work.comic.id, title=work.comic.title, completed=work.comic.completed) + comic = ComicResponse( + id=work.comic.id, + created_date=work.comic.created_date, + last_modified_date=work.comic.last_modified_date, + version=work.comic.version, + publisher_id=work.comic.publisher_id, + current_order=work.comic.current_order, + weblink=work.comic.weblink, + title=work.comic.title, + completed=work.comic.completed + ) comic_works_map[worktype_id].comics.append(comic) else: comic_works_map[worktype_id] = ArtistWorktypeComicResponse( @@ -37,7 +45,6 @@ def get_artist_details(artist: Artist) -> ArtistDetailResponse: return response def update_artist(add_artist: AddArtist, artist_id: str, db: Session) -> Optional[Artist]: - logger.info("update artist") artist: Optional[Artist] = db.get(Artist, artist_id) if artist is not None: artist.name = add_artist.name diff --git a/kontor-api/src/db/repository/comics/comic.py b/kontor-model/src/kontor_model/db/repository/comics/comic.py similarity index 73% rename from kontor-api/src/db/repository/comics/comic.py rename to kontor-model/src/kontor_model/db/repository/comics/comic.py index f080b89..785f9ad 100644 --- a/kontor-api/src/db/repository/comics/comic.py +++ b/kontor-model/src/kontor_model/db/repository/comics/comic.py @@ -2,16 +2,15 @@ from typing import Dict, List, Optional from sqlalchemy.orm import Session -from src.core.log_conf import logger -from src.db.models.comic import Comic, Issue -from src.schema.comics.artist import artist_to_response -from src.schema.comics.comic import ComicSchema, comic_to_response -from src.schema.comics.comic_details import ComicDetailsResponse, ComicWorktypeArtistResponse -from src.schema.comics.issue import IssueResponse, issue_to_response -from src.schema.comics.issue_details import IssueDetailsResponse -from src.schema.comics.publisher import publisher_to_response -from src.schema.comics.volume import VolumeResponse, volume_to_response -from src.schema.comics.worktype import worktype_to_response +from kontor_model.db.models.comic import Comic, Issue +from kontor_model.schema.comics.artist import artist_to_response +from kontor_model.schema.comics.comic import ComicSchema, comic_to_response +from kontor_model.schema.comics.comic_details import ComicDetailsResponse, ComicWorktypeArtistResponse +from kontor_model.schema.comics.issue import IssueResponse, issue_to_response +from kontor_model.schema.comics.issue_details import IssueDetailsResponse +from kontor_model.schema.comics.publisher import publisher_to_response +from kontor_model.schema.comics.volume import VolumeResponse, volume_to_response +from kontor_model.schema.comics.worktype import worktype_to_response def get_issue_details(issue: Issue) -> IssueDetailsResponse: @@ -30,7 +29,6 @@ def get_issue_details(issue: Issue) -> IssueDetailsResponse: def update_comic(new_comic: ComicSchema, comic_id: str, db: Session) -> Optional[Comic]: - logger.info(f"update_comic: {new_comic} with {comic_id}") comic: Optional[Comic] = db.get(Comic, comic_id) return comic @@ -48,7 +46,6 @@ def get_comic_details(comic: Comic) -> ComicDetailsResponse: if worktype_id in works_map: artist = artist_to_response(work.artist) 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: works_map[worktype_id] = ComicWorktypeArtistResponse( diff --git a/kontor-model/src/kontor_model/db/repository/comics/publisher.py b/kontor-model/src/kontor_model/db/repository/comics/publisher.py new file mode 100644 index 0000000..e0edcfb --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/comics/publisher.py @@ -0,0 +1,52 @@ +from typing import List + +from kontor_model.db.models.comic import Publisher +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.publisher import PublisherResponse +from kontor_model.schema.comics.publisher_details import PublisherDetailsResponse + + +def get_publisher_details(publisher: Publisher) -> PublisherDetailsResponse: + imprints: List[PublisherResponse] = [] + for imprint in publisher.imprints: + imprints.append( + PublisherResponse( + id=imprint.id, + created_date=imprint.created_date, + last_modified_date=imprint.last_modified_date, + version=imprint.version, + weblink=str(imprint.weblink), + parent_publisher_id=imprint.parent_publisher_id, + name=str(imprint.name) + ) + ) + comics: List[ComicResponse] = [] + for comic in publisher.comics: + comics.append( + ComicResponse( + id=comic.id, + created_date=comic.created_date, + last_modified_date=comic.last_modified_date, + version=comic.version, + publisher_id=comic.publisher_id, + current_order=comic.current_order, + weblink=comic.weblink, + title=comic.title, + completed=comic.completed + ) + ) + parent_publisher: PublisherResponse | None = None + if publisher.parent_publisher: + parent_publisher = PublisherResponse( + id=publisher.parent_publisher.id, + created_date=publisher.parent_publisher.created_date, + last_modified_date=publisher.parent_publisher.last_modified_date, + version=publisher.parent_publisher.version,# + weblink=str(publisher.parent_publisher.weblink), + parent_publisher_id=publisher.parent_publisher.parent_publisher_id, + name=str(publisher.parent_publisher.name) + ) + response: PublisherDetailsResponse = PublisherDetailsResponse( + id=publisher.id, name=str(publisher.name), parent_publisher=parent_publisher, imprints=imprints, comics=comics + ) + return response diff --git a/kontor-api/src/db/repository/comics/worktype.py b/kontor-model/src/kontor_model/db/repository/comics/worktype.py similarity index 78% rename from kontor-api/src/db/repository/comics/worktype.py rename to kontor-model/src/kontor_model/db/repository/comics/worktype.py index 4981be8..2d2a13f 100644 --- a/kontor-api/src/db/repository/comics/worktype.py +++ b/kontor-model/src/kontor_model/db/repository/comics/worktype.py @@ -4,9 +4,8 @@ from typing import AnyStr, Optional from sqlalchemy.orm import Session -from src.core.log_conf import logger -from src.db.models.comic import WorkType -from src.schema.comics.worktype import AddWorkType +from kontor_model.db.models.comic import WorkType +from kontor_model.schema.comics.worktype import AddWorkType def create_new_worktype(work: AddWorkType, db: Session) -> WorkType: @@ -18,12 +17,10 @@ def create_new_worktype(work: AddWorkType, db: Session) -> WorkType: db.add(worktype) db.commit() db.refresh(worktype) - logger.info(f"create_new_worktype: {worktype}") return worktype def update_worktype(work: AddWorkType, worktype_id: AnyStr, db: Session) -> Optional[WorkType]: - logger.info("update worktype") worktype: Optional[WorkType] = db.get(WorkType, worktype_id) if worktype is not None: worktype.name = work.worktype diff --git a/kontor-api/src/db/repository/media/actor.py b/kontor-model/src/kontor_model/db/repository/media/actor.py similarity index 81% rename from kontor-api/src/db/repository/media/actor.py rename to kontor-model/src/kontor_model/db/repository/media/actor.py index 4636f51..9bf58b5 100644 --- a/kontor-api/src/db/repository/media/actor.py +++ b/kontor-model/src/kontor_model/db/repository/media/actor.py @@ -3,14 +3,13 @@ import uuid from sqlalchemy.orm import Session -from src.core.log_conf import logger -from src.db.models.media import MediaActor -from src.db.repository.media.actorfile import delete_mediaactorfile -from src.schema.media.actor import MediaActorModel +from kontor_model.db.models.media import MediaActor +from kontor_model.db.repository.media.actorfile import delete_mediaactorfile +from kontor_model.schema.media.actor import MediaActorModel def create_new_mediaactor(new_actor: MediaActorModel, db: Session) -> MediaActor: - logger.info(f"create MediaActor with url {new_actor.url}") + print(f"create MediaActor with url {new_actor.url}") media_actor: MediaActor = MediaActor() media_actor.id = str(uuid.uuid4()) if new_actor.name is not None: @@ -22,11 +21,11 @@ def create_new_mediaactor(new_actor: MediaActorModel, db: Session) -> MediaActor db.add(media_actor) db.commit() db.refresh(media_actor) - logger.info(f"created {media_actor}") + print(f"created {media_actor}") return media_actor def delete_mediaactor(db: Session, actor_id: str): - logger.info(f"delete MediaActor with id {actor_id}") + print(f"delete MediaActor with id {actor_id}") media_actor = db.get(MediaActor, actor_id) if media_actor is not None: actor_files = media_actor.media_actor_files @@ -40,7 +39,7 @@ def import_mediaactor(db: Session, new_actor: MediaActorModel) -> MediaActor: """ import MediaFile and set missing values with default ones. """ - logger.info("import MediaActor with %s", new_actor) + print("import MediaActor with %s", new_actor) media_actor: MediaActor = MediaActor() media_actor.id = new_actor.id if new_actor.created_date: diff --git a/kontor-api/src/db/repository/media/actorfile.py b/kontor-model/src/kontor_model/db/repository/media/actorfile.py similarity index 83% rename from kontor-api/src/db/repository/media/actorfile.py rename to kontor-model/src/kontor_model/db/repository/media/actorfile.py index 9371e38..04ab50c 100644 --- a/kontor-api/src/db/repository/media/actorfile.py +++ b/kontor-model/src/kontor_model/db/repository/media/actorfile.py @@ -3,9 +3,8 @@ import uuid from sqlalchemy.orm import Session -from src.core.log_conf import logger -from src.db.models.media import MediaActorFile -from src.schema.media.actorfile import MediaActorFileModel +from kontor_model.db.models.media import MediaActorFile +from kontor_model.schema.media.actorfile import MediaActorFileModel def create_new_mediaactorfile( @@ -14,7 +13,7 @@ def create_new_mediaactorfile( """ Create relation for MediaFile and MediaActor """ - logger.info("create MediaActorFile with actor %s and file %s", actor_id, file_id) + print("create MediaActorFile with actor %s and file %s", actor_id, file_id) media_actor_file: MediaActorFile = MediaActorFile() media_actor_file.id = str(uuid.uuid4()) media_actor_file.created_date = datetime.now() @@ -32,7 +31,7 @@ def delete_mediaactorfile(db: Session, actorfile_id: str): """ Delete relation between MediaFile and MediaActor. """ - logger.info("delete MediaActorFile with id %s", actorfile_id) + print("delete MediaActorFile with id %s", actorfile_id) media_actorfile = db.get(MediaActorFile, actorfile_id) db.delete(media_actorfile) db.commit() @@ -44,7 +43,7 @@ def import_mediaactorfile( """ Import MediaFile and set missing values with default ones. """ - logger.info("import MediaActorFile with %s", new_actorfile) + print("import MediaActorFile with %s", new_actorfile) media_actor_file: MediaActorFile = MediaActorFile() media_actor_file.id = new_actorfile.id if new_actorfile.created_date: diff --git a/kontor-api/src/db/repository/media/file.py b/kontor-model/src/kontor_model/db/repository/media/file.py similarity index 85% rename from kontor-api/src/db/repository/media/file.py rename to kontor-model/src/kontor_model/db/repository/media/file.py index 3185b3c..ca99a6c 100644 --- a/kontor-api/src/db/repository/media/file.py +++ b/kontor-model/src/kontor_model/db/repository/media/file.py @@ -3,16 +3,15 @@ import uuid from sqlalchemy.orm import Session -from src.core.log_conf import logger -from src.db.models.media import MediaFile -from src.schema.media.file import MediaFileModel +from kontor_model.db.models.media import MediaFile +from kontor_model.schema.media.file import MediaFileModel def create_new_mediafile(link: str, db: Session) -> MediaFile: """ Create MediaFile with gievne URL. """ - logger.info("create MediaFile with url {link}") + print("create MediaFile with url {link}") media_file: MediaFile = MediaFile() media_file.id = str(uuid.uuid4()) media_file.url = link @@ -24,7 +23,7 @@ def create_new_mediafile(link: str, db: Session) -> MediaFile: db.add(media_file) db.commit() db.refresh(media_file) - logger.info("created %s", media_file) + print("created %s", media_file) return media_file @@ -32,7 +31,7 @@ def delete_mediafile(db: Session, media_file_id: str): """ Delete MediaFile with given ID from db. """ - logger.info("delete MediaFile with id %s", media_file_id) + print("delete MediaFile with id %s", media_file_id) media_file = db.get(MediaFile, media_file_id) db.delete(media_file) db.commit() @@ -42,7 +41,7 @@ def import_mediafile(db: Session, new_file: MediaFileModel) -> MediaFile: """ import MediaActor and set missing values with defautl ones. """ - logger.info("import MediaFile with %s", new_file) + print("import MediaFile with %s", new_file) media_file: MediaFile = MediaFile() media_file.id = new_file.id if new_file.created_date: diff --git a/kontor-model/src/kontor_model/db/repository/media/lofi.py b/kontor-model/src/kontor_model/db/repository/media/lofi.py new file mode 100644 index 0000000..3cdc2e3 --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/media/lofi.py @@ -0,0 +1,22 @@ +from datetime import datetime +import uuid + +from sqlalchemy.orm import Session + +from kontor_model.db.models.media import MediaLofi + + +def create_new_lofi(url: str, db: Session) -> MediaLofi: + print(url) + media_lofi = MediaLofi() + media_lofi.id = str(uuid.uuid4()) + media_lofi.url = url + media_lofi.created_date = datetime.now() + media_lofi.last_modified_date = datetime.now() + media_lofi.review = True + media_lofi.should_download = False + db.add(media_lofi) + db.commit() + db.refresh(media_lofi) + print(media_lofi) + return media_lofi diff --git a/kontor-api/src/db/repository/media/video.py b/kontor-model/src/kontor_model/db/repository/media/video.py similarity index 66% rename from kontor-api/src/db/repository/media/video.py rename to kontor-model/src/kontor_model/db/repository/media/video.py index 9048887..b1196dc 100644 --- a/kontor-api/src/db/repository/media/video.py +++ b/kontor-model/src/kontor_model/db/repository/media/video.py @@ -3,15 +3,14 @@ import uuid from sqlalchemy.orm import Session -from src.db.models.media import MediaVideo -from src.webapps.media.forms import AddLinkForm +from kontor_model.db.models.media import MediaVideo -def create_new_video(video: AddLinkForm, db: Session) -> MediaVideo: - print(video.url) +def create_new_video(url: str, db: Session) -> MediaVideo: + print(url) media_video = MediaVideo() media_video.id = str(uuid.uuid4()) - media_video.url = str(video.url) + media_video.url = url media_video.created_date = datetime.now() media_video.last_modified_date = datetime.now() media_video.review = True diff --git a/kontor-model/src/kontor_model/db/repository/user.py b/kontor-model/src/kontor_model/db/repository/user.py new file mode 100644 index 0000000..2511845 --- /dev/null +++ b/kontor-model/src/kontor_model/db/repository/user.py @@ -0,0 +1,41 @@ +from datetime import datetime +from typing import Optional +import uuid +from kontor_model.db.models.admin import Assignment, Profile +from sqlalchemy.orm import Session + +from kontor_model.schema.user.profile import ProfileModel + + +def create_new_profile(new_profile: ProfileModel, db: Session) -> Profile: + print(f"create Profile with username {new_profile.username}") + profile: Profile = Profile() + profile.id = str(uuid.uuid4()) + profile.user_name = new_profile.username + profile.first_name = new_profile.first_name + profile.last_name = new_profile.last_name + profile.created_date = datetime.now() + profile.last_modified_date = datetime.now() + profile.version = 0 + db.add(profile) + db.commit() + db.refresh(profile) + print(f"created {profile}") + return profile + +def delete_profile(db: Session, profile_id: str): + print(f"delete Profile with id {profile_id}") + profile: Optional[Profile] = db.get(Profile, profile_id) + if profile is not None: + assignments = profile.assignments + for assignment in assignments: + delete_assignment(db, assignment.id) + db.delete(profile) + db.commit() + +def delete_assignment(db: Session, assignment_id: str) -> None: + print(f"delete Assignment with id {assignment_id}") + assignment: Optional[Assignment] = db.get(Assignment, assignment_id) + if assignment is not None: + db.delete(assignment) + db.commit() diff --git a/kontor-api/src/schema/comics/__init__.py b/kontor-model/src/kontor_model/py.typed similarity index 100% rename from kontor-api/src/schema/comics/__init__.py rename to kontor-model/src/kontor_model/py.typed diff --git a/kontor-api/src/schema/media/__init__.py b/kontor-model/src/kontor_model/schema/__init__.py similarity index 100% rename from kontor-api/src/schema/media/__init__.py rename to kontor-model/src/kontor_model/schema/__init__.py diff --git a/kontor-api/src/schema/admin/healthcheck.py b/kontor-model/src/kontor_model/schema/admin/healthcheck.py similarity index 100% rename from kontor-api/src/schema/admin/healthcheck.py rename to kontor-model/src/kontor_model/schema/admin/healthcheck.py diff --git a/kontor-api/src/schema/admin/login.py b/kontor-model/src/kontor_model/schema/admin/login.py similarity index 100% rename from kontor-api/src/schema/admin/login.py rename to kontor-model/src/kontor_model/schema/admin/login.py diff --git a/kontor-api/src/schema/admin/mailaccount.py b/kontor-model/src/kontor_model/schema/admin/mailaccount.py similarity index 71% rename from kontor-api/src/schema/admin/mailaccount.py rename to kontor-model/src/kontor_model/schema/admin/mailaccount.py index 061a467..a61f914 100644 --- a/kontor-api/src/schema/admin/mailaccount.py +++ b/kontor-model/src/kontor_model/schema/admin/mailaccount.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.admin import MailAccount +from kontor_model.db.models.admin import MailAccount class MailAccountResponse(BaseModel): @@ -24,11 +24,11 @@ def to_response(account: MailAccount) -> MailAccountResponse: created_date=account.created_date, last_modified_date=account.last_modified_date, version=account.version, - host=account.host, + host=str(account.host), port=account.port, - protocol=account.protocol, - user_name=account.user_name, - password=account.password, - start_tls=account.start_tls, + protocol=str(account.protocol), + user_name=str(account.user_name), + password=str(account.password), + start_tls=bool(account.start_tls), ) return response diff --git a/kontor-api/src/schema/admin/token.py b/kontor-model/src/kontor_model/schema/admin/token.py similarity index 100% rename from kontor-api/src/schema/admin/token.py rename to kontor-model/src/kontor_model/schema/admin/token.py diff --git a/kontor-api/src/schema/bookshelf/article.py b/kontor-model/src/kontor_model/schema/bookshelf/article.py similarity index 84% rename from kontor-api/src/schema/bookshelf/article.py rename to kontor-model/src/kontor_model/schema/bookshelf/article.py index 3cf3861..4c0bf79 100644 --- a/kontor-api/src/schema/bookshelf/article.py +++ b/kontor-model/src/kontor_model/schema/bookshelf/article.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.bookshelf import Article +from kontor_model.db.models.bookshelf import Article class ArticleResponse(BaseModel): @@ -18,6 +18,6 @@ def to_response(article: Article) -> ArticleResponse: created_date=article.created_date, last_modified_date=article.last_modified_date, version=article.version, - title=article.title + title=str(article.title) ) return response diff --git a/kontor-api/src/schema/bookshelf/articleauthor.py b/kontor-model/src/kontor_model/schema/bookshelf/articleauthor.py similarity index 78% rename from kontor-api/src/schema/bookshelf/articleauthor.py rename to kontor-model/src/kontor_model/schema/bookshelf/articleauthor.py index 622b475..d8b6b37 100644 --- a/kontor-api/src/schema/bookshelf/articleauthor.py +++ b/kontor-model/src/kontor_model/schema/bookshelf/articleauthor.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.bookshelf import ArticleAuthor +from kontor_model.db.models.bookshelf import ArticleAuthor class ArticleAuthorResponse(BaseModel): @@ -19,7 +19,7 @@ def to_response(articleauthor: ArticleAuthor) -> ArticleAuthorResponse: created_date=articleauthor.created_date, last_modified_date=articleauthor.last_modified_date, version=articleauthor.version, - article_id=articleauthor.article_id, - author_id=articleauthor.author_id + article_id=str(articleauthor.article_id), + author_id=str(articleauthor.author_id) ) return response diff --git a/kontor-api/src/schema/bookshelf/author.py b/kontor-model/src/kontor_model/schema/bookshelf/author.py similarity index 78% rename from kontor-api/src/schema/bookshelf/author.py rename to kontor-model/src/kontor_model/schema/bookshelf/author.py index 32ca13a..955c805 100644 --- a/kontor-api/src/schema/bookshelf/author.py +++ b/kontor-model/src/kontor_model/schema/bookshelf/author.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.bookshelf import Author +from kontor_model.db.models.bookshelf import Author class AuthorResponse(BaseModel): @@ -19,7 +19,7 @@ def to_response(author: Author) -> AuthorResponse: created_date=author.created_date, last_modified_date=author.last_modified_date, version=author.version, - first_name=author.first_name, - last_name=author.last_name + first_name=str(author.first_name), + last_name=str(author.last_name) ) return response diff --git a/kontor-api/src/schema/bookshelf/book.py b/kontor-model/src/kontor_model/schema/bookshelf/book.py similarity index 76% rename from kontor-api/src/schema/bookshelf/book.py rename to kontor-model/src/kontor_model/schema/bookshelf/book.py index 355d56c..26000ff 100644 --- a/kontor-api/src/schema/bookshelf/book.py +++ b/kontor-model/src/kontor_model/schema/bookshelf/book.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.bookshelf import Book +from kontor_model.db.models.bookshelf import Book class BookResponse(BaseModel): @@ -21,9 +21,9 @@ def to_response(book: Book) -> BookResponse: created_date=book.created_date, last_modified_date=book.last_modified_date, version=book.version, - isbn=book.isbn, - title=book.title, + isbn=str(book.isbn), + title=str(book.title), year=book.year, - publisher_id=book.publisher_id + publisher_id=str(book.publisher_id) ) return response diff --git a/kontor-api/src/schema/bookshelf/bookauthor.py b/kontor-model/src/kontor_model/schema/bookshelf/bookauthor.py similarity index 78% rename from kontor-api/src/schema/bookshelf/bookauthor.py rename to kontor-model/src/kontor_model/schema/bookshelf/bookauthor.py index a92606d..4ef95fe 100644 --- a/kontor-api/src/schema/bookshelf/bookauthor.py +++ b/kontor-model/src/kontor_model/schema/bookshelf/bookauthor.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.bookshelf import BookAuthor +from kontor_model.db.models.bookshelf import BookAuthor class BookAuthorResponse(BaseModel): @@ -19,7 +19,7 @@ def to_response(bookauthor: BookAuthor) -> BookAuthorResponse: created_date=bookauthor.created_date, last_modified_date=bookauthor.last_modified_date, version=bookauthor.version, - author_id=bookauthor.author_id, - book_id=bookauthor.book_id + author_id=str(bookauthor.author_id), + book_id=str(bookauthor.book_id) ) return response diff --git a/kontor-api/src/schema/bookshelf/publisher.py b/kontor-model/src/kontor_model/schema/bookshelf/publisher.py similarity index 84% rename from kontor-api/src/schema/bookshelf/publisher.py rename to kontor-model/src/kontor_model/schema/bookshelf/publisher.py index 51292e1..28b0b9e 100644 --- a/kontor-api/src/schema/bookshelf/publisher.py +++ b/kontor-model/src/kontor_model/schema/bookshelf/publisher.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.bookshelf import BookshelfPublisher +from kontor_model.db.models.bookshelf import BookshelfPublisher class PublisherResponse(BaseModel): @@ -18,6 +18,6 @@ def to_response(publisher: BookshelfPublisher) -> PublisherResponse: created_date=publisher.created_date, last_modified_date=publisher.last_modified_date, version=publisher.version, - name=publisher.name + name=str(publisher.name) ) return response diff --git a/kontor-api/src/schema/tysc/__init__.py b/kontor-model/src/kontor_model/schema/comics/__init__.py similarity index 100% rename from kontor-api/src/schema/tysc/__init__.py rename to kontor-model/src/kontor_model/schema/comics/__init__.py diff --git a/kontor-api/src/schema/comics/artist.py b/kontor-model/src/kontor_model/schema/comics/artist.py similarity index 93% rename from kontor-api/src/schema/comics/artist.py rename to kontor-model/src/kontor_model/schema/comics/artist.py index 05c8704..58c68e6 100644 --- a/kontor-api/src/schema/comics/artist.py +++ b/kontor-model/src/kontor_model/schema/comics/artist.py @@ -3,7 +3,7 @@ from typing import Optional from pydantic import BaseModel -from src.db.models.comic import Artist +from kontor_model.db.models.comic import Artist class ArtistCreation(BaseModel): diff --git a/kontor-api/src/schema/comics/artist_details.py b/kontor-model/src/kontor_model/schema/comics/artist_details.py similarity index 70% rename from kontor-api/src/schema/comics/artist_details.py rename to kontor-model/src/kontor_model/schema/comics/artist_details.py index 416257c..0686c75 100644 --- a/kontor-api/src/schema/comics/artist_details.py +++ b/kontor-model/src/kontor_model/schema/comics/artist_details.py @@ -1,9 +1,9 @@ from typing import List from pydantic import BaseModel -from src.schema.comics.comic import ComicResponse -from src.schema.comics.issue_details import IssueDetailsResponse -from src.schema.comics.worktype import WorktypeResponse +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.issue_details import IssueDetailsResponse +from kontor_model.schema.comics.worktype import WorktypeResponse class ArtistWorktypeComicResponse(BaseModel): diff --git a/kontor-api/src/schema/comics/comic.py b/kontor-model/src/kontor_model/schema/comics/comic.py similarity index 77% rename from kontor-api/src/schema/comics/comic.py rename to kontor-model/src/kontor_model/schema/comics/comic.py index 6e5e34d..35d7119 100644 --- a/kontor-api/src/schema/comics/comic.py +++ b/kontor-model/src/kontor_model/schema/comics/comic.py @@ -5,7 +5,7 @@ from datetime import datetime from typing import Optional from pydantic import BaseModel, AnyUrl -from src.db.models.comic import Comic +from kontor_model.db.models.comic import Comic class ComicResponse(BaseModel): @@ -28,11 +28,11 @@ def comic_to_response(comic: Comic) -> ComicResponse: created_date=comic.created_date, last_modified_date=comic.last_modified_date, version=comic.version, - title=comic.title, - publisher_id=comic.publisher_id, - current_order=comic.current_order, - completed=comic.completed, - weblink=comic.weblink + title=str(comic.title), + publisher_id=str(comic.publisher_id), + current_order=bool(comic.current_order), + completed=bool(comic.completed), + weblink=str(comic.weblink) ) return response diff --git a/kontor-api/src/schema/comics/comic_details.py b/kontor-model/src/kontor_model/schema/comics/comic_details.py similarity index 59% rename from kontor-api/src/schema/comics/comic_details.py rename to kontor-model/src/kontor_model/schema/comics/comic_details.py index 16de453..0108ccb 100644 --- a/kontor-api/src/schema/comics/comic_details.py +++ b/kontor-model/src/kontor_model/schema/comics/comic_details.py @@ -1,11 +1,11 @@ from typing import List from pydantic import BaseModel -from src.schema.comics.artist import ArtistResponse -from src.schema.comics.issue import IssueResponse -from src.schema.comics.publisher import PublisherResponse -from src.schema.comics.volume import VolumeResponse -from src.schema.comics.worktype import WorktypeResponse +from kontor_model.schema.comics.artist import ArtistResponse +from kontor_model.schema.comics.issue import IssueResponse +from kontor_model.schema.comics.publisher import PublisherResponse +from kontor_model.schema.comics.volume import VolumeResponse +from kontor_model.schema.comics.worktype import WorktypeResponse class ComicWorktypeArtistResponse(BaseModel): diff --git a/kontor-api/src/schema/comics/comicwork.py b/kontor-model/src/kontor_model/schema/comics/comicwork.py similarity index 76% rename from kontor-api/src/schema/comics/comicwork.py rename to kontor-model/src/kontor_model/schema/comics/comicwork.py index 403e4ae..996bb2b 100644 --- a/kontor-api/src/schema/comics/comicwork.py +++ b/kontor-model/src/kontor_model/schema/comics/comicwork.py @@ -6,7 +6,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.comic import ComicWork +from kontor_model.db.models.comic import ComicWork class ComicWorkResponse(BaseModel): @@ -25,8 +25,8 @@ def comicwork_to_response(comicwork: ComicWork) -> ComicWorkResponse: 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, + comic_id=str(comicwork.comic_id), + artist_id=str(comicwork.artist_id), + work_type_id=str(comicwork.work_type_id), ) return response diff --git a/kontor-api/src/schema/comics/issue.py b/kontor-model/src/kontor_model/schema/comics/issue.py similarity index 69% rename from kontor-api/src/schema/comics/issue.py rename to kontor-model/src/kontor_model/schema/comics/issue.py index 4ca1621..1a1bec9 100644 --- a/kontor-api/src/schema/comics/issue.py +++ b/kontor-model/src/kontor_model/schema/comics/issue.py @@ -3,7 +3,7 @@ from typing import Optional from pydantic import BaseModel -from src.db.models.comic import Issue +from kontor_model.db.models.comic import Issue class IssueResponse(BaseModel): @@ -26,13 +26,13 @@ def issue_to_response(issue: Issue) -> IssueResponse: created_date=issue.created_date, last_modified_date=issue.last_modified_date, version=issue.version, - issue_number=issue.issue_number, - title=issue.title, + issue_number=str(issue.issue_number), + title=str(issue.title), published_on=issue.published_on, - in_stock=issue.in_stock, - is_read=issue.is_read, - comic_id=issue.comic_id, - volume_id=issue.volume_id, - story_arc_id=issue.story_arc_id + in_stock=bool(issue.in_stock), + is_read=bool(issue.is_read), + comic_id=str(issue.comic_id), + volume_id=str(issue.volume_id), + story_arc_id=str(issue.story_arc_id) ) return response diff --git a/kontor-api/src/schema/comics/issue_details.py b/kontor-model/src/kontor_model/schema/comics/issue_details.py similarity index 62% rename from kontor-api/src/schema/comics/issue_details.py rename to kontor-model/src/kontor_model/schema/comics/issue_details.py index df9c79d..01aca40 100644 --- a/kontor-api/src/schema/comics/issue_details.py +++ b/kontor-model/src/kontor_model/schema/comics/issue_details.py @@ -1,7 +1,7 @@ from pydantic import BaseModel -from src.schema.comics.comic import ComicResponse -from src.schema.comics.volume import VolumeResponse +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.volume import VolumeResponse class IssueDetailsResponse(BaseModel): diff --git a/kontor-api/src/schema/comics/issuework.py b/kontor-model/src/kontor_model/schema/comics/issuework.py similarity index 76% rename from kontor-api/src/schema/comics/issuework.py rename to kontor-model/src/kontor_model/schema/comics/issuework.py index 8d8ff68..4403e11 100644 --- a/kontor-api/src/schema/comics/issuework.py +++ b/kontor-model/src/kontor_model/schema/comics/issuework.py @@ -6,7 +6,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.comic import IssueWork +from kontor_model.db.models.comic import IssueWork class IssueWorkResponse(BaseModel): @@ -25,8 +25,8 @@ def issuework_to_response(issuework: IssueWork) -> IssueWorkResponse: 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, + issue_id=str(issuework.issue_id), + artist_id=str(issuework.artist_id), + work_type_id=str(issuework.work_type_id), ) return response diff --git a/kontor-api/src/schema/comics/publisher.py b/kontor-model/src/kontor_model/schema/comics/publisher.py similarity index 83% rename from kontor-api/src/schema/comics/publisher.py rename to kontor-model/src/kontor_model/schema/comics/publisher.py index a9ffd39..2a6a275 100644 --- a/kontor-api/src/schema/comics/publisher.py +++ b/kontor-model/src/kontor_model/schema/comics/publisher.py @@ -3,7 +3,7 @@ from typing import Optional from pydantic import BaseModel -from src.db.models.comic import Publisher +from kontor_model.db.models.comic import Publisher class PublisherResponse(BaseModel): @@ -22,8 +22,8 @@ def publisher_to_response(publisher: Publisher) -> PublisherResponse: created_date=publisher.created_date, last_modified_date=publisher.last_modified_date, version=publisher.version, - name=publisher.name, - weblink=publisher.weblink, + name=str(publisher.name), + weblink=str(publisher.weblink), parent_publisher_id=publisher.parent_publisher_id ) return response diff --git a/kontor-api/src/schema/comics/publisher_details.py b/kontor-model/src/kontor_model/schema/comics/publisher_details.py similarity index 66% rename from kontor-api/src/schema/comics/publisher_details.py rename to kontor-model/src/kontor_model/schema/comics/publisher_details.py index 5c4444e..ebb1fc7 100644 --- a/kontor-api/src/schema/comics/publisher_details.py +++ b/kontor-model/src/kontor_model/schema/comics/publisher_details.py @@ -2,8 +2,8 @@ from typing import List from pydantic import BaseModel -from src.schema.comics.comic import ComicResponse -from src.schema.comics.publisher import PublisherResponse +from kontor_model.schema.comics.comic import ComicResponse +from kontor_model.schema.comics.publisher import PublisherResponse class PublisherDetailsResponse(BaseModel): diff --git a/kontor-api/src/schema/comics/storyarc.py b/kontor-model/src/kontor_model/schema/comics/storyarc.py similarity index 78% rename from kontor-api/src/schema/comics/storyarc.py rename to kontor-model/src/kontor_model/schema/comics/storyarc.py index 30e8064..033daa8 100644 --- a/kontor-api/src/schema/comics/storyarc.py +++ b/kontor-model/src/kontor_model/schema/comics/storyarc.py @@ -3,7 +3,7 @@ from typing import Optional from pydantic import BaseModel -from src.db.models.comic import StoryArc +from kontor_model.db.models.comic import StoryArc class StoryArcResponse(BaseModel): id: str @@ -23,8 +23,8 @@ def storyarc_to_response(storyarc: StoryArc) -> StoryArcResponse: created_date=storyarc.created_date, last_modified_date=storyarc.last_modified_date, version=storyarc.version, - name=storyarc.name, - comic_id=storyarc.comic_id, - volume_id=storyarc.volume_id + name=str(storyarc.name), + comic_id=str(storyarc.comic_id), + volume_id=str(storyarc.volume_id) ) return response diff --git a/kontor-api/src/schema/comics/volume.py b/kontor-model/src/kontor_model/schema/comics/volume.py similarity index 81% rename from kontor-api/src/schema/comics/volume.py rename to kontor-model/src/kontor_model/schema/comics/volume.py index 3b4a109..260d79f 100644 --- a/kontor-api/src/schema/comics/volume.py +++ b/kontor-model/src/kontor_model/schema/comics/volume.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.comic import Volume +from kontor_model.db.models.comic import Volume class VolumeResponse(BaseModel): @@ -19,7 +19,7 @@ def volume_to_response(volume: Volume) -> VolumeResponse: created_date=volume.created_date, last_modified_date=volume.last_modified_date, version=volume.version, - name=volume.name, - comic_id=volume.comic_id + name=str(volume.name), + comic_id=str(volume.comic_id) ) return response diff --git a/kontor-api/src/schema/comics/worktype.py b/kontor-model/src/kontor_model/schema/comics/worktype.py similarity index 87% rename from kontor-api/src/schema/comics/worktype.py rename to kontor-model/src/kontor_model/schema/comics/worktype.py index 04a31bc..174bd34 100644 --- a/kontor-api/src/schema/comics/worktype.py +++ b/kontor-model/src/kontor_model/schema/comics/worktype.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.comic import WorkType +from kontor_model.db.models.comic import WorkType class AddWorkType(BaseModel): worktype: str @@ -21,6 +21,6 @@ def worktype_to_response(worktype: WorkType) -> WorktypeResponse: created_date=worktype.created_date, last_modified_date=worktype.last_modified_date, version=worktype.version, - name=worktype.name + name=str(worktype.name) ) return response diff --git a/kontor-scripts/db/__init__.py b/kontor-model/src/kontor_model/schema/media/__init__.py similarity index 100% rename from kontor-scripts/db/__init__.py rename to kontor-model/src/kontor_model/schema/media/__init__.py diff --git a/kontor-api/src/schema/media/actor.py b/kontor-model/src/kontor_model/schema/media/actor.py similarity index 86% rename from kontor-api/src/schema/media/actor.py rename to kontor-model/src/kontor_model/schema/media/actor.py index b3a6270..98d4151 100644 --- a/kontor-api/src/schema/media/actor.py +++ b/kontor-model/src/kontor_model/schema/media/actor.py @@ -2,7 +2,7 @@ from datetime import datetime from typing import Optional from pydantic import BaseModel -from src.db.models.media import MediaActor +from kontor_model.db.models.media import MediaActor class MediaActorResponse(BaseModel): @@ -19,8 +19,8 @@ def actor_to_response(actor: MediaActor) -> MediaActorResponse: created_date=actor.created_date, last_modified_date=actor.last_modified_date, version=actor.version, - name=actor.name, - url=actor.url + name=str(actor.name), + url=str(actor.url) ) return response diff --git a/kontor-api/src/schema/media/actorfile.py b/kontor-model/src/kontor_model/schema/media/actorfile.py similarity index 82% rename from kontor-api/src/schema/media/actorfile.py rename to kontor-model/src/kontor_model/schema/media/actorfile.py index 1dd5786..968b875 100644 --- a/kontor-api/src/schema/media/actorfile.py +++ b/kontor-model/src/kontor_model/schema/media/actorfile.py @@ -1,7 +1,7 @@ from datetime import datetime from typing import Optional -from src.db.models.media import MediaActorFile +from kontor_model.db.models.media import MediaActorFile from pydantic import BaseModel @@ -19,8 +19,8 @@ def actorfile_to_response(actorfile: MediaActorFile) -> MediaActorFileResponse: created_date=actorfile.created_date, last_modified_date=actorfile.last_modified_date, version=actorfile.version, - media_actor_id=actorfile.media_actor_id, - media_file_id=actorfile.media_file_id + media_actor_id=str(actorfile.media_actor_id), + media_file_id=str(actorfile.media_file_id) ) return response diff --git a/kontor-api/src/schema/media/article.py b/kontor-model/src/kontor_model/schema/media/article.py similarity index 81% rename from kontor-api/src/schema/media/article.py rename to kontor-model/src/kontor_model/schema/media/article.py index d4a1d79..5705cbf 100644 --- a/kontor-api/src/schema/media/article.py +++ b/kontor-model/src/kontor_model/schema/media/article.py @@ -3,7 +3,7 @@ from typing import Optional from pydantic import BaseModel -from src.db.models.media import MediaArticle +from kontor_model.db.models.media import MediaArticle class MediaArticleResponse(BaseModel): id: str @@ -23,8 +23,8 @@ def to_response(video: MediaArticle) -> MediaArticleResponse: created_date=video.created_date, last_modified_date=video.last_modified_date, version=video.version, - review=video.review, - title=video.title, - url=video.url, + review=bool(video.review), + title=str(video.title), + url=str(video.url), ) return response diff --git a/kontor-api/src/schema/media/file.py b/kontor-model/src/kontor_model/schema/media/file.py similarity index 97% rename from kontor-api/src/schema/media/file.py rename to kontor-model/src/kontor_model/schema/media/file.py index c10e6a0..c687afb 100644 --- a/kontor-api/src/schema/media/file.py +++ b/kontor-model/src/kontor_model/schema/media/file.py @@ -1,7 +1,7 @@ from datetime import datetime from typing import Optional -from src.db.models.media import MediaFile +from kontor_model.db.models.media import MediaFile from pydantic import BaseModel diff --git a/kontor-model/src/kontor_model/schema/media/lofi.py b/kontor-model/src/kontor_model/schema/media/lofi.py new file mode 100644 index 0000000..831b805 --- /dev/null +++ b/kontor-model/src/kontor_model/schema/media/lofi.py @@ -0,0 +1,33 @@ +from datetime import datetime + +from pydantic import BaseModel + +from kontor_model.db.models.media import MediaLofi + +class MediaLofiResponse(BaseModel): + id: str + created_date: datetime + last_modified_date: datetime + version: int + file_name: str = "" + review: bool = False + should_download: bool = False + title: str = "" + url: str = "" + +class AddLofi(BaseModel): + url: str + +def lofi_to_response(lofi: MediaLofi) -> MediaLofiResponse: + response: MediaLofiResponse = MediaLofiResponse( + id=lofi.id, + created_date=lofi.created_date, + last_modified_date=lofi.last_modified_date, + version=lofi.version, + file_name=str(lofi.file_name), + review=bool(lofi.review), + should_download=bool(lofi.should_download), + title=str(lofi.title), + url=str(lofi.url), + ) + return response diff --git a/kontor-api/src/schema/media/video.py b/kontor-model/src/kontor_model/schema/media/video.py similarity index 71% rename from kontor-api/src/schema/media/video.py rename to kontor-model/src/kontor_model/schema/media/video.py index 1445f00..5f23152 100644 --- a/kontor-api/src/schema/media/video.py +++ b/kontor-model/src/kontor_model/schema/media/video.py @@ -3,7 +3,7 @@ from typing import Optional from pydantic import BaseModel -from src.db.models.media import MediaVideo +from kontor_model.db.models.media import MediaVideo class MediaVideoResponse(BaseModel): id: str @@ -27,12 +27,12 @@ def video_to_response(video: MediaVideo) -> MediaVideoResponse: created_date=video.created_date, last_modified_date=video.last_modified_date, version=video.version, - cloud_link=video.cloud_link, - file_name=video.file_name, - path=video.path, - review=video.review, - title=video.title, - url=video.url, - should_download=video.should_download + cloud_link=str(video.cloud_link), + file_name=str(video.file_name), + path=str(video.path), + review=bool(video.review), + title=str(video.title), + url=str(video.url), + should_download=bool(video.should_download) ) return response diff --git a/kontor-scripts/db/repository/__init__.py b/kontor-model/src/kontor_model/schema/tysc/__init__.py similarity index 100% rename from kontor-scripts/db/repository/__init__.py rename to kontor-model/src/kontor_model/schema/tysc/__init__.py diff --git a/kontor-api/src/schema/tysc/card.py b/kontor-model/src/kontor_model/schema/tysc/card.py similarity index 77% rename from kontor-api/src/schema/tysc/card.py rename to kontor-model/src/kontor_model/schema/tysc/card.py index 7fe6cdf..9dc592c 100644 --- a/kontor-api/src/schema/tysc/card.py +++ b/kontor-model/src/kontor_model/schema/tysc/card.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.tysc import Card +from kontor_model.db.models.tysc import Card class CardResponse(BaseModel): @@ -24,8 +24,8 @@ def to_response(card: Card) -> CardResponse: version=card.version, card_number=card.card_number, year=card.year, - card_set_id=card.card_set_id, - rooster_id=card.rooster_id, - vendor_id=card.vendor_id + card_set_id=str(card.card_set_id), + rooster_id=str(card.rooster_id), + vendor_id=str(card.vendor_id) ) return response diff --git a/kontor-api/src/schema/tysc/cardset.py b/kontor-model/src/kontor_model/schema/tysc/cardset.py similarity index 71% rename from kontor-api/src/schema/tysc/cardset.py rename to kontor-model/src/kontor_model/schema/tysc/cardset.py index 0e2b77f..131ed68 100644 --- a/kontor-api/src/schema/tysc/cardset.py +++ b/kontor-model/src/kontor_model/schema/tysc/cardset.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.tysc import CardSet +from kontor_model.db.models.tysc import CardSet class CardSetResponse(BaseModel): @@ -22,9 +22,9 @@ def to_response(cardset: CardSet) -> CardSetResponse: created_date=cardset.created_date, last_modified_date=cardset.last_modified_date, version=cardset.version, - name=cardset.name, - parallel_set=cardset.parallel_set, - insert_set=cardset.insert_set, - vendor_id=cardset.vendor_id + name=str(cardset.name), + parallel_set=bool(cardset.parallel_set), + insert_set=bool(cardset.insert_set), + vendor_id=str(cardset.vendor_id) ) return response diff --git a/kontor-api/src/schema/tysc/fieldposition.py b/kontor-model/src/kontor_model/schema/tysc/fieldposition.py similarity index 75% rename from kontor-api/src/schema/tysc/fieldposition.py rename to kontor-model/src/kontor_model/schema/tysc/fieldposition.py index a206789..9fc06e2 100644 --- a/kontor-api/src/schema/tysc/fieldposition.py +++ b/kontor-model/src/kontor_model/schema/tysc/fieldposition.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.tysc import FieldPosition +from kontor_model.db.models.tysc import FieldPosition class FieldPositionResponse(BaseModel): @@ -21,8 +21,8 @@ def to_response(fieldposition: FieldPosition) -> FieldPositionResponse: created_date=fieldposition.created_date, last_modified_date=fieldposition.last_modified_date, version=fieldposition.version, - name=fieldposition.name, - short_name=fieldposition.short_name, - sport_id=fieldposition.sport_id + name=str(fieldposition.name), + short_name=str(fieldposition.short_name), + sport_id=str(fieldposition.sport_id) ) return response diff --git a/kontor-api/src/schema/tysc/player.py b/kontor-model/src/kontor_model/schema/tysc/player.py similarity index 78% rename from kontor-api/src/schema/tysc/player.py rename to kontor-model/src/kontor_model/schema/tysc/player.py index 47f9b14..dc7842a 100644 --- a/kontor-api/src/schema/tysc/player.py +++ b/kontor-model/src/kontor_model/schema/tysc/player.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.tysc import Player +from kontor_model.db.models.tysc import Player class PlayerResponse(BaseModel): @@ -19,7 +19,7 @@ def to_response(player: Player) -> PlayerResponse: created_date=player.created_date, last_modified_date=player.last_modified_date, version=player.version, - first_name=player.first_name, - last_name=player.last_name + first_name=str(player.first_name), + last_name=str(player.last_name) ) return response diff --git a/kontor-api/src/schema/tysc/rooster.py b/kontor-model/src/kontor_model/schema/tysc/rooster.py similarity index 80% rename from kontor-api/src/schema/tysc/rooster.py rename to kontor-model/src/kontor_model/schema/tysc/rooster.py index ccbcf55..b2df4b8 100644 --- a/kontor-api/src/schema/tysc/rooster.py +++ b/kontor-model/src/kontor_model/schema/tysc/rooster.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.tysc import Rooster +from kontor_model.db.models.tysc import Rooster class RoosterResponse(BaseModel): @@ -29,8 +29,8 @@ def to_response(rooster: Rooster) -> RoosterResponse: last_modified_date=rooster.last_modified_date, version=rooster.version, year=rooster.year, - team_id=rooster.team_id, - player_id=rooster.player_id, - position_id=rooster.position_id + team_id=str(rooster.team_id), + player_id=str(rooster.player_id), + position_id=str(rooster.position_id) ) return response diff --git a/kontor-api/src/schema/tysc/sport.py b/kontor-model/src/kontor_model/schema/tysc/sport.py similarity index 86% rename from kontor-api/src/schema/tysc/sport.py rename to kontor-model/src/kontor_model/schema/tysc/sport.py index 59da984..6d018df 100644 --- a/kontor-api/src/schema/tysc/sport.py +++ b/kontor-model/src/kontor_model/schema/tysc/sport.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.tysc import Sport +from kontor_model.db.models.tysc import Sport class SportResponse(BaseModel): @@ -19,6 +19,6 @@ def to_response(sport: Sport) -> SportResponse: created_date=sport.created_date, last_modified_date=sport.last_modified_date, version=sport.version, - name=sport.name + name=str(sport.name) ) return response diff --git a/kontor-api/src/schema/tysc/team.py b/kontor-model/src/kontor_model/schema/tysc/team.py similarity index 76% rename from kontor-api/src/schema/tysc/team.py rename to kontor-model/src/kontor_model/schema/tysc/team.py index abe63a7..cc69b59 100644 --- a/kontor-api/src/schema/tysc/team.py +++ b/kontor-model/src/kontor_model/schema/tysc/team.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.tysc import Team +from kontor_model.db.models.tysc import Team class TeamResponse(BaseModel): @@ -21,8 +21,8 @@ def to_response(team: Team) -> TeamResponse: created_date=team.created_date, last_modified_date=team.last_modified_date, version=team.version, - name=team.name, - short_name=team.short_name, - sport_id=team.sport_id + name=str(team.name), + short_name=str(team.short_name), + sport_id=str(team.sport_id) ) return response diff --git a/kontor-api/src/schema/tysc/vendor.py b/kontor-model/src/kontor_model/schema/tysc/vendor.py similarity index 89% rename from kontor-api/src/schema/tysc/vendor.py rename to kontor-model/src/kontor_model/schema/tysc/vendor.py index afea4e5..a5e8954 100644 --- a/kontor-api/src/schema/tysc/vendor.py +++ b/kontor-model/src/kontor_model/schema/tysc/vendor.py @@ -5,7 +5,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.tysc import Vendor +from kontor_model.db.models.tysc import Vendor class VendorResponse(BaseModel): @@ -27,6 +27,6 @@ def to_response(vendor: Vendor) -> VendorResponse: created_date=vendor.created_date, last_modified_date=vendor.last_modified_date, version=vendor.version, - name=vendor.name + name=str(vendor.name) ) return reponse diff --git a/kontor-api/src/schema/user/assignment.py b/kontor-model/src/kontor_model/schema/user/assignment.py similarity index 78% rename from kontor-api/src/schema/user/assignment.py rename to kontor-model/src/kontor_model/schema/user/assignment.py index bb12a66..5a61b05 100644 --- a/kontor-api/src/schema/user/assignment.py +++ b/kontor-model/src/kontor_model/schema/user/assignment.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.admin import Assignment +from kontor_model.db.models.admin import Assignment class AssignmentResponse(BaseModel): @@ -20,7 +20,7 @@ def to_response(assignment: Assignment) -> AssignmentResponse: created_date=assignment.created_date, last_modified_date=assignment.last_modified_date, version=assignment.version, - profile_id=assignment.profile_id, - permission_id=assignment.permission_id + profile_id=str(assignment.profile_id), + permission_id=str(assignment.permission_id) ) return response diff --git a/kontor-api/src/schema/user/permission.py b/kontor-model/src/kontor_model/schema/user/permission.py similarity index 85% rename from kontor-api/src/schema/user/permission.py rename to kontor-model/src/kontor_model/schema/user/permission.py index 913e0e0..18ab3b4 100644 --- a/kontor-api/src/schema/user/permission.py +++ b/kontor-model/src/kontor_model/schema/user/permission.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.admin import Permission +from kontor_model.db.models.admin import Permission class PermissionResponse(BaseModel): @@ -19,6 +19,6 @@ def to_response(permission: Permission) -> PermissionResponse: created_date=permission.created_date, last_modified_date=permission.last_modified_date, version=permission.version, - name=permission.name + name=str(permission.name) ) return response diff --git a/kontor-api/src/schema/user/profile.py b/kontor-model/src/kontor_model/schema/user/profile.py similarity index 77% rename from kontor-api/src/schema/user/profile.py rename to kontor-model/src/kontor_model/schema/user/profile.py index 218dbf5..7bb21a6 100644 --- a/kontor-api/src/schema/user/profile.py +++ b/kontor-model/src/kontor_model/schema/user/profile.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.admin import Profile +from kontor_model.db.models.admin import Profile class ProfileResponse(BaseModel): @@ -23,12 +23,12 @@ def to_response(profile: Profile) -> ProfileResponse: created_date=profile.created_date, last_modified_date=profile.last_modified_date, version=profile.version, - first_name=profile.first_name, - last_name=profile.last_name, - user_name=profile.user_name, - email=profile.email, - password=profile.password, - enabled=profile.enabled + first_name=str(profile.first_name), + last_name=str(profile.last_name), + user_name=str(profile.user_name), + email=str(profile.email), + password=str(profile.password), + enabled=bool(profile.enabled) ) return response diff --git a/kontor-api/src/schema/user/token.py b/kontor-model/src/kontor_model/schema/user/token.py similarity index 76% rename from kontor-api/src/schema/user/token.py rename to kontor-model/src/kontor_model/schema/user/token.py index 4748a74..e26409c 100644 --- a/kontor-api/src/schema/user/token.py +++ b/kontor-model/src/kontor_model/schema/user/token.py @@ -2,7 +2,7 @@ from datetime import datetime from pydantic import BaseModel -from src.db.models.admin import Token +from kontor_model.db.models.admin import Token class TokenResponse(BaseModel): @@ -23,10 +23,10 @@ def to_response(token: Token) -> TokenResponse: created_date=token.created_date, last_modified_date=token.last_modified_date, version=token.version, - token=token.token, - name=token.name, + token=str(token.token), + name=str(token.name), last_used_date=token.last_used_date, - enabled=token.enabled, - profile_id=token.profile_id + enabled=bool(token.enabled), + profile_id=str(token.profile_id) ) return response diff --git a/kontor-model/uv.lock b/kontor-model/uv.lock new file mode 100644 index 0000000..0193f92 --- /dev/null +++ b/kontor-model/uv.lock @@ -0,0 +1,317 @@ +version = 1 +revision = 3 +requires-python = ">=3.13" + +[[package]] +name = "annotated-types" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, +] + +[[package]] +name = "dnspython" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, +] + +[[package]] +name = "email-validator" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, +] + +[[package]] +name = "greenlet" +version = "3.5.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/d8/7cc97c142388aef03f622e001c572c4f84e9252a439549d483f555771970/greenlet-3.5.5.tar.gz", hash = "sha256:adb4bae02e91a8e863e48b177e4014bdcac8a6b5e047ea1df687a61534b85e6c", size = 207585, upload-time = "2026-08-10T15:09:36.136Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/3d/8cef5f724ec0d4add2af8961d504535ec60c3cca9e464f6d03bdba29d85b/greenlet-3.5.5-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:b79fd2a5bc099b5e744f34c4c9a58954a5f4cb7529fb4b6e8446057d61b6edaa", size = 294730, upload-time = "2026-08-10T13:27:51.206Z" }, + { url = "https://files.pythonhosted.org/packages/88/4b/8e7aa3f514273aecff30a16ab1bac09ff54cfc7e6860fdd8058c37ff2499/greenlet-3.5.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:634cf15a233a949136879dd388e25d3296e16f3f1e217d2456797b8579ebc6ed", size = 614536, upload-time = "2026-08-10T14:14:36.589Z" }, + { url = "https://files.pythonhosted.org/packages/85/48/4e95e9dd5a8a397dc6a6345dd7f1935113d0fca4f85e89d3976da9cd988d/greenlet-3.5.5-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:499adea519f748407fc6806d20eedabac2884fd73b9f38d81236e190ba20dfef", size = 626924, upload-time = "2026-08-10T14:27:27.048Z" }, + { url = "https://files.pythonhosted.org/packages/89/5d/398a1c71fa7a277deeb376c999979de6786f08fc2d5747a0b9d6e11738dd/greenlet-3.5.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2eabb980975cba5b93a95f6f69287d05fc05ac955bfd6a320a7c083eeb52c0b0", size = 623906, upload-time = "2026-08-10T13:40:50.501Z" }, + { url = "https://files.pythonhosted.org/packages/04/1b/745450fc5ea9e0cb17d840d248f284db3363de736d362c7d2d883e3eadba/greenlet-3.5.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:03115c2e0a371999bf8ae616aa8d653f96641d4705c457aebaa187276e9f7537", size = 1581430, upload-time = "2026-08-10T14:15:06.853Z" }, + { url = "https://files.pythonhosted.org/packages/d4/29/d51b296e3191bb15d3d81ec375af1909e4466c0f395d744ed475801798a9/greenlet-3.5.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4441153ffba21b90d3ca89fe3d31f5c093ae6c0bf0cfdfc98f54cde22f95b62e", size = 1645684, upload-time = "2026-08-10T13:40:32.133Z" }, + { url = "https://files.pythonhosted.org/packages/12/63/369f1a1625e64e9e31df3963c6044056e3fdfa3fa3fdba3c54ffefa6e987/greenlet-3.5.5-cp313-cp313-win_amd64.whl", hash = "sha256:95c5b1f4b3a193f8a0c2de4bfdcb48d119f7f1063941f1de1f2168051b3e52dd", size = 324075, upload-time = "2026-08-10T13:26:58.974Z" }, + { url = "https://files.pythonhosted.org/packages/45/78/649cb5c09d4d81f6dd1444e75474a7206784743283a21d24171562ac4899/greenlet-3.5.5-cp313-cp313-win_arm64.whl", hash = "sha256:1af90aa4bc129883b340cdd6957a3bc74f60528a4993bbd1f53aaebe1d9981cc", size = 308260, upload-time = "2026-08-10T13:27:50.795Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8c/080e881fa2be95ff1ddbd6994b2bab3b1a78df3b3fcab39306011764fcc7/greenlet-3.5.5-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d4a389a852e392a6366058651a20fa5ba40d979865aa81bea2ccbdc44805070d", size = 295309, upload-time = "2026-08-10T13:26:03.032Z" }, + { url = "https://files.pythonhosted.org/packages/25/cc/0ac614e6586c0e42d4cc281a5819150f4f43685744a4c5ff77139286409d/greenlet-3.5.5-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70b157cd319873e8b544ddc2de158f55bbd0a9b0218c8ce9332039801518e328", size = 661185, upload-time = "2026-08-10T14:14:37.867Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b9/6808725354be8ad305dfe5172377664fc9642d4fc043be246b3314cf4482/greenlet-3.5.5-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8bdfd1424abcf26832961e766570cae79efdb9599d709088c9cb6ef82b194926", size = 673419, upload-time = "2026-08-10T14:27:28.652Z" }, + { url = "https://files.pythonhosted.org/packages/42/2e/40c509967da7f254680826a2fa0dd22138ec79946c70b97542d74cde8b43/greenlet-3.5.5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:182de51c6b572a705f2fafaab2e783bcf7d2760940229dfe73086cbae037af3e", size = 670822, upload-time = "2026-08-10T13:40:51.833Z" }, + { url = "https://files.pythonhosted.org/packages/2d/22/c3c2eee4a8fe191d6d1d183086c56133d646024e3d70bfd414829f64560b/greenlet-3.5.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8fec3f165dfe332e490c3247c0f6c23b0bfc45f06496ad7f00ddb00e3d35e4dc", size = 1628469, upload-time = "2026-08-10T14:15:08.11Z" }, + { url = "https://files.pythonhosted.org/packages/f7/87/25babd09b94cb1f03e71db815fde463f0262e40cfbd953d58a8d77311351/greenlet-3.5.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c6ce25fee6cabc8bf22cb8b52e642cbb821be5b9aec8094d07ff03378141b8e9", size = 1691952, upload-time = "2026-08-10T13:40:33.502Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3d/5cc9701117ea4dc0eb7bf1f4f9b7888a6e2e5277ddfae095805ace50f2b6/greenlet-3.5.5-cp314-cp314-win_amd64.whl", hash = "sha256:7dffc5c859fe6059974df1e37d7923d654a83e2ae18fdd616994270e001115e1", size = 327458, upload-time = "2026-08-10T13:27:02.868Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6b/594fa2de7fae7629168a404a4305d7d7e31a5742c50a801b1839543cb93d/greenlet-3.5.5-cp314-cp314-win_arm64.whl", hash = "sha256:5e2afcfc4d4305dd715809b03da5cbe437c8984f61d8917751eb5fe4aefa3e07", size = 311146, upload-time = "2026-08-10T13:27:25.046Z" }, + { url = "https://files.pythonhosted.org/packages/24/e0/50cd600b469e5734c72709b6b1838b6bc63f307b573c772c3132d6ecfe92/greenlet-3.5.5-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:0e5a7de979d764aea1f5b6e95cf92b5b37741b9823702041f34b126e7f690277", size = 305471, upload-time = "2026-08-10T13:26:20.568Z" }, + { url = "https://files.pythonhosted.org/packages/75/a3/77acd66dfc6387b5219b2080806c0cabb73c10eb1bb44b413c40a62015ba/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fef01bd457f11fc158b130ca0027a3c365693280e8e231b65bdaf57999f39f5b", size = 672470, upload-time = "2026-08-10T14:14:39.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/71/0d178142dca3ec19f46fb2212ae73d30ad53b9d548dc64804086033a7089/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5173a72310725a74afc82c164f0e52cb8ad0de62f2bb623f24f6c0cc07d80272", size = 679973, upload-time = "2026-08-10T14:27:30.072Z" }, + { url = "https://files.pythonhosted.org/packages/6e/31/46eb8567302eaf787abf88d09df014e14ae3baf460af1b8b0efdbd3efcd5/greenlet-3.5.5-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44f08341873200ba8a60a8bc14ace3d91f1754f7fa7bc66157714a8cd420a476", size = 676634, upload-time = "2026-08-10T13:40:53.004Z" }, + { url = "https://files.pythonhosted.org/packages/a3/e9/b88bbf5b29970cb84172dc2c32aa3e5e579ceb94c808e81c826454138850/greenlet-3.5.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d246c0db9a2513cd45f019ba178ea4d4d4705bd210ee465e2c15d76a1ab13874", size = 1637320, upload-time = "2026-08-10T14:15:09.317Z" }, + { url = "https://files.pythonhosted.org/packages/6d/8c/7631ed29cc6f0392f11830076e172ce4885e70b0bc2c1bce1731176d4b4e/greenlet-3.5.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:72507285b5caa1d17904a3f7c322ca780823a54170a0e04ec3f37bcc60d4db71", size = 1697412, upload-time = "2026-08-10T13:40:34.924Z" }, + { url = "https://files.pythonhosted.org/packages/da/0f/f7dd935f9c4cb1be49098770587f54d8a78518e55c89bce86c4fb4109057/greenlet-3.5.5-cp314-cp314t-win_amd64.whl", hash = "sha256:7805655781fb8f28a55d05fe57ed61f5f10f1892fb587673e3bb5264f28041f0", size = 331514, upload-time = "2026-08-10T13:29:20.611Z" }, + { url = "https://files.pythonhosted.org/packages/b7/e5/681b01f8fbc1b55232822f99e8f8afeb78a55a7c76a7bf9dbdc7ccb03a6d/greenlet-3.5.5-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:c0db80fcd5b8aece93f66c64f78a786bbb6b96c5fe63ef5a5a4581ecf8bab206", size = 295975, upload-time = "2026-08-10T13:28:45.985Z" }, + { url = "https://files.pythonhosted.org/packages/11/f2/69b488cd9e7267bf4b0fe8cdebf25d8d6df680d21bdf41150d23e23d6652/greenlet-3.5.5-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b241c32f912ada659808d68e308c568baf577eebf757d15471472de0c18cfad", size = 666823, upload-time = "2026-08-10T14:14:40.222Z" }, + { url = "https://files.pythonhosted.org/packages/84/d4/d5bc2fdebbdda0c94555925ba79948b8395d75a7f6a36cc85dce5bab9f11/greenlet-3.5.5-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ef6a08349401d8eaf3cb12688ac8557de95788556b8631ef17555a4a173022c0", size = 677613, upload-time = "2026-08-10T14:27:31.543Z" }, + { url = "https://files.pythonhosted.org/packages/bd/93/542d8a3a90f3b35c6ad8bf7e56a03010287f2cafa289a5b7985b5207db39/greenlet-3.5.5-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f2e3d061b8e13aec2f0441689b3c71b244a20e5d274a52cb0f7e31bd1d139552", size = 675930, upload-time = "2026-08-10T13:40:54.205Z" }, + { url = "https://files.pythonhosted.org/packages/52/b5/89c9f2e8460d71101037d47a1feed11928615a5edd42370be290e0657eeb/greenlet-3.5.5-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:9ab5f5b93655e77fe0d6c2dfd22b5eac751bb1f876d8ec21761b7c1fb9266007", size = 1633878, upload-time = "2026-08-10T14:15:10.693Z" }, + { url = "https://files.pythonhosted.org/packages/b8/60/297de93f3b02ac78a5e04d32bb8bbe3080f4a73d8ed95016561463b70618/greenlet-3.5.5-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:f0e5a21bd4452a88cf032fc43c4a5b307ab1380eacb63b5988f9c0317885e773", size = 1696597, upload-time = "2026-08-10T13:40:36.252Z" }, + { url = "https://files.pythonhosted.org/packages/18/25/54c6eaff4f337fb670215e89eb2d00d9499487b658e709d4b477be4a342e/greenlet-3.5.5-cp315-cp315-win_amd64.whl", hash = "sha256:469dbb0a78625642f4a626cfd0c6e8bccc0385b5e49189b6308bbe849ec88a8e", size = 327700, upload-time = "2026-08-10T13:28:06.752Z" }, + { url = "https://files.pythonhosted.org/packages/67/67/857e88a36301caa0e029870132c2478bd55d896630321432afab03a3115f/greenlet-3.5.5-cp315-cp315-win_arm64.whl", hash = "sha256:2d57406c3efd32d7a81e17a674314e8bd00792cdab49ea3228a49aa1bfb2e769", size = 311750, upload-time = "2026-08-10T13:34:08.815Z" }, + { url = "https://files.pythonhosted.org/packages/10/e2/3144c0a116067ac1e30457b0139a94d60d1d36a86e015de68e9ac87cb3bc/greenlet-3.5.5-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:68184dfcf50ccaa8e864770fe0633a7e27250ea9329f8192ef47ee9ecfd78e1c", size = 306387, upload-time = "2026-08-10T13:27:00.897Z" }, + { url = "https://files.pythonhosted.org/packages/5c/a1/cb4223a7e9b9f43b8807e8eb212358bfe2dfaa174a9ea2889eb1714dcba2/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9ec0dc0e59dc9c61af5c47348365ccbbd7addfafe0a93b00336ff3da2907bdc6", size = 676472, upload-time = "2026-08-10T14:14:41.417Z" }, + { url = "https://files.pythonhosted.org/packages/9e/cd/a154b4498e5d8f12ada291cfb3b8d596eadde2177f5bf09a9be699d2a446/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e604f58e35833fc46ef20302bcb314dddbfd3fcf33a4f936216d51dd678d63ae", size = 684238, upload-time = "2026-08-10T14:27:32.946Z" }, + { url = "https://files.pythonhosted.org/packages/bf/bb/b0031d260c2968a3c87deebc51d80c64e499377f993aafe06ee3b7488cc2/greenlet-3.5.5-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:40239b5384f96da3963585cc6d7eaa9b56f8ae67e8d92cc82dd9e202fc847de3", size = 681246, upload-time = "2026-08-10T13:40:55.402Z" }, + { url = "https://files.pythonhosted.org/packages/9a/07/da554b71ab88e649da146e1065d86a48a5c5d92e50ab74ef41b504aa7f56/greenlet-3.5.5-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:a1eaccf5c3a1d3e46dead602c72e6836731e8e245c9de6a27764567b6b62d4c0", size = 1642735, upload-time = "2026-08-10T14:15:11.92Z" }, + { url = "https://files.pythonhosted.org/packages/78/76/26a3782a051677668af9d92beaa47cd87ba9dd5072f762961144a03dd4c6/greenlet-3.5.5-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:19e4e026fe20691f333b8eb1a3bc9625eceba8c3f9d62ec5a6f8581afbc6b5a5", size = 1700925, upload-time = "2026-08-10T13:40:37.656Z" }, + { url = "https://files.pythonhosted.org/packages/28/d9/fe7baf4190c2ae71f267efb9de21b3172bb35bc0ed1ef53dd6027d658e33/greenlet-3.5.5-cp315-cp315t-win_amd64.whl", hash = "sha256:712aee154f648bde84634654bb38bb78c69ac640c37a45c9effed800735049d8", size = 331829, upload-time = "2026-08-10T13:26:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/df/af/419a4e383bd600858a9b67e9b280a60fdc383ee3f2fe5b6c0c1ef04e74d1/greenlet-3.5.5-cp315-cp315t-win_arm64.whl", hash = "sha256:7f049911ee81a16a03c33d5450d8d5867d27f596ca5fb201b86f4524e874468b", size = 315093, upload-time = "2026-08-10T13:29:34.949Z" }, +] + +[[package]] +name = "idna" +version = "3.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, +] + +[[package]] +name = "kontor-model" +version = "0.3.0" +source = { editable = "." } +dependencies = [ + { name = "msgspec", extra = ["toml", "yaml"] }, + { name = "pydantic", extra = ["email"] }, + { name = "sqlalchemy" }, +] + +[package.metadata] +requires-dist = [ + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, + { name = "pydantic", extras = ["email"], specifier = ">=2.13.4" }, + { name = "sqlalchemy", specifier = ">=2.0.52" }, +] + +[[package]] +name = "msgspec" +version = "0.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e3/60/f79b9b013a16fa3a58350c9295ddc6789f2e335f36ea61ed10a21b215364/msgspec-0.21.1.tar.gz", hash = "sha256:2313508e394b0d208f8f56892ca9b2799e2561329de9763b19619595a6c0f72c", size = 319193, upload-time = "2026-04-12T21:44:50.394Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/74/f11ede02839b19ff459f88e3145df5d711626ca84da4e23520cebf819367/msgspec-0.21.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:764173717a01743f007e9f74520ed281f24672c604514f7d76c1c3a10e8edb66", size = 196176, upload-time = "2026-04-12T21:44:17.613Z" }, + { url = "https://files.pythonhosted.org/packages/bb/40/4476c1bd341418a046c4955aff632ec769315d1e3cb94e6acf86d461f9ed/msgspec-0.21.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:344c7cd0eaed1fb81d7959f99100ef71ec9b536881a376f11b9a6c4803365697", size = 188524, upload-time = "2026-04-12T21:44:18.815Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d9/9e9d7d7e5061b47540d03d640fab9b3965ba7ae49c1b2154861c8f007518/msgspec-0.21.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48943e278b3854c2f89f955ddc6f9f430d3f0784b16e47d10604ee0463cd21f5", size = 218880, upload-time = "2026-04-12T21:44:20.028Z" }, + { url = "https://files.pythonhosted.org/packages/74/66/2bb344f34abb4b57e60c7c9c761994e0417b9718ec1460bf00c296f2a7ea/msgspec-0.21.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9aa659ebb0101b1cbc31461212b87e341d961f0ab0772aaf068a99e001ec4aa", size = 225050, upload-time = "2026-04-12T21:44:21.577Z" }, + { url = "https://files.pythonhosted.org/packages/1a/84/7c1e412f76092277bf760cef12b7979d03314d259ab5b5cafde5d0c1722d/msgspec-0.21.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7b27d1a8ead2b6f5b0c4f2d07b8be1ccfcc041c8a0e704781edebe3ae13c484", size = 222713, upload-time = "2026-04-12T21:44:22.83Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/0bba04b2b4ef05f3d068429410bc71d2cea925f1596a8f41152cccd5edb8/msgspec-0.21.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38fe93e86b61328fe544cb7fd871fad5a27c8734bfda90f65e5dbe288ae50f61", size = 227259, upload-time = "2026-04-12T21:44:24.11Z" }, + { url = "https://files.pythonhosted.org/packages/b0/2d/09574b0eea02fed2c2c1383dbaae2c7f79dc16dcd6487a886000afb5d7c4/msgspec-0.21.1-cp313-cp313-win_amd64.whl", hash = "sha256:8bc666331c35fcce05a7cd2d6221adbe0f6058f8e750711413d22793c080ac6a", size = 189857, upload-time = "2026-04-12T21:44:25.359Z" }, + { url = "https://files.pythonhosted.org/packages/46/34/105b1576ad182879914f0c821f17ee1d13abb165cb060448f96fe2aff078/msgspec-0.21.1-cp313-cp313-win_arm64.whl", hash = "sha256:42bb1241e0750c1a4346f2aa84db26c5ffd99a4eb3a954927d9f149ff2f42898", size = 175403, upload-time = "2026-04-12T21:44:26.608Z" }, + { url = "https://files.pythonhosted.org/packages/5a/ad/86954e987d1d6a5c579e2c2e7832b65e0fff194179fdac4f581536086024/msgspec-0.21.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fab48eb45fdbfbdb2c0edfec00ffc53b6b6085beefc6b50b61e01659f9f8757f", size = 196261, upload-time = "2026-04-12T21:44:27.807Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a1/c5e46c3e42b866199365e35d11dddfd1fbd8bba4fdb3c52f965b1607ce94/msgspec-0.21.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3cb779ea0c35bc807ff941d415875c1f69ca0be91a2e907ab99a171811d86a9a", size = 188729, upload-time = "2026-04-12T21:44:28.99Z" }, + { url = "https://files.pythonhosted.org/packages/85/7d/1e29a319d678d6cb962ae5bdf32a6858ebdf38f73bc654c0e9c742a0c2c8/msgspec-0.21.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68604db36b3b4dd9bf160e436e12798a4738848144cea1aca1cb984011eb160f", size = 219866, upload-time = "2026-04-12T21:44:31.104Z" }, + { url = "https://files.pythonhosted.org/packages/25/1f/cca084ca2572810fff12ea9dbdcbe39eac048f40daf4a9077b49fcbe8cee/msgspec-0.21.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3d6b9dc50948eaf65df54d2fd0ff66e6d8c32f116037209ee861810eb9b676cb", size = 224993, upload-time = "2026-04-12T21:44:32.649Z" }, + { url = "https://files.pythonhosted.org/packages/71/94/d2120fc9d419a89a3a7c13e5b7078798c4b392a96a02a6e2b3ce43a8766c/msgspec-0.21.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:52c5e21930942302394429c5a582ce7e6b62c7f983b3760834c2ce107e0dd6df", size = 223535, upload-time = "2026-04-12T21:44:33.839Z" }, + { url = "https://files.pythonhosted.org/packages/75/17/42418b66a3ad972a89bab73dd78b79cc6282bb488a25e73c853cee7443b9/msgspec-0.21.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:abbb39d65681fa24ed394e01af3d59d869068324f900c61d06062b7fb9980f2f", size = 227222, upload-time = "2026-04-12T21:44:35.093Z" }, + { url = "https://files.pythonhosted.org/packages/c4/33/265c894268cca88ff67b144ca2b4c522fc8b9a6f1966a3640c70516e78e1/msgspec-0.21.1-cp314-cp314-win_amd64.whl", hash = "sha256:5666b1b560b97b6ec2eb3fca8a502298ebac56e13bbca1f88523538ce83d01ea", size = 193810, upload-time = "2026-04-12T21:44:36.612Z" }, + { url = "https://files.pythonhosted.org/packages/3b/8f/a6d35f25bf1fc63c492fdd88fdce01ba0875ead48c2b91f90f33653b4131/msgspec-0.21.1-cp314-cp314-win_arm64.whl", hash = "sha256:d8b8578e4c83b14ceea4cef0d0b747e31d9330fe4b03b2b2ad4063866a178f93", size = 179125, upload-time = "2026-04-12T21:44:38.198Z" }, + { url = "https://files.pythonhosted.org/packages/c6/39/74839641e64b99d87da55af0fc472854d42b46e2183b9e2a67fe1bb2a512/msgspec-0.21.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:15f523d51c00ebad412213bfe9f06f0a50ec2b93e0c19e824a2d267cabb48ea2", size = 200171, upload-time = "2026-04-12T21:44:39.414Z" }, + { url = "https://files.pythonhosted.org/packages/70/9b/ce0cca6d2d87fcd4b6ff97600790494e64f26a2c55d61507cd2755c16193/msgspec-0.21.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e47390360583ba3d5c6cb44cf0a9f61b0a06a899d3c2c00627cedebb2e2884b", size = 192879, upload-time = "2026-04-12T21:44:40.882Z" }, + { url = "https://files.pythonhosted.org/packages/a7/08/673a7bb05e5702dc787ddd3011195b509f9867927970da59052211929987/msgspec-0.21.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f60800e6299b798142dc40b0644da77ceac5ea0568be58228417eae14135c847", size = 226281, upload-time = "2026-04-12T21:44:42.181Z" }, + { url = "https://files.pythonhosted.org/packages/7d/45/86508cf57283e9070b3c447e3ab25b792a7a0855a3ea4e0c6d111ac34c97/msgspec-0.21.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5f8e9dfcd98419cf7568808470c4317a3fb30bef0e3715b568730a2b272a20d7", size = 229863, upload-time = "2026-04-12T21:44:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/2c/62/e7c9367cd08d590559faacd711edbae36840342843e669440363f33c7d36/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92d89dfad13bd1ea640dc3e37e724ed380da1030b272bdf5ecafb983c3ad7c75", size = 230445, upload-time = "2026-04-12T21:44:44.806Z" }, + { url = "https://files.pythonhosted.org/packages/42/b4/c0f54632103846b658a10930025f4de41c8724b5e4805a5f3b395586cb7e/msgspec-0.21.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0d03867786e5d7ba25d666df4b11320c27170f4aeafcb8e3a8b0a50a4fb742ca", size = 231822, upload-time = "2026-04-12T21:44:46.343Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1d/0d85cc79d0ccf5508e9c846cc66552a6a16bf92abd1dbd8362617f7b35cd/msgspec-0.21.1-cp314-cp314t-win_amd64.whl", hash = "sha256:740fbf1c9d59992ca3537d6fbe9ebbf9eaf726a65fbf31448e0ecbc710697a63", size = 206650, upload-time = "2026-04-12T21:44:47.601Z" }, + { url = "https://files.pythonhosted.org/packages/90/91/56c5d560f20e6c20e9e4f55bd0e458f7f162aa689ee350346c04c48eac0b/msgspec-0.21.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0d2cc73df6058d811a126ac3a8ad63a4dfa210c82f9cf5a004802eaf4712de90", size = 183149, upload-time = "2026-04-12T21:44:48.833Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli-w" }, +] +yaml = [ + { name = "pyyaml" }, +] + +[[package]] +name = "pydantic" +version = "2.13.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/21/77b4c147963073040dc3c3a5cb7a8c3001a1893c0209432cb77f9df836aa/sqlalchemy-2.0.52.tar.gz", hash = "sha256:5e2d46356ac2ccb7d268ab6c2319ac6a2b42f1b8d5fd8bd3d46855cd82abee97", size = 9945637, upload-time = "2026-08-11T19:07:09.829Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/18/e30c6fe1eca1bf34a39fbdd6066121cc9974c850faf6f349eac563697a26/sqlalchemy-2.0.52-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2eb3c6a64b1bfe6704777cfd504e7b8ad093a5f3e03ce67663a5e6742f294e43", size = 2167724, upload-time = "2026-08-11T20:58:12.679Z" }, + { url = "https://files.pythonhosted.org/packages/d0/56/2e17d161a4f7ecc1c2ffb93e607b4e1898bb551b451b283235acb8f6ce47/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:923bb183c1dc64fdf7b717965e3d59938ec4f8b8710b419a21ce403e5da9a9e1", size = 3321189, upload-time = "2026-08-11T21:02:41.932Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b8/8490916e893f3f8d74dc9cc54c078619364999dee37047a188e73abbc852/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:651d6d8782e80679e6151707c7b490834d46ada526328895abf567f25e63d29c", size = 3338185, upload-time = "2026-08-11T21:17:02.597Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f7/752cc8ee453da222829b3f5c4613614bf750d97429363b70414fa10478e4/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b08cddb8989775e3c88799d86704bdfc3ee6e9846118201aa5997f16f27e3a15", size = 3271698, upload-time = "2026-08-11T21:02:43.963Z" }, + { url = "https://files.pythonhosted.org/packages/51/e6/074ade0c07b9e4c8e8bca46820320ed94df9702afdb6f2af06623068d2e6/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab66fa9618269390d4dfa222f2f2f88f7bc4bf5da13905131b818217db7e8057", size = 3308936, upload-time = "2026-08-11T21:17:04.172Z" }, + { url = "https://files.pythonhosted.org/packages/66/07/557c0d04716705599227945ac14e0a17ad0338e899f37d8c2ddff4dcc663/sqlalchemy-2.0.52-cp313-cp313-win32.whl", hash = "sha256:c63bda077685c85ca513286547a531ba57e7a68cf0a7ed3bafcc2bbd18896f4d", size = 2127308, upload-time = "2026-08-11T21:14:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/96/4e/226eda27654318ce525d043025221f689abef883da2c7126f9065121618c/sqlalchemy-2.0.52-cp313-cp313-win_amd64.whl", hash = "sha256:9876b09b9f1ce7398b0ffece585c0a911244c53191187341f6bcae640e133751", size = 2153876, upload-time = "2026-08-11T21:14:55.527Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f5/71cb30af58c9b80a4e1fac0b73bb48f86d497a774a6a2eb6d2f1e657bb73/sqlalchemy-2.0.52-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:410d52be41d17f1a236d19520fbe776257dc16516ed06bd16d433311842aefd9", size = 2169537, upload-time = "2026-08-11T20:58:13.855Z" }, + { url = "https://files.pythonhosted.org/packages/4c/93/d07ebd645d1b07b6b5ed63450a70f063a346a7e0f2c8810daf2e532400cb/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfe9ce533dbe4d0a2ae1486546619bd30b76bcd670539a44d910361376175f5e", size = 3319606, upload-time = "2026-08-11T21:02:45.829Z" }, + { url = "https://files.pythonhosted.org/packages/ae/5c/290c84c7c2566ecd3b65baaae0fddec9bc33b033b398a06123bb86fbfc6e/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:812bae5138bfc0aa46fb0686da0fc7f581f68e2bbb05bc24c3713bebaedd1437", size = 3323642, upload-time = "2026-08-11T21:17:05.675Z" }, + { url = "https://files.pythonhosted.org/packages/13/f5/2cc160590ca49173359557880b92a0572293ccb899e8f6cedf150c5a3ddf/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:50bff43b632a56fbf5ed9afdd76307e1512b62051bcd5afb341ae67205bbb6c8", size = 3268125, upload-time = "2026-08-11T21:02:47.649Z" }, + { url = "https://files.pythonhosted.org/packages/35/f3/ea8933fc9f7d1353e9c2ff9965eae687c4cef181120574591ed2fa0633e1/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:49565daf5af554f538e23aef1fc81a95a4e49658f152285e45c02f5fc44f04cd", size = 3289516, upload-time = "2026-08-11T21:17:07.267Z" }, + { url = "https://files.pythonhosted.org/packages/45/67/05cf86541c1e1716fca1e4a996954a439cd74501707cda607fb7cb02ef50/sqlalchemy-2.0.52-cp314-cp314-win32.whl", hash = "sha256:ab9da41e61b9979b910499d633b241df20c51ee5037e5405b11c2faac3cbe1a2", size = 2130249, upload-time = "2026-08-11T21:14:57.273Z" }, + { url = "https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl", hash = "sha256:a593db51b3bae75db17a5738ad5f992244b3a03863f83c28117ee482c6a3f76d", size = 2156718, upload-time = "2026-08-11T21:14:58.667Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4b/e01a737eef378e734cc6394a82248a6ce13b167dfa36c731075ce9fc9c64/sqlalchemy-2.0.52-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1e61d08bdf4ee2f41024569e3400de7d6734ba498144766b11260936ccfa582", size = 2190344, upload-time = "2026-08-11T19:53:21.393Z" }, + { url = "https://files.pythonhosted.org/packages/b3/3f/3582293d1e185e71d19d7c731c3e2ee20ba21981c4a1115c0806c1f62120/sqlalchemy-2.0.52-py3-none-any.whl", hash = "sha256:3b81b8363a919ce53453591cdb93702e6bd54ade6c4fa2f468fc053baee5ed89", size = 1950700, upload-time = "2026-08-11T20:47:21.603Z" }, +] + +[[package]] +name = "tomli-w" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/75/241269d1da26b624c0d5e110e8149093c759b7a286138f4efd61a60e75fe/tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021", size = 7184, upload-time = "2025-01-15T12:07:24.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/18/c86eb8e0202e32dd3df50d43d7ff9854f8e0603945ff398974c1d91ac1ef/tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90", size = 6675, upload-time = "2025-01-15T12:07:22.074Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/26/b09b8010994eccc3c09092e6b34058f36a460eea2d4c3e8b910c695975a0/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47", size = 76928, upload-time = "2026-08-12T12:37:25.997Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/81/4add07e5172b7ac40d8ed5ff580409a7801a4fe26d529bdd915401dabfbe/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147", size = 14750, upload-time = "2026-08-12T12:37:24.648Z" }, +] diff --git a/kontor-scripts/add_links.py b/kontor-scripts/add_links.py index c889411..77d416c 100644 --- a/kontor-scripts/add_links.py +++ b/kontor-scripts/add_links.py @@ -13,7 +13,7 @@ from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from pathlib import Path from api import Server, get_api_config from log import get_logger -from db.models.media import MediaActor, MediaActorFile, MediaFile +from kontor_model.db.models.media import MediaActor, MediaActorFile, MediaFile parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument( diff --git a/kontor-scripts/api.py b/kontor-scripts/api.py index a49b861..7234be6 100644 --- a/kontor-scripts/api.py +++ b/kontor-scripts/api.py @@ -1,7 +1,5 @@ from dataclasses import dataclass from enum import Enum, auto -import logging -import logging.config from logging import Logger from pathlib import Path from typing import Dict, List, Optional @@ -38,6 +36,7 @@ MAPPING: Dict[str, str] = { "book_author": "api/bookshelf/bookauthors", "media_article": "api/media/articles", "media_video": "api/media/videos", + "media_lofi": "api/media/lofi", "media_file": "api/media/files", "media_actor": "api/media/actors", "media_actor_file": "api/media/actorfiles", diff --git a/kontor-scripts/db/models/database.py b/kontor-scripts/db/models/database.py deleted file mode 100644 index 5eb9dbb..0000000 --- a/kontor-scripts/db/models/database.py +++ /dev/null @@ -1,66 +0,0 @@ -from enum import Enum, auto -from logging import Logger -from typing import Any - -from sqlalchemy import select -from sqlalchemy.orm import sessionmaker - -from db.models import registry - - -class ColumnEntry(Enum): - COLUMN_NAME = 'column' - COLUMN_LABEL = 'label' - COLUMN_ORDER = 'order' - COLUMN_REF_COLUMN = 'ref_column' - COLUMN_TYPE = 'type' - COLUMN_WIDGET = 'widget' - - -class StatusType(Enum): - UNKNOWN = auto() - FILE_NAME = auto() - FILE_ID = auto() - DUPLICATE = auto() - CLOUD_LINK = auto() - CLOUD_LINK_ID = auto() - - -class ExportType(Enum): - JSON = "JSON" - YAML = "YAML" - SQLITE = "SQLite" - - -class KontorDB: - - def __init__(self, db_engine: Any, log: Logger): - self.engine = db_engine - self.log = log - - def data(self, table_name: str, columns: dict, filters: dict) -> list: - data = [] - __session__ = sessionmaker(self.engine) - table = registry[table_name] - with __session__() as session: - entries = [] - if len(filters) == 0: - entries = session.scalars(select(table)).all() - else: - entries = session.scalars(select(table).filter_by(**filters)).all() - for entry in entries: - # self.log.info("data: %s", entry) - row = [] - for order in columns.keys(): - column_name = columns[order][ColumnEntry.COLUMN_NAME] - ref_column = columns[order][ColumnEntry.COLUMN_REF_COLUMN] - if str(column_name).endswith("_id"): - ref_table = column_name[:-3] - ref = getattr(entry, ref_table) - value = getattr(ref, ref_column) - row.append(value) - else: - row.append(getattr(entry, column_name)) - data.append(row) - # self.log.info("data: %s", data) - return data diff --git a/kontor-scripts/download.py b/kontor-scripts/download.py index 9f2b6c0..9101288 100644 --- a/kontor-scripts/download.py +++ b/kontor-scripts/download.py @@ -13,7 +13,8 @@ from logging import Logger from typing import Any, Dict, Optional from uuid import UUID -from api import Option, OptionType, Server, get_api_config, get_logger +from api import Option, OptionType, Server, get_api_config +from log import get_logger parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument("--verbose", "-v", action="count", default=0) diff --git a/kontor-scripts/export.py b/kontor-scripts/export.py index b81da36..51dafc3 100644 --- a/kontor-scripts/export.py +++ b/kontor-scripts/export.py @@ -6,8 +6,8 @@ import json import os from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -from db.models import registry -from db.models.base import Base +from kontor_model.db.models import registry +from kontor_model.db.models.base import Base from config import get_logger parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) diff --git a/kontor-scripts/find_links.py b/kontor-scripts/find_links.py index 1ef6854..0ff56da 100644 --- a/kontor-scripts/find_links.py +++ b/kontor-scripts/find_links.py @@ -2,7 +2,6 @@ download files with URLs from DB """ import logging.config -import sys from typing import Any, Dict import requests import re diff --git a/kontor-scripts/import.py b/kontor-scripts/import.py index a00349e..564a96a 100644 --- a/kontor-scripts/import.py +++ b/kontor-scripts/import.py @@ -16,8 +16,8 @@ from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker from config import get_api_config, get_logger -from db.models import registry -from db.models.base import Base +from kontor_model.db.models import registry +from kontor_model.db.models.base import Base parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument("--verbose", "-v", action="count", default=0) diff --git a/kontor-scripts/pyproject.toml b/kontor-scripts/pyproject.toml index e16057c..e6ace1a 100644 --- a/kontor-scripts/pyproject.toml +++ b/kontor-scripts/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "click>=8.1.8", "coverage>=7.8.0", "fastapi[standard]>=0.115.12", + "kontor-model", "msgspec[toml,yaml]>=0.21.1", "pathlib>=1.0.1", "platformdirs>=4.3.7", @@ -28,3 +29,6 @@ dependencies = [ "sqlmodel>=0.0.24", "stomp-py", ] + +[tool.uv.sources] +kontor_model = { path = "../kontor-model", editable = true } diff --git a/kontor-scripts/update_title.py b/kontor-scripts/update_title.py index a85af90..a55ab8b 100644 --- a/kontor-scripts/update_title.py +++ b/kontor-scripts/update_title.py @@ -8,7 +8,7 @@ from typing import Any, Dict, List import requests from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, Session -from db.models.base import Base +from kontor_model.db.models.base import Base import yaml from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from pathlib import Path @@ -16,7 +16,7 @@ from pathlib import Path from bs4 import BeautifulSoup from platformdirs import PlatformDirs from config import get_api_config -from db.models.media import MediaFile +from kontor_model.db.models.media import MediaFile parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter) parser.add_argument('--verbose', '-v', action='count', default=0) @@ -128,7 +128,7 @@ if __name__ == '__main__': log.info(f"data: {len(data)}") session = get_session() with session as db: - media_files = db.query(MediaFile).filter(MediaFile.review == True).all() + media_files = db.query(MediaFile).filter(MediaFile.review).all() for media_file in media_files: link = media_file.url log.info(f"{media_file.id} - {str(link)}") diff --git a/kontor-scripts/uv.lock b/kontor-scripts/uv.lock index 7df759b..971a56c 100644 --- a/kontor-scripts/uv.lock +++ b/kontor-scripts/uv.lock @@ -316,6 +316,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] +[[package]] +name = "kontor-model" +version = "0.3.0" +source = { editable = "../kontor-model" } +dependencies = [ + { name = "msgspec", extra = ["toml", "yaml"] }, + { name = "sqlalchemy" }, +] + +[package.metadata] +requires-dist = [ + { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, + { name = "sqlalchemy", specifier = ">=2.0.52" }, +] + [[package]] name = "kontor-scripts" version = "0.1.0" @@ -325,6 +340,7 @@ dependencies = [ { name = "click" }, { name = "coverage" }, { name = "fastapi", extra = ["standard"] }, + { name = "kontor-model" }, { name = "msgspec", extra = ["toml", "yaml"] }, { name = "pathlib" }, { name = "platformdirs" }, @@ -346,6 +362,7 @@ requires-dist = [ { name = "click", specifier = ">=8.1.8" }, { name = "coverage", specifier = ">=7.8.0" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.115.12" }, + { name = "kontor-model", editable = "../kontor-model" }, { name = "msgspec", extras = ["toml", "yaml"], specifier = ">=0.21.1" }, { name = "pathlib", specifier = ">=1.0.1" }, { name = "platformdirs", specifier = ">=4.3.7" }, @@ -727,23 +744,30 @@ wheels = [ [[package]] name = "sqlalchemy" -version = "2.0.40" +version = "2.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/68/c3/3f2bfa5e4dcd9938405fe2fab5b6ab94a9248a4f9536ea2fd497da20525f/sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00", size = 9664299, upload-time = "2025-03-27T17:52:31.876Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/21/77b4c147963073040dc3c3a5cb7a8c3001a1893c0209432cb77f9df836aa/sqlalchemy-2.0.52.tar.gz", hash = "sha256:5e2d46356ac2ccb7d268ab6c2319ac6a2b42f1b8d5fd8bd3d46855cd82abee97", size = 9945637, upload-time = "2026-08-11T19:07:09.829Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/18/4e3a86cc0232377bc48c373a9ba6a1b3fb79ba32dbb4eda0b357f5a2c59d/sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01", size = 2107887, upload-time = "2025-03-27T18:40:05.461Z" }, - { url = "https://files.pythonhosted.org/packages/cb/60/9fa692b1d2ffc4cbd5f47753731fd332afed30137115d862d6e9a1e962c7/sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705", size = 2098367, upload-time = "2025-03-27T18:40:07.182Z" }, - { url = "https://files.pythonhosted.org/packages/4c/9f/84b78357ca641714a439eb3fbbddb17297dacfa05d951dbf24f28d7b5c08/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364", size = 3184806, upload-time = "2025-03-27T18:51:29.356Z" }, - { url = "https://files.pythonhosted.org/packages/4b/7d/e06164161b6bfce04c01bfa01518a20cccbd4100d5c951e5a7422189191a/sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0", size = 3198131, upload-time = "2025-03-27T18:50:31.616Z" }, - { url = "https://files.pythonhosted.org/packages/6d/51/354af20da42d7ec7b5c9de99edafbb7663a1d75686d1999ceb2c15811302/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db", size = 3131364, upload-time = "2025-03-27T18:51:31.336Z" }, - { url = "https://files.pythonhosted.org/packages/7a/2f/48a41ff4e6e10549d83fcc551ab85c268bde7c03cf77afb36303c6594d11/sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26", size = 3159482, upload-time = "2025-03-27T18:50:33.201Z" }, - { url = "https://files.pythonhosted.org/packages/33/ac/e5e0a807163652a35be878c0ad5cfd8b1d29605edcadfb5df3c512cdf9f3/sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500", size = 2080704, upload-time = "2025-03-27T18:46:00.193Z" }, - { url = "https://files.pythonhosted.org/packages/1c/cb/f38c61f7f2fd4d10494c1c135ff6a6ddb63508d0b47bccccd93670637309/sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad", size = 2104564, upload-time = "2025-03-27T18:46:01.442Z" }, - { url = "https://files.pythonhosted.org/packages/d1/7c/5fc8e802e7506fe8b55a03a2e1dab156eae205c91bee46305755e086d2e2/sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a", size = 1903894, upload-time = "2025-03-27T18:40:43.796Z" }, + { url = "https://files.pythonhosted.org/packages/7f/18/e30c6fe1eca1bf34a39fbdd6066121cc9974c850faf6f349eac563697a26/sqlalchemy-2.0.52-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2eb3c6a64b1bfe6704777cfd504e7b8ad093a5f3e03ce67663a5e6742f294e43", size = 2167724, upload-time = "2026-08-11T20:58:12.679Z" }, + { url = "https://files.pythonhosted.org/packages/d0/56/2e17d161a4f7ecc1c2ffb93e607b4e1898bb551b451b283235acb8f6ce47/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:923bb183c1dc64fdf7b717965e3d59938ec4f8b8710b419a21ce403e5da9a9e1", size = 3321189, upload-time = "2026-08-11T21:02:41.932Z" }, + { url = "https://files.pythonhosted.org/packages/cf/b8/8490916e893f3f8d74dc9cc54c078619364999dee37047a188e73abbc852/sqlalchemy-2.0.52-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:651d6d8782e80679e6151707c7b490834d46ada526328895abf567f25e63d29c", size = 3338185, upload-time = "2026-08-11T21:17:02.597Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f7/752cc8ee453da222829b3f5c4613614bf750d97429363b70414fa10478e4/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b08cddb8989775e3c88799d86704bdfc3ee6e9846118201aa5997f16f27e3a15", size = 3271698, upload-time = "2026-08-11T21:02:43.963Z" }, + { url = "https://files.pythonhosted.org/packages/51/e6/074ade0c07b9e4c8e8bca46820320ed94df9702afdb6f2af06623068d2e6/sqlalchemy-2.0.52-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ab66fa9618269390d4dfa222f2f2f88f7bc4bf5da13905131b818217db7e8057", size = 3308936, upload-time = "2026-08-11T21:17:04.172Z" }, + { url = "https://files.pythonhosted.org/packages/66/07/557c0d04716705599227945ac14e0a17ad0338e899f37d8c2ddff4dcc663/sqlalchemy-2.0.52-cp313-cp313-win32.whl", hash = "sha256:c63bda077685c85ca513286547a531ba57e7a68cf0a7ed3bafcc2bbd18896f4d", size = 2127308, upload-time = "2026-08-11T21:14:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/96/4e/226eda27654318ce525d043025221f689abef883da2c7126f9065121618c/sqlalchemy-2.0.52-cp313-cp313-win_amd64.whl", hash = "sha256:9876b09b9f1ce7398b0ffece585c0a911244c53191187341f6bcae640e133751", size = 2153876, upload-time = "2026-08-11T21:14:55.527Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f5/71cb30af58c9b80a4e1fac0b73bb48f86d497a774a6a2eb6d2f1e657bb73/sqlalchemy-2.0.52-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:410d52be41d17f1a236d19520fbe776257dc16516ed06bd16d433311842aefd9", size = 2169537, upload-time = "2026-08-11T20:58:13.855Z" }, + { url = "https://files.pythonhosted.org/packages/4c/93/d07ebd645d1b07b6b5ed63450a70f063a346a7e0f2c8810daf2e532400cb/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfe9ce533dbe4d0a2ae1486546619bd30b76bcd670539a44d910361376175f5e", size = 3319606, upload-time = "2026-08-11T21:02:45.829Z" }, + { url = "https://files.pythonhosted.org/packages/ae/5c/290c84c7c2566ecd3b65baaae0fddec9bc33b033b398a06123bb86fbfc6e/sqlalchemy-2.0.52-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:812bae5138bfc0aa46fb0686da0fc7f581f68e2bbb05bc24c3713bebaedd1437", size = 3323642, upload-time = "2026-08-11T21:17:05.675Z" }, + { url = "https://files.pythonhosted.org/packages/13/f5/2cc160590ca49173359557880b92a0572293ccb899e8f6cedf150c5a3ddf/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:50bff43b632a56fbf5ed9afdd76307e1512b62051bcd5afb341ae67205bbb6c8", size = 3268125, upload-time = "2026-08-11T21:02:47.649Z" }, + { url = "https://files.pythonhosted.org/packages/35/f3/ea8933fc9f7d1353e9c2ff9965eae687c4cef181120574591ed2fa0633e1/sqlalchemy-2.0.52-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:49565daf5af554f538e23aef1fc81a95a4e49658f152285e45c02f5fc44f04cd", size = 3289516, upload-time = "2026-08-11T21:17:07.267Z" }, + { url = "https://files.pythonhosted.org/packages/45/67/05cf86541c1e1716fca1e4a996954a439cd74501707cda607fb7cb02ef50/sqlalchemy-2.0.52-cp314-cp314-win32.whl", hash = "sha256:ab9da41e61b9979b910499d633b241df20c51ee5037e5405b11c2faac3cbe1a2", size = 2130249, upload-time = "2026-08-11T21:14:57.273Z" }, + { url = "https://files.pythonhosted.org/packages/96/d7/8ac6ffa1e36169e762ef65bd835046abb2251b1bc17f8f6708e14ed8d31f/sqlalchemy-2.0.52-cp314-cp314-win_amd64.whl", hash = "sha256:a593db51b3bae75db17a5738ad5f992244b3a03863f83c28117ee482c6a3f76d", size = 2156718, upload-time = "2026-08-11T21:14:58.667Z" }, + { url = "https://files.pythonhosted.org/packages/dc/4b/e01a737eef378e734cc6394a82248a6ce13b167dfa36c731075ce9fc9c64/sqlalchemy-2.0.52-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1e61d08bdf4ee2f41024569e3400de7d6734ba498144766b11260936ccfa582", size = 2190344, upload-time = "2026-08-11T19:53:21.393Z" }, + { url = "https://files.pythonhosted.org/packages/b3/3f/3582293d1e185e71d19d7c731c3e2ee20ba21981c4a1115c0806c1f62120/sqlalchemy-2.0.52-py3-none-any.whl", hash = "sha256:3b81b8363a919ce53453591cdb93702e6bd54ade6c4fa2f468fc053baee5ed89", size = 1950700, upload-time = "2026-08-11T20:47:21.603Z" }, ] [[package]] diff --git a/script/cibuild b/script/cibuild index d896271..18dd619 100755 --- a/script/cibuild +++ b/script/cibuild @@ -9,7 +9,7 @@ cd "$(dirname "$0")/.." echo " => Baue Image localhost/kontor-spring:0.3.0" buildah build -t kontor-spring:0.3.0 kontor-spring echo " => Baue Image localhost/kontor-api:0.3.0" -buildah build -t kontor-api:0.3.0 kontor-api +buildah build --volume /home/tpeetz/projects/kontor/kontor-model:/container/kontor-model kontor-api:0.3.0 kontor-api echo " => Baue Image localhost/kontor-quarkus:0.3.0" buildah build -t kontor-quarkus:0.3.0 kontor-quarkus echo " => Baue Image localhost/kontor-echo:0.3.0" diff --git a/script/update b/script/update index f74c8c7..fe8622b 100755 --- a/script/update +++ b/script/update @@ -11,7 +11,7 @@ if podman pod exists kontor; then podman pod stop kontor fi -script/cibuild +#script/cibuild script/setup