oarepo-runtime 1.5.6__tar.gz → 1.5.7__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. {oarepo-runtime-1.5.6/oarepo_runtime.egg-info → oarepo-runtime-1.5.7}/PKG-INFO +1 -1
  2. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/fixtures.py +6 -3
  3. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/fixtures.py +15 -6
  4. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/ext.py +3 -5
  5. oarepo-runtime-1.5.7/oarepo_runtime/info/views.py +302 -0
  6. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/systemfields/mapping.py +4 -0
  7. oarepo-runtime-1.5.7/oarepo_runtime/records/systemfields/synthetic.py +79 -0
  8. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/custom_fields/mappings.py +9 -3
  9. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/results.py +5 -1
  10. oarepo-runtime-1.5.7/oarepo_runtime/utils/functools.py +8 -0
  11. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7/oarepo_runtime.egg-info}/PKG-INFO +1 -1
  12. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime.egg-info/SOURCES.txt +4 -0
  13. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime.egg-info/entry_points.txt +3 -0
  14. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/setup.cfg +3 -1
  15. oarepo-runtime-1.5.7/tests/pkg_data/__init__.py +0 -0
  16. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/LICENSE +0 -0
  17. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/MANIFEST.in +0 -0
  18. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/README.md +0 -0
  19. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/__init__.py +0 -0
  20. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/__init__.py +0 -0
  21. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/assets.py +0 -0
  22. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/base.py +0 -0
  23. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/cf.py +0 -0
  24. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/check.py +0 -0
  25. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/configuration.py +0 -0
  26. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/index.py +0 -0
  27. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/cli/validate.py +0 -0
  28. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/__init__.py +0 -0
  29. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/asynchronous.py +0 -0
  30. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/catalogue.py +0 -0
  31. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/datastreams.py +0 -0
  32. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/errors.py +0 -0
  33. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/ext.py +0 -0
  34. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/json.py +0 -0
  35. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/readers/__init__.py +0 -0
  36. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/readers/attachments.py +0 -0
  37. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/readers/excel.py +0 -0
  38. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/readers/json.py +0 -0
  39. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/readers/service.py +0 -0
  40. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/readers/yaml.py +0 -0
  41. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/semi_asynchronous.py +0 -0
  42. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/synchronous.py +0 -0
  43. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/transformers.py +0 -0
  44. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/types.py +0 -0
  45. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/utils.py +0 -0
  46. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/writers/__init__.py +0 -0
  47. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/writers/attachments_file.py +0 -0
  48. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/writers/attachments_service.py +0 -0
  49. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/writers/service.py +0 -0
  50. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/writers/utils.py +0 -0
  51. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/writers/validation_errors.py +0 -0
  52. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/datastreams/writers/yaml.py +0 -0
  53. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/ext_config.py +0 -0
  54. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/i18n/__init__.py +0 -0
  55. {oarepo-runtime-1.5.6/oarepo_runtime/services → oarepo-runtime-1.5.7/oarepo_runtime/info}/__init__.py +0 -0
  56. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/profile.py +0 -0
  57. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/proxies.py +0 -0
  58. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/__init__.py +0 -0
  59. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/dumpers/__init__.py +0 -0
  60. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/dumpers/edtf_interval.py +0 -0
  61. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/dumpers/multilingual_dumper.py +0 -0
  62. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/entity_resolvers/__init__.py +0 -0
  63. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/entity_resolvers/proxies.py +0 -0
  64. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/relations/__init__.py +0 -0
  65. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/relations/base.py +0 -0
  66. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/relations/internal.py +0 -0
  67. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/relations/lookup.py +0 -0
  68. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/relations/pid_relation.py +0 -0
  69. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/systemfields/__init__.py +0 -0
  70. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/systemfields/featured_file.py +0 -0
  71. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/systemfields/has_draftcheck.py +0 -0
  72. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/systemfields/icu.py +0 -0
  73. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/records/systemfields/record_status.py +0 -0
  74. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/resources/__init__.py +0 -0
  75. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/resources/file_resource.py +0 -0
  76. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/resources/localized_ui_json_serializer.py +0 -0
  77. {oarepo-runtime-1.5.6/oarepo_runtime/services/config → oarepo-runtime-1.5.7/oarepo_runtime/services}/__init__.py +0 -0
  78. {oarepo-runtime-1.5.6/oarepo_runtime/services/expansions → oarepo-runtime-1.5.7/oarepo_runtime/services/config}/__init__.py +0 -0
  79. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/config/permissions_presets.py +0 -0
  80. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/config/service.py +0 -0
  81. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/custom_fields/__init__.py +0 -0
  82. {oarepo-runtime-1.5.6/oarepo_runtime/services/facets → oarepo-runtime-1.5.7/oarepo_runtime/services/expansions}/__init__.py +0 -0
  83. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/expansions/expandable_fields.py +0 -0
  84. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/expansions/service.py +0 -0
  85. {oarepo-runtime-1.5.6/oarepo_runtime/services/relations → oarepo-runtime-1.5.7/oarepo_runtime/services/facets}/__init__.py +0 -0
  86. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/facets/base.py +0 -0
  87. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/facets/date.py +0 -0
  88. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/facets/enum.py +0 -0
  89. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/facets/facet_groups_names.py +0 -0
  90. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/facets/max_facet.py +0 -0
  91. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/facets/nested_facet.py +0 -0
  92. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/facets/params.py +0 -0
  93. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/files/__init__.py +0 -0
  94. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/files/service.py +0 -0
  95. {oarepo-runtime-1.5.6/oarepo_runtime/utils → oarepo-runtime-1.5.7/oarepo_runtime/services/relations}/__init__.py +0 -0
  96. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/relations/components.py +0 -0
  97. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/relations/errors.py +0 -0
  98. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/relations/mapping.py +0 -0
  99. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/__init__.py +0 -0
  100. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/cf.py +0 -0
  101. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/i18n.py +0 -0
  102. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/i18n_ui.py +0 -0
  103. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/i18n_validation.py +0 -0
  104. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/marshmallow.py +0 -0
  105. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/polymorphic.py +0 -0
  106. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/ui.py +0 -0
  107. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/schema/validation.py +0 -0
  108. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/services/search.py +0 -0
  109. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/translations/cs/LC_MESSAGES/messages.mo +0 -0
  110. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/translations/cs/LC_MESSAGES/messages.po +0 -0
  111. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/translations/default_translations.py +0 -0
  112. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/translations/en/LC_MESSAGES/messages.mo +0 -0
  113. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/translations/en/LC_MESSAGES/messages.po +0 -0
  114. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/translations/jinjax_messages.jinja +0 -0
  115. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/translations/messages.pot +0 -0
  116. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/uow.py +0 -0
  117. {oarepo-runtime-1.5.6/tests/pkg_data → oarepo-runtime-1.5.7/oarepo_runtime/utils}/__init__.py +0 -0
  118. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime/utils/path.py +0 -0
  119. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime.egg-info/dependency_links.txt +0 -0
  120. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime.egg-info/requires.txt +0 -0
  121. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/oarepo_runtime.egg-info/top_level.txt +0 -0
  122. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/pyproject.toml +0 -0
  123. {oarepo-runtime-1.5.6 → oarepo-runtime-1.5.7}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oarepo-runtime
