From 64e8d6871f607c126be507ed14c7265bd7f53ef7 Mon Sep 17 00:00:00 2001 From: Yaro Kasear Date: Mon, 15 Sep 2025 08:26:08 -0500 Subject: [PATCH] Added CRUDKit registry functionality. --- crudkit/integration.py | 25 +++++++++++++++++++ crudkit/registry.py | 27 +++++++++++++++++++- crudkit/ui/fragments.py | 2 +- inventory/__init__.py | 34 +++++++++++--------------- inventory/templates/crudkit/table.html | 2 +- 5 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 crudkit/integration.py diff --git a/crudkit/integration.py b/crudkit/integration.py new file mode 100644 index 0000000..665e813 --- /dev/null +++ b/crudkit/integration.py @@ -0,0 +1,25 @@ +from __future__ import annotations +from typing import Type +from flask import Flask + +from crudkit.engines import CRUDKitRuntime + +from .registry import CRUDRegistry + +class CRUDKit: + def __init__(self, app: Flask, runtime: CRUDKitRuntime): + self.app = app + self.runtime = runtime + self.registry = CRUDRegistry(runtime) + + def register(self, model: Type, **kwargs): + return self.registry.register_class(self.app, model, **kwargs) + + def register_many(self, models: list[Type], **kwargs): + return self.registry.register_many(self.app, models, **kwargs) + + def get_model(self, key: str): + return self.registry.get_model(key) + + def get_service(self, model: Type): + return self.registry.get_service(model) diff --git a/crudkit/registry.py b/crudkit/registry.py index 8dc200d..9c66153 100644 --- a/crudkit/registry.py +++ b/crudkit/registry.py @@ -92,4 +92,29 @@ class CRUDRegistry: bp.name = bp_name app.register_blueprint(bp, url_prefix=prefix) - reg = Registered(model=model, service=) + reg = Registered(model=model, service=svc, blueprint_name=bp_name, url_prefix=prefix) + self._bps_by_model[model] = reg + return reg + + def register_many( + self, + app: Flask, + models: list[Type[Any]], + *, + base_prefix: str = "/api", + polymorphic: bool = False, + service_kwargs: Optional[dict] = None, + ) -> list[Registered]: + out: list[Registered] = [] + for m in models: + key = self._key(m) + out.append( + self.register_class( + app, + m, + url_prefix=f"{base_prefix}/{key}", + polymorphic=polymorphic, + service_kwargs=service_kwargs, + ) + ) + return out diff --git a/crudkit/ui/fragments.py b/crudkit/ui/fragments.py index 6a3b7a4..4fe4208 100644 --- a/crudkit/ui/fragments.py +++ b/crudkit/ui/fragments.py @@ -85,7 +85,7 @@ def _build_href(spec: Dict[str, Any], row: Dict[str, Any], obj) -> Optional[str] print(f"[render_table] url_for failed: endpoint={spec}: params={params}") return None try: - return url_for(spec["endpoint"], **params) + return url_for('crudkit.' + spec["endpoint"], **params) except Exception as e: print(f"[render_table] url_for failed: endpoint={spec['endpoint']} params={params} err={e}") return None diff --git a/inventory/__init__.py b/inventory/__init__.py index 4eb2929..e392936 100644 --- a/inventory/__init__.py +++ b/inventory/__init__.py @@ -6,6 +6,7 @@ from flask import Flask from crudkit import ProdConfig from crudkit.api.flask_api import generate_crud_blueprint from crudkit.core.service import CRUDService +from crudkit.integration import CRUDKit from crudkit.integrations.flask import init_app from .config import DevConfig @@ -17,6 +18,7 @@ def create_app(config_cls=DevConfig) -> Flask: app = Flask(__name__) runtime = init_app(app, config=ProdConfig) + crud = CRUDKit(app, runtime) print(f"Effective DB URL: {str(runtime.engine.url)}") from . import models as _models @@ -30,27 +32,19 @@ def create_app(config_cls=DevConfig) -> Flask: session = Session - area_service = CRUDService(_models.Area, session) - brand_service = CRUDService(_models.Brand, session) - device_type_service = CRUDService(_models.DeviceType, session) - image_service = CRUDService(_models.Image, session) - inventory_service = CRUDService(_models.Inventory, session) - room_function_service = CRUDService(_models.RoomFunction, session) - room_service = CRUDService(_models.Room, session) - user_service = CRUDService(_models.User, session) - work_log_service = CRUDService(_models.WorkLog, session) - work_note_service = CRUDService(_models.WorkNote, session) + crud.register_many([ + _models.Area, + _models.Brand, + _models.DeviceType, + _models.Image, + _models.Inventory, + _models.RoomFunction, + _models.Room, + _models.User, + _models.WorkLog, + _models.WorkNote, + ]) - app.register_blueprint(generate_crud_blueprint(_models.Area, area_service), url_prefix="/api/area") - app.register_blueprint(generate_crud_blueprint(_models.Brand, brand_service), url_prefix="/api/brand") - app.register_blueprint(generate_crud_blueprint(_models.DeviceType, device_type_service), url_prefix="/api/device_type") - app.register_blueprint(generate_crud_blueprint(_models.Image, image_service), url_prefix="/api/image") - app.register_blueprint(generate_crud_blueprint(_models.Inventory, inventory_service), url_prefix="/api/inventory") - app.register_blueprint(generate_crud_blueprint(_models.RoomFunction, room_function_service), url_prefix="/api/room_function") - app.register_blueprint(generate_crud_blueprint(_models.Room, room_service), url_prefix="/api/room") - app.register_blueprint(generate_crud_blueprint(_models.User, user_service), url_prefix="/api/user") - app.register_blueprint(generate_crud_blueprint(_models.WorkLog, work_log_service), url_prefix="/api/work_log") - app.register_blueprint(generate_crud_blueprint(_models.WorkNote, work_note_service), url_prefix="/api/work_note") app.register_blueprint(bp_reports) init_index_routes(app) diff --git a/inventory/templates/crudkit/table.html b/inventory/templates/crudkit/table.html index d25fe34..2f5d414 100644 --- a/inventory/templates/crudkit/table.html +++ b/inventory/templates/crudkit/table.html @@ -9,7 +9,7 @@ {% if rows %} {% for row in rows %} - + {% for cell in row.cells %} {% if cell.href %} {{ cell.text if cell.text is not none else '-' }}