oarepo-runtime 2.0.0.dev18__py3-none-any.whl → 2.0.0.dev19__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,6 @@ from .api import Model
19
19
  from .ext import OARepoRuntime
20
20
  from .proxies import current_runtime
21
21
 
22
- __version__ = "2.0.0dev18"
22
+ __version__ = "2.0.0dev19"
23
23
 
24
24
  __all__ = ("Model", "OARepoRuntime", "__version__", "current_runtime")
@@ -0,0 +1,63 @@
1
+ #
2
+ # Copyright (c) 2025 CESNET z.s.p.o.
3
+ #
4
+ # This file is a part of oarepo-runtime (see http://github.com/oarepo/oarepo-runtime).
5
+ #
6
+ # oarepo-runtime is free software; you can redistribute it and/or modify it
7
+ # under the terms of the MIT License; see LICENSE file for more details.
8
+ #
9
+ """Module to update the mapping of system fields in a record class."""
10
+
11
+ from __future__ import annotations
12
+
13
+ import inspect
14
+ from typing import TYPE_CHECKING
15
+
16
+ from flask import current_app
17
+ from invenio_records.systemfields.relations import MultiRelationsField
18
+ from invenio_vocabularies.records.systemfields.relations import CustomFieldsRelation
19
+
20
+ from oarepo_runtime.records.mapping import prefixed_index, update_record_index
21
+
22
+ if TYPE_CHECKING:
23
+ from collections.abc import Iterable
24
+
25
+ from invenio_records.api import RecordBase
26
+
27
+
28
+ def update_record_system_fields_mapping_relation_field(
29
+ record_class: type[RecordBase],
30
+ ) -> None:
31
+ """Update mapping for system fields in the record class.
32
+
33
+ :param record_class: The record class which index mapping should be updated.
34
+ :raise search.RequestError: If there is an error while updating the mapping.
35
+ """
36
+ index = getattr(record_class, "index", None)
37
+ if not index:
38
+ return
39
+
40
+ for field_name, fld in get_mapping_relation_fields(record_class):
41
+ custom_fields = current_app.config.get(fld._fields_var, []) # noqa: SLF001
42
+
43
+ props: dict[str, dict] = {}
44
+ mapping = {field_name: {"type": "object", "properties": props}}
45
+ for cf in custom_fields:
46
+ # get mapping
47
+ props[cf.name] = cf.mapping
48
+
49
+ # upload mapping
50
+ if props:
51
+ update_record_index(prefixed_index(index), {}, mapping, None)
52
+
53
+
54
+ def get_mapping_relation_fields(
55
+ record_class: type[RecordBase],
56
+ ) -> Iterable[tuple[str, CustomFieldsRelation]]:
57
+ """Get all mapping fields from the record class."""
58
+ for _, relation_fields in inspect.getmembers(record_class, lambda x: isinstance(x, MultiRelationsField)):
59
+ yield from (
60
+ (field_name, relation_field)
61
+ for field_name, relation_field in relation_fields._original_fields.items() # noqa: SLF001
62
+ if isinstance(relation_field, CustomFieldsRelation)
63
+ )
@@ -0,0 +1,51 @@
1
+ #
2
+ # Copyright (c) 2025 CESNET z.s.p.o.
3
+ #
4
+ # This file is a part of oarepo-runtime (see http://github.com/oarepo/oarepo-runtime).
5
+ #
6
+ # oarepo-runtime is free software; you can redistribute it and/or modify it
7
+ # under the terms of the MIT License; see LICENSE file for more details.
8
+ #
9
+ """Selectors for extracting values from records based on specified paths."""
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Any, Protocol
14
+
15
+
16
+ class Selector(Protocol):
17
+ """Protocol for selectors that extract values from records."""
18
+
19
+ def select(self, record: dict) -> list[Any]: # noqa: ARG002
20
+ """Select values from the record based on the selector's logic."""
21
+ return []
22
+
23
+
24
+ class PathSelector(Selector):
25
+ """Selector that extracts values from records based on specified paths."""
26
+
27
+ def __init__(self, *paths: str) -> None:
28
+ """Initialize the PathSelector with given paths."""
29
+ self.paths = [x.split(".") for x in paths]
30
+
31
+ def select(self, record: dict) -> list[Any]:
32
+ """Select values from the record based on the specified paths."""
33
+ ret = []
34
+ for path in self.paths:
35
+ ret.extend(list(getter(record, path)))
36
+ return ret
37
+
38
+
39
+ def getter(data: list | dict, path: list) -> Any:
40
+ """Recursively get values from data based on the provided path."""
41
+ if len(path) == 0:
42
+ if isinstance(data, list):
43
+ yield from data
44
+ else:
45
+ yield data
46
+ elif isinstance(data, dict):
47
+ if path[0] in data:
48
+ yield from getter(data[path[0]], path[1:])
49
+ elif isinstance(data, list):
50
+ for item in data:
51
+ yield from getter(item, path)
@@ -0,0 +1,44 @@
1
+ #
2
+ # Copyright (c) 2025 CESNET z.s.p.o.
3
+ #
4
+ # This file is a part of oarepo-runtime (see http://github.com/oarepo/oarepo-runtime).
5
+ #
6
+ # oarepo-runtime is free software; you can redistribute it and/or modify it
7
+ # under the terms of the MIT License; see LICENSE file for more details.
8
+ #
9
+ """Services for updating custom fields mappings in opensearch."""
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import TYPE_CHECKING
14
+
15
+ from invenio_records_resources.services.records import (
16
+ RecordService,
17
+ RecordServiceConfig,
18
+ )
19
+
20
+ from oarepo_runtime import current_runtime
21
+ from oarepo_runtime.records.systemfields.custom_fields import (
22
+ update_record_system_fields_mapping_relation_field,
23
+ )
24
+
25
+ if TYPE_CHECKING:
26
+ from invenio_records_resources.services.base import Service
27
+
28
+
29
+ def update_all_records_mappings_relation_fields() -> None:
30
+ """Update all mappings for the registered record classes."""
31
+ service: Service
32
+ for service in current_runtime.services.values():
33
+ if not isinstance(service, RecordService):
34
+ continue
35
+
36
+ config: RecordServiceConfig = service.config
37
+
38
+ record_class = getattr(config, "record_cls", None)
39
+ if record_class:
40
+ update_record_system_fields_mapping_relation_field(record_class)
41
+
42
+ draft_class = getattr(config, "draft_cls", None)
43
+ if draft_class:
44
+ update_record_system_fields_mapping_relation_field(draft_class)
@@ -0,0 +1,60 @@
1
+ #
2
+ # Copyright (c) 2025 CESNET z.s.p.o.
3
+ #
4
+ # This file is a part of oarepo-runtime (see http://github.com/oarepo/oarepo-runtime).
5
+ #
6
+ # oarepo-runtime is free software; you can redistribute it and/or modify it
7
+ # under the terms of the MIT License; see LICENSE file for more details.
8
+ #
9
+
10
+ """Module for typing related functionality."""
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import TYPE_CHECKING, Any
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import Callable
18
+
19
+
20
+ def require_kwargs(*kwargs_names: str) -> Any:
21
+ """Wrap function to require specific kwargs in a function call.
22
+
23
+ This decorator is used to fix typing errors in inherited classes where the base class defines kwargs and the
24
+ inherited class needs to access a specific kwarg.
25
+
26
+ Example:
27
+ ```python
28
+ # base class
29
+ class ConditionalGenerator(
30
+ InvenioConditionalGenerator, ABC
31
+ ):
32
+ @abstractmethod
33
+ def _condition(
34
+ self, **kwargs: Any
35
+ ) -> bool: ...
36
+
37
+
38
+ # inherited class
39
+ class IfRecordHasField(
40
+ ConditionalGenerator
41
+ ):
42
+ @override
43
+ @require_kwargs("field")
44
+ def _condition(
45
+ self, *, field, **kwargs: Any
46
+ ) -> bool: ...
47
+ ```
48
+
49
+ """
50
+
51
+ def wrapper(f: Callable) -> Callable:
52
+ def wrapped_f(*args: Any, **kwargs: Any) -> Any:
53
+ for kwarg_name in kwargs_names:
54
+ if kwarg_name not in kwargs:
55
+ raise ValueError(f"Keyword argument {kwarg_name} not found in function call.")
56
+ return f(*args, **kwargs)
57
+
58
+ return wrapped_f
59
+
60
+ return wrapper
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oarepo-runtime
3
- Version: 2.0.0.dev18
3
+ Version: 2.0.0.dev19
4
4
  Summary: A set of runtime extensions of Invenio repository
