Skip to content

oarepo_oaipmh_harvester.oai_harvester.resource

oarepo_oaipmh_harvester.oai_harvester.resource

OAI Harvester HTTP resource.

AdministrationDetailJSONSerializer

Bases: JSONSerializer

JSON serializer for administration API.

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

    @override
    def serialize_object(self, obj: Any) -> str:
        """Serialize a single harvester into the administration detail form."""
        obj = self._convert_to_administration_detail(obj)
        # rendered as html by the detail view; only here, as it costs two searches per harvester
        obj["harvested_records"] = _harvested_records_html(obj["id"])
        return super().serialize_object(obj)

    @override
    def serialize_object_list(self, obj_list: list[Any]) -> str:
        """Serialize a list of harvesters into the administration detail form."""
        obj_list = [self._convert_to_administration_detail(obj) for obj in obj_list]
        return super().serialize_object_list(obj_list)

    def _convert_to_administration_detail(self, serialized_harvester: dict[str, Any]) -> dict[str, Any]:
        serialized_harvester = {**serialized_harvester}
        serialized_harvester["transformers"] = data_to_html_yaml(serialized_harvester["transformers"])
        serialized_harvester["writers"] = data_to_html_yaml(serialized_harvester["writers"])
        # rendered as html by the detail view
        serialized_harvester["harvest_managers"] = "<br>".join(
            str(escape(email)) for email in _manager_emails(serialized_harvester)
        )
        # TODO: link to jobs here
        return serialized_harvester

serialize_object(obj: Any) -> str

Serialize a single harvester into the administration detail form.

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
@override
def serialize_object(self, obj: Any) -> str:
    """Serialize a single harvester into the administration detail form."""
    obj = self._convert_to_administration_detail(obj)
    # rendered as html by the detail view; only here, as it costs two searches per harvester
    obj["harvested_records"] = _harvested_records_html(obj["id"])
    return super().serialize_object(obj)

serialize_object_list(obj_list: list[Any]) -> str

Serialize a list of harvesters into the administration detail form.

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
@override
def serialize_object_list(self, obj_list: list[Any]) -> str:
    """Serialize a list of harvesters into the administration detail form."""
    obj_list = [self._convert_to_administration_detail(obj) for obj in obj_list]
    return super().serialize_object_list(obj_list)

AdministrationEditJSONSerializer

Bases: JSONSerializer

JSON serializer for the administration edit form.

The form edits transformers, writers and harvest_managers in textareas - they are serialized as newline separated text, managers as their e-mail addresses. The schema accepts the same text back (OAIHarvesterSchema).

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
class AdministrationEditJSONSerializer(JSONSerializer):
    """JSON serializer for the administration edit form.

    The form edits `transformers`, `writers` and `harvest_managers` in textareas - they are
    serialized as newline separated text, managers as their e-mail addresses. The schema
    accepts the same text back
    ([OAIHarvesterSchema][oarepo_oaipmh_harvester.oai_harvester.schema.OAIHarvesterSchema]).
    """

    @override
    def serialize_object(self, obj: Any) -> str:
        """Serialize a single harvester for the edit form."""
        return super().serialize_object(self._convert_to_form(obj))

    def _convert_to_form(self, serialized_harvester: dict[str, Any]) -> dict[str, Any]:
        return {
            **serialized_harvester,
            "transformers": "\n".join(serialized_harvester.get("transformers") or []),
            "writers": "\n".join(serialized_harvester.get("writers") or []),
            "harvest_managers": "\n".join(_manager_emails(serialized_harvester)),
        }

serialize_object(obj: Any) -> str

Serialize a single harvester for the edit form.

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
@override
def serialize_object(self, obj: Any) -> str:
    """Serialize a single harvester for the edit form."""
    return super().serialize_object(self._convert_to_form(obj))

OAIHarvesterResourceConfig

Bases: RecordResourceConfig, ConfiguratorMixin

OAI-PMH harvester resource configuration.

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
class OAIHarvesterResourceConfig(RecordResourceConfig, ConfiguratorMixin):
    """OAI-PMH harvester resource configuration."""

    blueprint_name = "oarepo-oaipmh-harvester"
    url_prefix = "/oai/harvest/harvesters/"

    api_service = "oarepo-oaipmh-harvesters"
    routes: Mapping[str, str] = {
        "list": "",
        "item": "/<pid_value>",
        "harvest": "/<pid_value>/start",
    }

    response_handlers: Mapping[str, ResponseHandler] = {
        "application/json": ResponseHandler(
            serializer=JSONSerializer(),
            headers=etag_headers,
        ),
        # the administration edit page fetches the record with react-invenio-forms' default Accept
        "application/vnd.inveniordm.v1+json": ResponseHandler(
            serializer=AdministrationEditJSONSerializer(),
            headers=etag_headers,
        ),
        "application/invenio-administration-detail+json": ResponseHandler(
            serializer=AdministrationDetailJSONSerializer(),
            headers=etag_headers,
        ),
    }

OAIHarvesterResource

Bases: RecordResource

REST resource for OAI-PMH harvesters.

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
class OAIHarvesterResource(RecordResource):
    """REST resource for OAI-PMH harvesters."""

    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[dict[str, Any]]:
        """Create the URL rules for the harvester resource."""
        routes = self.config.routes
        return [
            route("GET", routes["list"], self.search),
            route("GET", routes["item"], self.read),
            route("PUT", routes["item"], self.update),
            route("DELETE", routes["item"], self.delete),
            route("POST", routes["harvest"], self.harvest),
        ]

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

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

    @request_view_args
    @request_data
    @response_handler()
    def harvest(self) -> tuple[dict[str, Any], int]:
        """Harvest the source - all records unless the payload has `all_records: false`."""
        item = self.service.harvest(
            id_=resource_requestctx.view_args["pid_value"],
            identity=g.identity,
            all_records=(resource_requestctx.data or {}).get("all_records", True),
        )
        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_harvester/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[dict[str, Any]]

Create the URL rules for the harvester resource.

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
def create_url_rules(self) -> list[dict[str, Any]]:
    """Create the URL rules for the harvester resource."""
    routes = self.config.routes
    return [
        route("GET", routes["list"], self.search),
        route("GET", routes["item"], self.read),
        route("PUT", routes["item"], self.update),
        route("DELETE", routes["item"], self.delete),
        route("POST", routes["harvest"], self.harvest),
    ]

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

Search harvesters.

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
@request_search_args
@request_view_args
@response_handler(many=True)
def search(self) -> tuple[dict[str, Any], int]:
    """Search harvesters."""
    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 harvester.

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

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

Harvest the source - all records unless the payload has all_records: false.

Source code in oarepo_oaipmh_harvester/oai_harvester/resource.py
@request_view_args
@request_data
@response_handler()
def harvest(self) -> tuple[dict[str, Any], int]:
    """Harvest the source - all records unless the payload has `all_records: false`."""
    item = self.service.harvest(
        id_=resource_requestctx.view_args["pid_value"],
        identity=g.identity,
        all_records=(resource_requestctx.data or {}).get("all_records", True),
    )
    return item.to_dict(), 200

data_to_html_yaml(data: Any) -> str

Convert data to HTML-formatted YAML string.

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