Skip to main content

OARepo Runtime

Runtime extensions for Invenio framework.

Overview

This package extends Invenio with:

  • Model registry for unified record type configuration
  • Typed system fields with dynamic OpenSearch mapping
  • Nested and date-range facets with permission-based filtering
  • Service component dependency ordering
  • Multilingual schema support (I18N)
  • FAIR Signposting implementation (HTTP Link headers and linksets)
  • Repository information endpoints
  • Custom field mapping updates
  • CLI extensions for search initialization

Installation

pip install oarepo-runtime

Requirements

  • Python 3.13+
  • Invenio 14.x
  • OpenSearch/Elasticsearch compatible search backend

Key Features

1. Model Registry and Management

Source: oarepo_runtime/api.py, oarepo_runtime/ext.py, oarepo_runtime/config.py

The Model class provides a unified configuration structure for record types in your repository:

from oarepo_runtime import Model
from flask_babel import lazy_gettext as _

model = Model(
    code="my_record",
    name=_("My Record Type"),
    version="1.0.0",
    service="my_records",
    resource_config="my_app.resources.config.MyRecordResourceConfig",
    description=_("Custom record type for my repository"),
    exports=[
        Export(
            code="datacite",
            name=_("DataCite JSON"),
            mimetype="application/vnd.datacite.datacite+json",
            serializer=DataCiteSerializer(),
        )
    ],
    records_alias_enabled=True,
)

Normally, it is created automatically when using the oarepo-model library.

The OARepoRuntime extension manages all registered models:

from oarepo_runtime import current_runtime

# Access models by code
model = current_runtime.models["my_record"]

# Get service for a record instance
service = current_runtime.get_record_service_for_record(record)

# Find records by PID type
record_class = current_runtime.record_class_by_pid_type["recid"]

# Get all RDM-compatible models
rdm_models = list(current_runtime.rdm_models)

Key capabilities:

  • Centralized model registration via OAREPO_MODELS configuration
  • Automatic service and resource resolution
  • PID type to record class mapping
  • Schema to model mapping for serialization
  • Support for draft/published record workflows
  • File service integration

2. Enhanced System Fields

Source: oarepo_runtime/records/systemfields/

Typed System Fields

Base class for system fields with type hints and proper typing support:

from oarepo_runtime.records.systemfields import TypedSystemField


class MyCustomField(TypedSystemField[MyRecord, str]):
    def obj_get(self, record: MyRecord) -> str:
        # Implementation
        pass

Mapping System Fields

Dynamic OpenSearch mapping support for system fields that need custom indexing:

from oarepo_runtime.records.systemfields import MappingSystemFieldMixin


class DynamicField(MappingSystemFieldMixin, TypedSystemField):
    def mapping_settings(self, record_class):
        return {"type": "keyword", "eager_global_ordinals": True}

Publication Status System Field

Built-in field for tracking record publication status:

from oarepo_runtime.records.systemfields import PublicationStatusSystemField


class MyRecord(Record):
    publication_status = PublicationStatusSystemField()

3. Advanced Faceting System

Source: oarepo_runtime/services/facets/

Date Range Facets

Support for date-based faceting with configurable intervals:

from oarepo_runtime.services.facets.date import DateRangeFacet

facets = {"created": DateRangeFacet(field="created", label="Created Date", interval="year")}

Nested Facets

Faceting on nested objects with label resolution:

from oarepo_runtime.services.facets.nested_facet import NestedLabeledFacet

facets = {
    "contributors": NestedLabeledFacet(
        field="metadata.contributors.person.id",
        nested_path="metadata.contributors",
        value_labels={"person123": {"cs": "Jan Novák", "en": "Jan Novak"}},
    )
}

Grouped Facets with Permissions

Permission-based facet grouping for different user roles:

from oarepo_runtime.services.facets.params import GroupedFacetsParam

search_config = {
    "facets": base_facets,
    "facet_groups": {
        "admin": {
            "label": "Admin Facets",
            "facets": ["internal_status", "workflow_state"],
            "provides_needs": [AdminNeed()],
        }
    },
}

4. Service Component Ordering

Source: oarepo_runtime/services/config/components.py

Deterministic ordering of service components with dependency resolution:

class ComponentOrderingMixin:
    """Mixin that ensures service components execute in the correct order."""

    @property
    def components(self):
        # Components are automatically ordered based on:
        # - depends_on declarations
        # - affects declarations
        # - wildcard semantics (*)
        # - input order preservation where possible
        return self._ordered_components

Components can declare dependencies:

class MyComponent(ServiceComponent):
    depends_on = [ValidationComponent]  # Runs after ValidationComponent
    affects = "*"  # Affects all subsequent components

5. Multilingual Support

Source: oarepo_runtime/services/schema/

I18N UI Schema Support

Marshmallow schemas with multilingual field support:

from oarepo_runtime.services.schema.i18n_ui import I18nUISchema, MultilingualUIField


class MyUISchema(I18nUISchema):
    title = MultilingualUIField()
    description = MultilingualUIField(
        ui_params={"widget": "textarea", "placeholder": {"en": "Enter description", "cs": "Zadejte popis"}}
    )

Locale Handling

from oarepo_runtime.services.schema.i18n import LocalizedDateTime