5
5
  Project-URL: Homepage, https://github.com/oarepo/oarepo-runtime
6
6
  License-Expression: MIT
@@ -1,9 +1,10 @@
1
- oarepo_runtime/__init__.py,sha256=6z9_8CzYNGg5SzI-1U_6PbV9AZfjt6baMAwbuggSoQs,686
1
+ oarepo_runtime/__init__.py,sha256=ELfuJkeP59PnlRE7L7YZP4hwKX8EcHdzurXJYP3b2xs,686
2
2
  oarepo_runtime/api.py,sha256=7gPeRS66moT1lIedPRmuK0EnB8PpGO7iD5eRCQOty4U,12552
3
3
  oarepo_runtime/config.py,sha256=RUEPFn_5bKp9Wb0OY-Fb3VK30m35vF5IsLjYaQHhP3g,3838
4
4
  oarepo_runtime/ext.py,sha256=G9j5IgnVPdE656qaiN4RllpOkdyToP8v9uwas3DdpTY,8451
5
5
  oarepo_runtime/proxies.py,sha256=PXaRiBh5qs5-h8M81cJOgtqypFQcYUSjiSn2TLSujRw,648
6
6
  oarepo_runtime/py.typed,sha256=RznSCjXReEUI9zkmD25E8XniG_MvPpLBF6MyNZA8MmE,42
