From 664121326246c921305447caef7f0c57baf7ce7b Mon Sep 17 00:00:00 2001 From: Birger Schacht Date: Mon, 13 Jan 2025 11:18:56 +0100 Subject: [PATCH] feat: introduce rdfproxywrapper --- pfp_api/main.py | 21 ++++++++------------- pfp_api/rdfproxy.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 pfp_api/rdfproxy.py diff --git a/pfp_api/main.py b/pfp_api/main.py index 1302820..5fe6f75 100644 --- a/pfp_api/main.py +++ b/pfp_api/main.py @@ -5,13 +5,15 @@ from fastapi import FastAPI, Query, HTTPException from fastapi.responses import RedirectResponse -from rdfproxy import Page, SPARQLModelAdapter, QueryParameters +from rdfproxy import Page, QueryParameters +from pfp_api.rdfproxy import RDFProxyWrapper from pfp_api.models import Person, PersonDetail app = FastAPI() env = Environment(loader=PackageLoader("pfp_api")) +rfp = RDFProxyWrapper("https://pfp-ts-backend.acdh-ch-dev.oeaw.ac.at/") class PersonParams(QueryParameters): @@ -26,12 +28,8 @@ def root(): @app.get("/persons") def persons(query_parameters: Annotated[PersonParams, Query()]) -> Page[Person]: template = env.get_template("persons.j2") - adapter = SPARQLModelAdapter( - target="https://pfp-ts-backend.acdh-ch-dev.oeaw.ac.at/", - query=template.render(dict(query_parameters)), - model=Person, - ) - return adapter.query(query_parameters) + query = template.render(dict(query_parameters)) + return rfp.paginate(query=query, model=Person, page=query_parameters.page, size=query_parameters.size) @app.get("/person/{person_id}") @@ -41,9 +39,6 @@ def person(person_id: str): person_id = urlsafe_b64decode(person_id).decode() except binascii.Error: raise HTTPException(status_code=404, detail="Person not found") - adapter = SPARQLModelAdapter( - target="https://pfp-ts-backend.acdh-ch-dev.oeaw.ac.at/", - query=template.render({"person_id": person_id}), - model=PersonDetail - ) - return adapter.query(QueryParameters()) + + query = template.render({"person_id": person_id}) + return rfp.query(query=query, model=PersonDetail) diff --git a/pfp_api/rdfproxy.py b/pfp_api/rdfproxy.py new file mode 100644 index 0000000..dac18b1 --- /dev/null +++ b/pfp_api/rdfproxy.py @@ -0,0 +1,43 @@ +import logging +import math +from collections.abc import Iterator +from rdfproxy.constructor import QueryConstructor +from rdfproxy.utils.models import QueryParameters +from rdfproxy.sparql_strategies import HttpxStrategy +from rdfproxy.mapper import ModelBindingsMapper +from rdfproxy.utils.models import Page +from pydantic import BaseModel + +logger = logging.getLogger(__name__) + + +class RDFProxyWrapper: + def __init__(self, target: str): + self.strategy = HttpxStrategy(target) + + def query(self, query, model, query_parameters) -> BaseModel: + query_constructor = QueryConstructor(query=query, query_parameters=query_parameters, model=model) + items_query = query_constructor.get_items_query() + logger.debug(items_query) + print(items_query) + + items_query_bindings: Iterator[dict] = self.strategy.query(items_query) + mapper = ModelBindingsMapper(model, *items_query_bindings) + items: list[BaseModel] = mapper.get_models() + + return items + + def paginate(self, query, model, page=1, size=100) -> Page[BaseModel]: + qp = QueryParameters().parse_obj({"page": page, "size": size}) + query_constructor = QueryConstructor(query=query, query_parameters=qp, model=model) + count_query = query_constructor.get_count_query() + logger.debug(count_query) + print(count_query) + + count_query_bindings: Iterator[dict] = self.strategy.query(count_query) + total: int = int(next(count_query_bindings)["cnt"]) + pages: int = math.ceil(total / size) + + items = self.query(query, model, qp) + + return Page(items=items, page=page, size=size, total=total, pages=pages)