From c701a4ab9b5fe9f385f29f9038fac15b443669da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Ur=C3=ADa?= Date: Sun, 15 Feb 2026 11:32:33 +0100 Subject: [PATCH] [WIP] Library REST API --- app/api/cruds/base/__init__.py | 4 +-- app/api/cruds/base/read.py | 6 +++- app/controller/__init__.py | 21 +++++++++++- app/routes/api/library/__init__.py | 5 ++- app/routes/api/library/delete.py | 23 +++++++++++++ app/routes/api/library/read.py | 27 ++++++++++++++++ app/routes/api/library/update.py | 50 +++++++++++++++++++++++++++++ test.db | Bin 32768 -> 32768 bytes 8 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 app/routes/api/library/delete.py create mode 100644 app/routes/api/library/read.py create mode 100644 app/routes/api/library/update.py diff --git a/app/api/cruds/base/__init__.py b/app/api/cruds/base/__init__.py index 9dcb188..4ef2533 100644 --- a/app/api/cruds/base/__init__.py +++ b/app/api/cruds/base/__init__.py @@ -1,4 +1,4 @@ from .create import create -from .read import read +from .read import read, read_all from .update import update -from .delete import delete \ No newline at end of file +from .delete import delete diff --git a/app/api/cruds/base/read.py b/app/api/cruds/base/read.py index 8bb8645..1fdab10 100644 --- a/app/api/cruds/base/read.py +++ b/app/api/cruds/base/read.py @@ -5,4 +5,8 @@ from ....schema.library.base import Base def read(session:Session, _id:int, obj:Base): stmt = select(obj).where(obj.id == _id) - return session.scalars(stmt).one() \ No newline at end of file + return session.scalars(stmt).one() + +def read_all(session:Session, obj:Base): + stmt = select(obj) + return session.scalars(stmt).fetchall() #TODO: Pagination \ No newline at end of file diff --git a/app/controller/__init__.py b/app/controller/__init__.py index c9f272b..d75747b 100644 --- a/app/controller/__init__.py +++ b/app/controller/__init__.py @@ -1,7 +1,7 @@ from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -from app.api.cruds.base import create, read, update, delete +from app.api.cruds.base import create, read, update, delete, read_all from app.schema.library import Library from ..db.config.config import get_engine_configuration @@ -22,6 +22,9 @@ class LibraryController: self._library = None if library_id is not None: self.read(library_id) + + self._libraries = [] + def __del__(self): self.session.close() @@ -49,6 +52,19 @@ class LibraryController: def session(self): return self._session + @property + def libraries(self): + if self._library and len(self._libraries) == 0: + self._libraries = [self._library] + return self._libraries + + def set_library(self, _id): + libraries = filter(lambda x: x.get("id") == _id, self.libraries) + if len(libraries) == 1: + self._library = libraries[0] + return True + return False + def create(self, library:Library): self._library = create(self.session, library) return self @@ -56,6 +72,9 @@ class LibraryController: def read(self, _id): self._library = read(self.session, _id, Library) return self + + def read_all(self): + self._libraries = read_all(self.session, Library) def update(self): self.session.commit() diff --git a/app/routes/api/library/__init__.py b/app/routes/api/library/__init__.py index b4a18a3..7a73116 100644 --- a/app/routes/api/library/__init__.py +++ b/app/routes/api/library/__init__.py @@ -1,2 +1,5 @@ from .blueprint import api_library -from .create import create_library \ No newline at end of file +from .create import create_library +from .read import read_libraries, read_library +from .update import update_library +from .delete import delete_library \ No newline at end of file diff --git a/app/routes/api/library/delete.py b/app/routes/api/library/delete.py new file mode 100644 index 0000000..5b66150 --- /dev/null +++ b/app/routes/api/library/delete.py @@ -0,0 +1,23 @@ +from flask import request +from sqlalchemy.exc import NoResultFound + +from .blueprint import api_library + +from ....controller import LibraryController +from ....schema.library.library import Library + +import logging +logger = logging.getLogger(__name__) + +@api_library.route("/<_id>", methods=["DELETE"]) +def delete_library(_id): + + try: # TODO: function + controller = LibraryController(_id) + except NoResultFound as e: + logger.debug({e}) + return { "status": "error", "error": "Library not found" }, 404 + + controller.delete() + + return { "status": "ok" }, 201 \ No newline at end of file diff --git a/app/routes/api/library/read.py b/app/routes/api/library/read.py new file mode 100644 index 0000000..17d68af --- /dev/null +++ b/app/routes/api/library/read.py @@ -0,0 +1,27 @@ +from flask import request +from sqlalchemy.exc import NoResultFound + +from .blueprint import api_library + +from ....controller import LibraryController +from ....schema.library.library import Library + +import logging +logger = logging.getLogger(__name__) + +@api_library.route("/", methods=["GET"]) +def read_libraries(): + library = LibraryController() + library.read_all() + return { "status": "ok", "results": [lib.to_dict() for lib in library.libraries] }, 200 + +@api_library.route("/<_id>", methods=["GET"]) +def read_library(_id): + try: + library = LibraryController(_id) + except NoResultFound as e: + logger.debug(f"No result found for Library wid id {_id}") + logger.debug(f"Error {e}") + logger.debug(f"Error {dir(e)}") + return { "status": "error", "result": "Library not found"}, 404 + return { "status": "ok", "result": library.data.to_dict() }, 200 diff --git a/app/routes/api/library/update.py b/app/routes/api/library/update.py new file mode 100644 index 0000000..179e4cb --- /dev/null +++ b/app/routes/api/library/update.py @@ -0,0 +1,50 @@ +from flask import request +from sqlalchemy.exc import IntegrityError, NoResultFound + +from .blueprint import api_library + +from ....controller import LibraryController +from ....schema.library.library import Library + +import logging +logger = logging.getLogger(__name__) + +def update_library_item(library:Library, key, value): + if key == "id": + raise AttributeError("id is not updatable") + try: + library.__getattribute__(key) + except AttributeError: + raise AttributeError(f"{key} not in library") + library.__setattr__(key, value) + +@api_library.route("/<_id>", methods=["PATCH"]) +def update_library(_id): + try: + data:dict = request.json + logger.debug(f"data: {data}") + except Exception as e: + logger.debug(f"{e}") + return { "status": "error", "error": "JSON Required" }, 415 + + try: # TODO: function + controller = LibraryController(_id) + except NoResultFound as e: + logger.debug({e}) + return { "status": "error", "error": "Library not found" }, 404 + + library = controller.data + for key, value in data.items(): + try: + update_library_item(library, key, value) + except AttributeError as e: + logger.debug(f"Error updating {e}") + return { "status": "error", "error": e.name } + + try: + controller.update() + except IntegrityError as e: + logger.debug(f"DB Error Creating {e}") + return { "status": "error", "error": f"{e.orig}" }, 400 + else: + return { "status": "ok", "result": controller.data.to_dict() }, 200 \ No newline at end of file diff --git a/test.db b/test.db index 838c097b9a1e18175de1d2317aa439d6f491d499..cd897f14deaeae229c54d4e14b06e8763559aa14 100644 GIT binary patch delta 156 zcmZo@U}|V!njp={HBrWyk!xeZLVj-k2MkR7GZ^@1@SoW%DA2?2W5me9;ArZYmtT^R zTBMMlm#UDIS&~|;0OTs9lopqSWMmdA08t`T1yHU;h>3+kSvV}eG$*x60Z0`mW+XB& nFeprPl;Pn5GMM-;G4Ma)zXY`57{35Nvoa%+TBgm9^yLBo9{Mg! delta 73 zcmZo@U}|V!njp={K2gS*k$q#rLVivL1_nm{2MqiVHVYbD<7bm&WMOb*m^@Ejii-;@ X^@xH05m4#|KZ`80BPU2=kwE|elOGY%