7
+ oarepo_runtime/typing.py,sha256=vH8UUb4QTJowuvibwHaOOEwxx8i21LcOeplxJl0Yrew,1594
7
8
  oarepo_runtime/cli/__init__.py,sha256=H7GOeOBf0udgKWOdlAQswIMvRrD8BwcEjOVxIqP0Suw,731
8
9
  oarepo_runtime/cli/search.py,sha256=4fHkrjltUUPVUzJiuWaiWxTk62rIYxal3_3jRsZVMmI,1175
9
10
  oarepo_runtime/records/__init__.py,sha256=AbWzmVCY7MhrpdEeI0e3lKzeugPMUSo8T08-NBVeig4,339
@@ -11,8 +12,10 @@ oarepo_runtime/records/drafts.py,sha256=CS-dUkrylNwscgBGfDyhwGBRCzwsyT6AA3Mhu40S
11
12
  oarepo_runtime/records/mapping.py,sha256=SJbSzerT1645a93-3-Fgz_i3anzFNlrZqbjjwW2ctKs,2660
12
13
  oarepo_runtime/records/pid_providers.py,sha256=DSpbVB2Z5GxnjhoY7_WJLfUfrr1UsArJye7CXPfEkNI,1773
13
14
  oarepo_runtime/records/systemfields/__init__.py,sha256=g-u408qyNnsbUTpDtVVwlcyiJaO68GTjDN0W9rXs9pk,524
15
+ oarepo_runtime/records/systemfields/custom_fields.py,sha256=PEoaCEnvanysFQAaqTtD9-VwaBmnFkoP2pmpCl9ZFfI,2237
14
16
  oarepo_runtime/records/systemfields/mapping.py,sha256=66OQavKewJEUMkghymOxvskIO0LUSP2E-MbHryeT5Nk,1968