3
- Version: 1.5.6
3
+ Version: 1.5.7
4
4
  Summary: A set of runtime extensions of Invenio repository
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -48,6 +48,9 @@ def load(
48
48
  else:
49
49
  callback = fixtures_asynchronous_callback.s()
50
50
 
51
+ if fixture_dir:
52
+ system_fixtures = False
53
+
51
54
  with current_app.wsgi_app.mounts["/api"].app_context():
52
55
  load_fixtures(
53
56
  fixture_dir,
@@ -56,9 +59,9 @@ def load(
56
59
  system_fixtures=system_fixtures,
57
60
  callback=callback,
58
61
  batch_size=bulk_size,
59
- datastreams_impl=AsynchronousDataStream
60
- if on_background
61
- else SynchronousDataStream,
62
+ datastreams_impl=(
63
+ AsynchronousDataStream if on_background else SynchronousDataStream
64
+ ),
62
65
  )
63
66
  if not on_background:
64
67
  _show_stats(callback, "Load fixtures")
@@ -57,12 +57,20 @@ def load_fixtures(
57
57
  )
58
58
 
59
59
  if system_fixtures:
60
- for r in reversed(
61
- sorted(
62
- pkg_resources.iter_entry_points("oarepo.fixtures"), key=lambda r: r.name
63
- )
64
- ):
65
- pkg = r.load()
60
+
61
+ def get_priority(name):
62
+ match = re.match(r"(\d+)-", name)
63
+ if match:
64
+ return -int(match.group(1))
65
+ return 0
66
+
67
+ entry_points = list(
68
+ (get_priority(r.name), r.name, r)
69
+ for r in pkg_resources.iter_entry_points("oarepo.fixtures")
70
+ )
71
+ entry_points.sort(key=lambda x: x[:2])
72
+ for r in entry_points:
73
+ pkg = r[2].load()
66
74
  pkg_fixture_dir = Path(pkg.__file__)
67
75
  if pkg_fixture_dir.is_file():
68
76
  pkg_fixture_dir = pkg_fixture_dir.parent
@@ -90,6 +98,7 @@ def _load_fixtures_from_catalogue(
90
98
  continue
91
99
  if any(x.match(catalogue_datastream.stream_name) for x in exclude):
92
100
  continue
101
+
93
102
  fixtures.add(catalogue_datastream.stream_name)
94
103
 
95
104
  datastream = datastreams_impl(
@@ -28,9 +28,9 @@ class OARepoRuntime(object):
28
28
 
29
29
  for k in ext_config.OAREPO_PERMISSIONS_PRESETS:
30
30
  if k not in app.config["OAREPO_PERMISSIONS_PRESETS"]:
31
- app.config["OAREPO_PERMISSIONS_PRESETS"][
32
- k
33
- ] = ext_config.OAREPO_PERMISSIONS_PRESETS[k]
31
+ app.config["OAREPO_PERMISSIONS_PRESETS"][k] = (
32
+ ext_config.OAREPO_PERMISSIONS_PRESETS[k]
33
+ )
34
34
 
35
35
  for k in dir(ext_config):
36
36
  if k == "DEFAULT_DATASTREAMS_EXCLUDES":
@@ -53,5 +53,3 @@ class OARepoRuntime(object):
53
53
  for val_k, val_value in source.items():
54
54
  if val_k not in target:
55
55
  target[val_k] = val_value
56
-
57
-
@@ -0,0 +1,302 @@
1
+ import json
2
+ import logging
3
+ import re
4
+ from functools import cached_property
5
+ from urllib.parse import urljoin
6
+
7
+ import importlib_metadata
8
+ import importlib_resources
9
+ import marshmallow as ma
10
+ from flask import current_app, request, url_for
11
+ from flask_resources import (
12
+ Resource,
13
+ ResourceConfig,
14
+ from_conf,
15
+ request_parser,
16
+ resource_requestctx,
17
+ response_handler,
18
+ route,
19
+ )
20
+ from flask_restful import abort
21
+ from invenio_base.utils import obj_or_import_string
22
+ from invenio_jsonschemas import current_jsonschemas
23
+ from invenio_records_resources.proxies import current_service_registry
24
+
25
+ logger = logging.getLogger("oarepo_runtime.info")
26
+
27
+
28
+ class InfoConfig(ResourceConfig):
29
+ blueprint_name = "oarepo_runtime_info"
30
+ url_prefix = "/.well-known/repository"
31
+
32
+ schema_view_args = {"schema": ma.fields.Str()}
33
+ model_view_args = {"model": ma.fields.Str()}
34
+
35
+ def __init__(self, app):
36
+ self.app = app
37
+
38
+ @cached_property
39
+ def components(self):
40
+ return tuple(
41
+ obj_or_import_string(x)
42
+ for x in self.app.config.get("INFO_ENDPOINT_COMPONENTS", [])
43
+ )
44
+
45
+
46
+ schema_view_args = request_parser(from_conf("schema_view_args"), location="view_args")
47
+ model_view_args = request_parser(from_conf("model_view_args"), location="view_args")
48
+
49
+
50
+ class InfoResource(Resource):
51
+ def create_url_rules(self):
52
+ return [
53
+ route("GET", "/", self.repository),
54
+ route("GET", "/models", self.models),
55
+ route("GET", "/schema/<path:schema>", self.schema),
56
+ route("GET", "/models/<model>", self.model),
57
+ ]
58
+
59
+ @cached_property
60
+ def components(self):
61
+ return [x(self) for x in self.config.components]
62
+
63
+ @response_handler()
64
+ def repository(self):
65
+ """Repository endpoint."""
66
+ ret = {
67
+ "name": current_app.config.get("THEME_SITENAME", ""),
68
+ "description": current_app.config.get("REPOSITORY_DESCRIPTION", ""),
69
+ "version": get_package_version("repo"),
70
+ "invenio_version": get_package_version("oarepo"),
71
+ "transfers": [
72
+ "local-file",
73
+ "url-fetch",
74
+ # TODO: where to get these? (permissions?)
75
+ # "direct-s3",
76
+ ],
77
+ "links": {
78
+ "self": url_for(request.endpoint, _external=True),
79
+ "models": url_for("oarepo_runtime_info.models", _external=True),
80
+ },
81
+ }
82
+ self.call_components("repository", data=ret)
83
+ return ret, 200
84
+
85
+ @response_handler(many=True)
86
+ def models(self):
87
+ data = []
88
+ # iterate entrypoint oarepo.models
89
+ for model in importlib_metadata.entry_points().select(group="oarepo.models"):
90
+ package_name, file_name = model.value.split(":")
91
+ model_data = json.loads(
92
+ importlib_resources.files(package_name).joinpath(file_name).read_text()
93
+ )
94
+ model_data = model_data["model"]
95
+ if model_data["type"] != "model":
96
+ continue
97
+
98
+ service = self._get_service(model_data)
99
+ if not service:
100
+ continue
101
+
102
+ model_features = self._get_model_features(model_data)
103
+
104
+ links = {
105
+ "api": self._get_model_api_endpoint(model_data),
106
+ "html": self._get_model_html_endpoint(model_data),
107
+ "schema": self._get_model_schema_endpoint(model_data),
108
+ "model": self._get_model_model_endpoint(model.name),
109
+ # "openapi": url_for(self._get_model_openapi_endpoint(model_data), _external=True)
110
+ }
111
+
112
+ links["published"] = links["api"]
113
+ if "drafts" in model_features:
114
+ links["drafts"] = self._get_model_draft_endpoint(model_data)
115
+
116
+ data.append(
117
+ {
118
+ "name": model_data.get(
119
+ "model-name", model_data.get("module", {}).get("base", "")
120
+ ).lower(),
121
+ "description": model_data.get("model-description", ""),
122
+ "version": model_data["json-schema-settings"]["version"],
123
+ "features": model_features,
124
+ "links": links,
125
+ # TODO: we also need to get previous schema versions here if we support
126
+ # multiple version of the same schema at the same time
127
+ "schemas": self._get_model_schemas(service),
128
+ }
129
+ )
130
+ self.call_components("repository", data=data)
131
+ return data, 200
132
+
133
+ @schema_view_args
134
+ @response_handler()
135
+ def schema(self):
136
+ schema = resource_requestctx.view_args["schema"]
137
+ return current_jsonschemas.get_schema(schema, resolved=True), 200
138
+
139
+ @model_view_args
140
+ @response_handler()
141
+ def model(self):
142
+ model = resource_requestctx.view_args["model"]
143
+ for _model in importlib_metadata.entry_points().select(
144
+ group="oarepo.models", name=model
145
+ ):
146
+ package_name, file_name = _model.value.split(":")
147
+ model_data = json.loads(
148
+ importlib_resources.files(package_name).joinpath(file_name).read_text()
149
+ )
150
+ return self._remove_implementation_details_from_model(model_data), 200
151
+ abort(404)
152
+
153
+ IMPLEMENTATION_DETAILS = re.compile(
154
+ r"""
155
+ ^(
156
+ class |
157
+ .*-class |
158
+ base-classes |
159
+ .*-base-classes |
160
+ module |
161
+ generate |
162
+ imports |
163
+ extra-code |
164
+ components |
165
+ .*-args
166
+ )$
167
+ """,
168
+ re.VERBOSE,
169
+ )
170
+
171
+ def _remove_implementation_details_from_model(self, model):
172
+ if isinstance(model, dict):
173
+ return self._remove_implementation_details_from_model_dict(model)
174
+ elif isinstance(model, list):
175
+ return self._remove_implementation_details_from_model_list(model)
176
+ else:
177
+ return model
178
+
179
+ def _remove_implementation_details_from_model_dict(self, model):
180
+ ret = {}
181
+ for k, v in model.items():
182
+ if not self.IMPLEMENTATION_DETAILS.match(k):
183
+ new_value = self._remove_implementation_details_from_model(v)
184
+ if new_value is not None and new_value != {} and new_value != []:
185
+ ret[k] = new_value
186
+ return ret
187
+
188
+ def _remove_implementation_details_from_model_list(self, model):
189
+ ret = []
190
+ for v in model:
191
+ new_value = self._remove_implementation_details_from_model(v)
192
+ if new_value is not None and new_value != {} and new_value != []:
193
+ ret.append(new_value)
194
+ return ret
195
+
196
+ def call_components(self, method_name, **kwargs):
197
+ for component in self.config.components:
198
+ if hasattr(component, method_name):
199
+ getattr(component, method_name)(**kwargs)
200
+
201
+ def _get_model_features(self, model):
202
+ features = []
203
+ if model.get("requests", {}):
204
+ features.append("requests")
205
+ if model.get("draft", {}):
206
+ features.append("drafts")
207
+ if model.get("files", {}):
208
+ features.append("files")
209
+ return features
210
+
211
+ def _get_model_api_endpoint(self, model):
212
+ try:
213
+ alias = model["api-blueprint"]["alias"]
214
+ return api_url_for(f"{alias}.search", _external=True)
215
+ except: # NOSONAR noqa
216
+ logger.exception("Failed to get model api endpoint")
217
+ return None
218
+
219
+ def _get_model_draft_endpoint(self, model):
220
+ try:
221
+ alias = model["api-blueprint"]["alias"]
222
+ return api_url_for(f"{alias}.search_user_records", _external=True)
223
+ except: # NOSONAR noqa
224
+ logger.exception("Failed to get model draft endpoint")
225
+ return None
226
+
227
+ def _get_model_html_endpoint(self, model):
228
+ try:
229
+ return urljoin(
230
+ self._get_model_api_endpoint(model),
231
+ model["resource-config"]["base-html-url"],
232
+ )
233
+ except: # NOSONAR noqa
234
+ logger.exception("Failed to get model html endpoint")
235
+ return None
236
+
237
+ def _get_model_schema_endpoint(self, model):
238
+ try:
239
+ return url_for(
240
+ "oarepo_runtime_info.schema",
241
+ schema=model["json-schema-settings"]["name"],
242
+ _external=True,
243
+ )
244
+ except: # NOSONAR noqa
245
+ logger.exception("Failed to get model schema endpoint")
246
+ return None
247
+
248
+ def _get_model_model_endpoint(self, model):
249
+ try:
250
+ return url_for("oarepo_runtime_info.model", model=model, _external=True)
251
+ except: # NOSONAR noqa
252
+ logger.exception("Failed to get model model endpoint")
253
+ return None
254
+
255
+ def _get_model_schemas(self, service):
256
+ try:
257
+ record_cls = service.config.record_cls
258
+ schema = getattr(record_cls, "schema", None)
259
+ if schema is not None:
260
+ return [schema.value]
261
+ except: # NOSONAR noqa
262
+ logger.exception("Failed to get model schemas")
263
+ return []
264
+
265
+ def _get_service(self, model_data):
266
+ service_id = model_data["service-config"]["service-id"]
267
+ try:
268
+ service = current_service_registry.get(service_id)
269
+ except KeyError:
270
+ return None
271
+ return service
272
+
273
+
274
+ def create_wellknown_blueprint(app):
275
+ """Create blueprint."""
276
+ config_class = obj_or_import_string(
277
+ app.config.get("INFO_ENDPOINT_CONFIG", InfoConfig)
278
+ )
279
+ return InfoResource(config=config_class(app)).as_blueprint()
280
+
281
+
282
+ def get_package_version(package_name):
283
+ """Get package version."""
284
+ from pkg_resources import get_distribution
285
+
286
+ try:
287
+ return re.sub(r"\+.*", "", get_distribution(package_name).version)
288
+ except Exception: # NOSONAR noqa
289
+ logger.exception(f"Failed to get package version for {package_name}")
290
+ return None
291
+
292
+
293
+ def api_url_for(endpoint, _external=True, **values):
294
+ """API url_for."""
295
+ site_api_url = current_app.config["SITE_API_URL"]
296
+ site_url = current_app.config["SITE_UI_URL"]
297
+ base_url = url_for(endpoint, **values, _external=_external)
298
+ if base_url.startswith(site_api_url):
299
+ return base_url
300
+ if base_url.startswith(site_url):
301
+ return base_url.replace(site_url, site_api_url)
302
+ raise ValueError(f"URL {base_url} does not start with {site_url} or {site_api_url}")
@@ -12,6 +12,10 @@ class MappingSystemFieldMixin:
12
12
  def mapping_settings(self):
13
13
  return {}
14
14
 
15
+ @property
16
+ def dynamic_templates(self):
17
+ return []
18
+
15
19
 
16
20
  class SystemFieldDumperExt(SearchDumperExt):
17
21
  def dump(self, record, data):
@@ -0,0 +1,79 @@
1
+ from invenio_records.systemfields import SystemField
2
+
3
+ from .mapping import MappingSystemFieldMixin
4
+
5
+
6
+ class SyntheticSystemField(MappingSystemFieldMixin, SystemField):
7
+ """
8
+ A class that provides a synthetic system field, that is a system field that
9
+ generates its content from what is already present inside the record.
10
+
11
+ The field is not stored in the record, but is generated on the fly when
12
+ the record is being indexed.
13
+
14
+ Usage:
15
+
16
+ 1. Create a new class that inherits from SyntheticSystemField
17
+ 2. Implement the _value method that returns the value of the field from a data (
18
+ either a dictionary or an instance of the record class)
19
+ 3. Put the class onto the record. If you use oarepo-model-builder, add it to the model
20
+ like:
21
+ ```yaml
22
+ record:
23
+ record:
24
+ extra-code: |-2
25
+ # extra custom fields for facets
26
+ faculty = {{common.theses.synthetic_fields.FacultySystemField}}()
27
+ department = {{common.theses.synthetic_fields.DepartmentSystemField}}()
28
+ defenseYear = {{common.theses.synthetic_fields.DefenseYearSystemField}}()
29
+ ```
30
+
31
+ 4. Add the extra fields to the mapping and facets. If using oarepo-model-builder, add it to the
32
+ model like the following piece of code and compile the model:
33
+ ```yaml
34
+ record:
35
+ properties:
36
+ faculty:
37
+ type: vocabulary
38
+ vocabulary-type: institutions
39
+ facets:
40
+ facet-groups:
41
+ - default
42
+ label.cs: Fakulta
43
+ label.en: Faculty
44
+
45
+
46
+ department:
47
+ type: vocabulary
48
+ vocabulary-type: institutions
49
+ facets:
50
+ facet-groups:
51
+ - default
52
+ label.cs: Ústav
53
+ label.en: Department
54
+
55
+ defenseYear:
56
+ type: integer
57
+ facets:
58
+ facet-groups:
59
+ - default
60
+ label.cs: Rok obhajoby
61
+ label.en: Defense year
62
+ ```
63
+ """
64
+
65
+ def search_dump(self, data):
66
+ dt = self._value(data)
67
+ if dt:
68
+ data[self.key] = dt
69
+
70
+ def search_load(self, data):
71
+ data.pop(self.key)
72
+
73
+ def __get__(self, record, owner=None):
74
+ if record is None:
75
+ return self
76
+ return self._value(record)
77
+
78
+ def _value(self, data):
79
+ raise NotImplementedError("You must implement the _value method")
@@ -80,6 +80,7 @@ def prepare_cf_index(config: RecordServiceConfig):
80
80
  # get mapping
81
81
  mapping = fld.mapping
82
82
  settings = fld.mapping_settings
83
+ dynamic_templates = fld.dynamic_templates
83
84
 
84
85
  # upload mapping
85
86
  try:
@@ -98,20 +99,25 @@ def prepare_cf_index(config: RecordServiceConfig):
98
99
  ),
99
100
  using=current_search_client,
100
101
  )
101
- update_index(draft_index, settings, mapping)
102
+ update_index(draft_index, settings, mapping, dynamic_templates)
102
103
 
103
104
  except search.RequestError as e:
104
105
  click.secho("An error occurred while creating custom fields.", fg="red")
105
106
  click.secho(e.info["error"]["reason"], fg="red")
106
107
 
107
108
 
108
- def update_index(record_index, settings, mapping):
109
+ def update_index(record_index, settings, mapping, dynamic_templates=None):
109
110
  if settings:
110
111
  record_index.close()
111
112
  record_index.put_settings(body=settings)
112
113
  record_index.open()
114
+ body = {}
113
115
  if mapping:
114
- record_index.put_mapping(body={"properties": mapping})
116
+ body["properties"] = mapping
117
+ if dynamic_templates:
118
+ body["dynamic_templates"] = dynamic_templates
119
+ if body:
120
+ record_index.put_mapping(body=body)
115
121
 
116
122
 
117
123
  def get_mapping_fields(record_class) -> Iterable[MappingSystemFieldMixin]:
@@ -1,4 +1,3 @@
1
- import inspect
2
1
 
3
2
  from invenio_records_resources.services.records.results import (
4
3
  RecordItem as BaseRecordItem,
@@ -7,9 +6,12 @@ from invenio_records_resources.services.records.results import (
7
6
  RecordList as BaseRecordList,
8
7
  )
9
8
 
9
+
10
10
  class RecordItem(BaseRecordItem):
11
11
  """Single record result."""
12
+
12
13
  components = []
14
+
13
15
  @property
14
16
  def data(self):
15
17
  if self._data:
@@ -19,8 +21,10 @@ class RecordItem(BaseRecordItem):
19
21
  c.update_data(self._identity, self._record, _data)
20
22
  return _data
21
23
 
24
+
22
25
  class RecordList(BaseRecordList):
23
26
  components = []
27
+
24
28
  @property
25
29
  def hits(self):
26
30
  """Iterator over the hits."""
@@ -0,0 +1,8 @@
1
+ def try_sequence(*funcs, ignored_exceptions=(), raised_exception=Exception):
2
+ raised_exceptions = []
3
+ for func in funcs:
4
+ try:
5
+ return func()
6
+ except ignored_exceptions as e:
7
+ raised_exceptions.append(e)
8
+ raise raised_exception(raised_exceptions) from raised_exceptions[-1]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oarepo-runtime
3
- Version: 1.5.6
3
+ Version: 1.5.7
4
4
  Summary: A set of runtime extensions of Invenio repository
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -52,6 +52,8 @@ oarepo_runtime/datastreams/writers/utils.py
52
52
  oarepo_runtime/datastreams/writers/validation_errors.py
53
53
  oarepo_runtime/datastreams/writers/yaml.py
54
54
  oarepo_runtime/i18n/__init__.py
55
+ oarepo_runtime/info/__init__.py
56
+ oarepo_runtime/info/views.py
55
57
  oarepo_runtime/records/__init__.py
56
58
  oarepo_runtime/records/dumpers/__init__.py
57
59
  oarepo_runtime/records/dumpers/edtf_interval.py
@@ -69,6 +71,7 @@ oarepo_runtime/records/systemfields/has_draftcheck.py
69
71
  oarepo_runtime/records/systemfields/icu.py
70
72
  oarepo_runtime/records/systemfields/mapping.py
71
73
  oarepo_runtime/records/systemfields/record_status.py
74
+ oarepo_runtime/records/systemfields/synthetic.py
72
75
  oarepo_runtime/resources/__init__.py
73
76
  oarepo_runtime/resources/file_resource.py
74
77
  oarepo_runtime/resources/localized_ui_json_serializer.py
@@ -114,5 +117,6 @@ oarepo_runtime/translations/cs/LC_MESSAGES/messages.po
114
117
  oarepo_runtime/translations/en/LC_MESSAGES/messages.mo
115
118
  oarepo_runtime/translations/en/LC_MESSAGES/messages.po
116
119
  oarepo_runtime/utils/__init__.py
120
+ oarepo_runtime/utils/functools.py
117
121
  oarepo_runtime/utils/path.py
118
122
  tests/pkg_data/__init__.py
@@ -4,5 +4,8 @@ oarepo_runtime = oarepo_runtime.ext:OARepoRuntime
4
4
  [invenio_base.apps]
5
5
  oarepo_runtime = oarepo_runtime.ext:OARepoRuntime
6
6
 
7
+ [invenio_base.blueprints]
8
+ oarepo_runtime_info = oarepo_runtime.info.views:create_wellknown_blueprint
9
+
7
10
  [invenio_celery.tasks]
8
11
  oarepo_runtime_datastreams = oarepo_runtime.datastreams
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = oarepo-runtime
3
- version = 1.5.6
3
+ version = 1.5.7
4
4
  description = A set of runtime extensions of Invenio repository
5
5
  authors = Alzbeta Pokorna
6
6
  readme = README.md
@@ -50,6 +50,8 @@ invenio_base.api_apps =
50
50
  oarepo_runtime = oarepo_runtime.ext:OARepoRuntime
51
51
  invenio_celery.tasks =
52
52
  oarepo_runtime_datastreams = oarepo_runtime.datastreams
53
+ invenio_base.blueprints =
54
+ oarepo_runtime_info = oarepo_runtime.info.views:create_wellknown_blueprint
53
55
 
54
56
  [oarepo.i18n]
55
57
  languages =
File without changes
File without changes
File without changes
File without changes