class RecordSchema(Schema):
    created = LocalizedDateTime()  # Automatically formats dates per locale

6. Signposting and FAIR Data

Source: oarepo_runtime/resources/signposting/

Full implementation of FAIR Signposting for machine-readable links:

from oarepo_runtime.resources.signposting import landing_page_signpost_links_list, create_linkset, create_linkset_json

# Generate signposting links for a landing page
links = landing_page_signpost_links_list(datacite_dict, record_dict, short=False)

# Create HTTP Link header
header = list_of_signpost_links_to_http_header(links)

# Create application/linkset format
linkset = create_linkset(datacite_dict, record_dict)

# Create application/linkset+json format
linkset_json = create_linkset_json(datacite_dict, record_dict)

Supported relation types:

  • author - Links to author identifiers
  • cite-as - Persistent identifier (DOI)
  • describedby - Metadata export formats
  • item - File contents
  • license - License URIs
  • type - Resource type (schema.org)

7. Repository Information API

Source: oarepo_runtime/info/views.py

Machine-readable endpoint for repository metadata:

# GET /.well-known/repository
{
    "models": {
        "my_record": {
            "code": "my_record",
            "name": "My Record Type",
            "version": "1.0.0",
            "links": {"search": "/api/my-records/", "ui": "/my-records/"},
            "jsonschemas": {"record": "https://localhost/schemas/my-records-1.0.0.json"},
            "exports": [{"code": "datacite", "mimetype": "application/vnd.datacite.datacite+json"}],
        }
    }
}

8. CLI Extensions

Source: oarepo_runtime/cli/

Enhanced search index initialization:

# Initialize search indices with custom field mapping updates
invenio index init

# The init command automatically runs registered hooks from:
# - oarepo.cli.search.init entry point
# - Updates dynamic mappings for all registered models

Extension point for custom initialization:

# In your package's entry points:
[project.entry-points."oarepo.cli.search.init"]
my_init = "my_app.init:update_custom_mappings"

9. Custom Fields and Relations

Source: oarepo_runtime/services/records/

Support for updating record mappings with custom fields:

from oarepo_runtime.services.records.custom_fields import update_all_records_mappings_relation_fields

# Update OpenSearch mappings for all records with relation fields
update_all_records_mappings_relation_fields()

10. Permission Generators

Source: oarepo_runtime/services/config/permissions.py

Pre-configured permission policy for open access repositories:

from oarepo_runtime.services.config.permissions import EveryonePermissionPolicy


class MyServiceConfig(RecordServiceConfig):
    permission_policy_cls = EveryonePermissionPolicy
    # Grants all permissions to any authenticated or anonymous user

Development

Setup

# Clone repository
git clone https://github.com/oarepo/oarepo-runtime.git
cd oarepo-runtime

./run.sh venv

Running Tests

./run.sh test

Entry Points

The package registers several Invenio entry points:

[project.entry-points."invenio_base.api_apps"]
oarepo_runtime = "oarepo_runtime.ext:OARepoRuntime"

[project.entry-points."invenio_base.apps"]
oarepo_runtime = "oarepo_runtime.ext:OARepoRuntime"

[project.entry-points."flask.commands"]
oarepo = "oarepo_runtime.cli:oarepo"

[project.entry-points."oarepo.cli.search.init"]
runtime_update_mappings = "oarepo_runtime.services.records.mapping:update_all_records_mappings"

[project.entry-points."invenio_base.blueprints"]
oarepo_runtime_info = "oarepo_runtime.info.views:create_wellknown_blueprint"

License

Copyright (c) 2020-2025 CESNET z.s.p.o.

OARepo Runtime is free software; you can redistribute it and/or modify it under the terms of the MIT License. See LICENSE file for more details.

Links

Acknowledgments

This project builds upon Invenio Framework and is developed as part of the OARepo ecosystem.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oarepo_runtime-7.4.0.tar.gz (50.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

oarepo_runtime-7.4.0-py3-none-any.whl (75.6 kB view details)

Uploaded Python 3

File details

Details for the file oarepo_runtime-7.4.0.tar.gz.

File metadata

  • Download URL: oarepo_runtime-7.4.0.tar.gz
  • Upload date:
  • Size: 50.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for oarepo_runtime-7.4.0.tar.gz
Algorithm Hash digest
SHA256 9171b03d0343e18e881d5f6274dfb23fa3ed55fdf17503bbfb5dd8a992244d75
MD5 7ca6540a54cf507f2af5705e100bbdef
BLAKE2b-256 5c24e66f2be407c9f8a26dc2761dadd451ac5c1f7495c4208ac74ea686edfd72

See more details on using hashes here.

File details

Details for the file oarepo_runtime-7.4.0-py3-none-any.whl.

File metadata

  • Download URL: oarepo_runtime-7.4.0-py3-none-any.whl
  • Upload date:
  • Size: 75.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for oarepo_runtime-7.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4e368060ec7b2ef7f88e671ee6d59dd84d021d8a0bd6303b321bd44d8abed064
MD5 54d66c230470bd0f29a08ea8f55b8fb8
BLAKE2b-256 873a8647cfafa5b9436d11da557c8521b732d08b4e2c1b40df2f725c564e9718

See more details on using hashes here.

Release history Release notifications | RSS feed

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page