15
17
  oarepo_runtime/records/systemfields/publication_status.py,sha256=1g3VXNPh0FsiPCpe-7ZuaMEF4x8ffrDrt37Rqnjp0ng,2027
18
+ oarepo_runtime/records/systemfields/selectors.py,sha256=ijVDwAXaXTV5NtcXsrALkhddgCogLNe2eEscFr23qyg,1656
16
19
  oarepo_runtime/resources/__init__.py,sha256=voynQULXoOEviADkbOpekMphZPTAz4IOTg5BF9xPwTM,453
17
20
  oarepo_runtime/resources/config.py,sha256=hJewyZ2FlEm4TtYnQS9JsnKnA6hhtSbvo1PC24-7f7Y,980
18
21
  oarepo_runtime/services/__init__.py,sha256=OGtBgEeaDTyk2RPDNXuKbU9_7egFBZr42SM0gN5FrF4,341
@@ -25,13 +28,14 @@ oarepo_runtime/services/config/permissions.py,sha256=9_706Yyz7X6IXhSaRBnkmGOr7c8
25
28
  oarepo_runtime/services/facets/__init__.py,sha256=k39ZYt1dMVOW01QRSTgx3CfuTYwvEWmL0VYTR3huVsE,349
26
29
  oarepo_runtime/services/facets/params.py,sha256=BxAmPmHlPs5ILQsKR98jZUFOWBSeiF454vOSIVIJj40,4697
27
30
  oarepo_runtime/services/records/__init__.py,sha256=Mpohx3xEXTmoodTEHbCih6I97JIofgqa_bf_Ysq4e2g,446
31
+ oarepo_runtime/services/records/custom_fields.py,sha256=Yp3WsLYq1_OPMmJvpxCDtZi9IhuxHsBFPor8q901qn0,1417
28
32
  oarepo_runtime/services/records/links.py,sha256=oTKE9HXByQWEy8J6vT4KGjneeM_16MStwlXXglnnQSo,1254
29
33
  oarepo_runtime/services/records/mapping.py,sha256=y3oeToKEnaRYpMV3q2-2cXNzyzyL3XXGvY26BifybpE,1332
30
34
  oarepo_runtime/services/schema/__init__.py,sha256=jgAPI_uKC6Ug4KQWnwQVg3-aNaw-eHja323AUFo5ELo,351
31
35
  oarepo_runtime/services/schema/i18n.py,sha256=9D1zOQaPKAnYzejB0vO-m2BJYnam0N0Lrq4jID7twfE,3174
32
36
  oarepo_runtime/services/schema/i18n_ui.py,sha256=DbusphhGDeaobTt4nuwNgKZ6Houlu4Sv3SuMGkdjRRY,3582
33
- oarepo_runtime-2.0.0.dev18.dist-info/METADATA,sha256=pC-YWi379OZ-3-kDzDg20ziCln3aaGO7ehf1auWoZNI,4495
34
- oarepo_runtime-2.0.0.dev18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
35
- oarepo_runtime-2.0.0.dev18.dist-info/entry_points.txt,sha256=rOfs8R1oXFN_dLH9zAZ6ydkvr83mDajegc6NBIRsCMQ,318
36
- oarepo_runtime-2.0.0.dev18.dist-info/licenses/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
37
- oarepo_runtime-2.0.0.dev18.dist-info/RECORD,,
37
+ oarepo_runtime-2.0.0.dev19.dist-info/METADATA,sha256=5XpM4niZTzcf6Hb-bFN_HeoDQPh7ci-u43PNYw9GleE,4495
38
+ oarepo_runtime-2.0.0.dev19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
39
+ oarepo_runtime-2.0.0.dev19.dist-info/entry_points.txt,sha256=rOfs8R1oXFN_dLH9zAZ6ydkvr83mDajegc6NBIRsCMQ,318
40
+ oarepo_runtime-2.0.0.dev19.dist-info/licenses/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
41
+ oarepo_runtime-2.0.0.dev19.dist-info/RECORD,,