Skip to content

oarepo_oaipmh_harvester.oai_record.resource

oarepo_oaipmh_harvester.oai_record.resource

OAI Record resource config.

AdministrationDetailJSONSerializer

Bases: JSONSerializer

JSON serializer for administration API.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
class AdministrationDetailJSONSerializer(JSONSerializer):
    """JSON serializer for administration API."""

    @override
    def serialize_object(self, obj: Any) -> str:
        """Serialize a single object."""
        obj = self._convert_to_administration_detail(obj)
        return super().serialize_object(obj)

    @override
    def serialize_object_list(self, obj_list: dict[str, Any]) -> str:
        obj_list["hits"]["hits"] = [self._convert_to_administration_detail(obj) for obj in obj_list["hits"]["hits"]]
        return super().serialize_object_list(obj_list)

    def _convert_to_administration_detail(self, serialized_record: dict[str, Any]) -> dict[str, Any]:
        serialized_record = {**serialized_record}
        tr = serialized_record.get("transformed_data", {})
        if tr:
            serialized_record["title"] = tr.get("metadata", {}).get("title", "") or tr.get("title", "")
            if serialized_record["title"]:
                serialized_record["title"] = str(serialized_record["title"])
        record_pid = serialized_record.get("record_pid")
        if record_pid:
            record_link = tr.get("links", {}).get("self_html")
            if record_link:
                serialized_record["record_id_with_link"] = '<a href="{}">{}</a>'.format(
                    record_link, serialized_record["record_pid"]
                )
            else:
                serialized_record["record_id_with_link"] = '<a href="{}">{}</a>'.format(
                    f"/records/{record_pid}", serialized_record["record_pid"]
                )
        serialized_record["errors"] = data_to_html_yaml(
            location_to_list(cast("list[Any]", serialized_record.get("errors")))
        )
        serialized_record["original_data"] = data_to_html_yaml(serialized_record.get("original_data"))
        serialized_record["transformed_data"] = data_to_html_yaml(serialized_record.get("transformed_data"))
        serialized_record["has_errors"] = serialized_record.get("has_errors")
        serialized_record["deleted"] = serialized_record.get("deleted")
        return serialized_record

serialize_object(obj: Any) -> str

Serialize a single object.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
@override
def serialize_object(self, obj: Any) -> str:
    """Serialize a single object."""
    obj = self._convert_to_administration_detail(obj)
    return super().serialize_object(obj)

OAIRecordResourceConfig

Bases: RecordResourceConfig

Harvest record resource configuration.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
class OAIRecordResourceConfig(RecordResourceConfig):
    """Harvest record resource configuration."""

    blueprint_name = "oai_records"
    url_prefix = "/oai/harvest/records"
    api_service = "oai-harvest-record"

    routes: Mapping[str, Any] = {
        "list": "",
        "item": "/<path:id>",
        "harvest": "/<path:id>/harvest",
    }

    request_view_args: Mapping[str, Any] = {
        "id": ma.fields.Str(),
    }

    error_handlers: Mapping[
        type[HTTPException | BaseException] | int,
        Callable[[Exception], Response],
    ] = {
        **ErrorHandlersMixin.error_handlers,
    }

    response_handlers: Mapping[str, Any] = {
        "application/vnd.inveniordm.v1+json": RecordResourceConfig.response_handlers["application/json"],
        "application/invenio-administration-detail+json": ResponseHandler(
            serializer=AdministrationDetailJSONSerializer(),
            headers=etag_headers,
        ),
        **RecordResourceConfig.response_handlers,
    }

OAIRecordResource

Bases: RecordResource

OAI Record resource.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
class OAIRecordResource(RecordResource):
    """OAI Record resource."""

    def p(self, prefix: str, route: str) -> str:
        """Prefix a route with the URL prefix."""
        return f"{prefix}{route}"

    def create_url_rules(self) -> list:
        """Create the URL rules for the harvest record resource."""
        routes = self.config.routes
        return [
            route("GET", routes["list"], self.search),
            route("GET", routes["item"], self.read),
            route("POST", routes["harvest"], self.harvest),
        ]

    @override
    @request_search_args
    @request_view_args
    @response_handler(many=True)
    def search(self) -> tuple[dict[str, Any], int]:
        """Search harvest records."""
        hits = self.service.search(
            identity=g.identity,
            params=resource_requestctx.args,
            search_preference=search_preference(),
        )
        return hits.to_dict(), 200

    @override
    @request_view_args
    @response_handler()
    def read(self) -> tuple[dict[str, Any], int]:
        """Read a single harvest record."""
        item = self.service.read(
            id_=resource_requestctx.view_args["id"],
            identity=g.identity,
        )
        return item.to_dict(), 200

    @request_view_args
    @response_handler()
    def harvest(self) -> tuple[dict[str, Any], int]:
        """Re-harvest the OAI record."""
        item = self.service.harvest(
            id_=resource_requestctx.view_args["id"],
            identity=g.identity,
        )
        return item.to_dict(), 200

p(prefix: str, route: str) -> str

Prefix a route with the URL prefix.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
def p(self, prefix: str, route: str) -> str:
    """Prefix a route with the URL prefix."""
    return f"{prefix}{route}"

create_url_rules() -> list

Create the URL rules for the harvest record resource.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
def create_url_rules(self) -> list:
    """Create the URL rules for the harvest record resource."""
    routes = self.config.routes
    return [
        route("GET", routes["list"], self.search),
        route("GET", routes["item"], self.read),
        route("POST", routes["harvest"], self.harvest),
    ]

search() -> tuple[dict[str, Any], int]

Search harvest records.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
@override
@request_search_args
@request_view_args
@response_handler(many=True)
def search(self) -> tuple[dict[str, Any], int]:
    """Search harvest records."""
    hits = self.service.search(
        identity=g.identity,
        params=resource_requestctx.args,
        search_preference=search_preference(),
    )
    return hits.to_dict(), 200

read() -> tuple[dict[str, Any], int]

Read a single harvest record.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
@override
@request_view_args
@response_handler()
def read(self) -> tuple[dict[str, Any], int]:
    """Read a single harvest record."""
    item = self.service.read(
        id_=resource_requestctx.view_args["id"],
        identity=g.identity,
    )
    return item.to_dict(), 200

harvest() -> tuple[dict[str, Any], int]

Re-harvest the OAI record.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
@request_view_args
@response_handler()
def harvest(self) -> tuple[dict[str, Any], int]:
    """Re-harvest the OAI record."""
    item = self.service.harvest(
        id_=resource_requestctx.view_args["id"],
        identity=g.identity,
    )
    return item.to_dict(), 200

data_to_html_yaml(data: Any) -> str

Convert data to HTML highlighted YAML.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
def data_to_html_yaml(data: Any) -> str:
    """Convert data to HTML highlighted YAML."""
    yaml_str = yaml.dump(data, default_flow_style=False, sort_keys=False, allow_unicode=True)
    return highlight(yaml_str, YamlLexer(), HtmlFormatter(full=False))

location_to_list(errors: list[Any] | None) -> list[Any]

Convert error locations inside serialized errors from string to list.

Source code in oarepo_oaipmh_harvester/oai_record/resource.py
def location_to_list(errors: list[Any] | None) -> list[Any]:
    """Convert error locations inside serialized errors from string to list."""
    if errors is None:
        return []
    for error in errors:
        error_location = error.get("location")
        if error_location is not None:
            error["location"] = error_location.split("\n")
    return errors