oarepo-runtime 1.10.3__py3-none-any.whl → 2.0.0.dev3__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.
Files changed (171) hide show
  1. oarepo_runtime/__init__.py +24 -0
  2. oarepo_runtime/api.py +111 -0
  3. oarepo_runtime/cli/__init__.py +10 -21
  4. oarepo_runtime/cli/search.py +34 -0
  5. oarepo_runtime/config.py +86 -13
  6. oarepo_runtime/ext.py +64 -82
  7. oarepo_runtime/proxies.py +21 -5
  8. oarepo_runtime/records/__init__.py +11 -50
  9. oarepo_runtime/records/drafts.py +24 -18
  10. oarepo_runtime/records/mapping.py +84 -0
  11. oarepo_runtime/records/pid_providers.py +43 -7
  12. oarepo_runtime/records/systemfields/__init__.py +15 -33
  13. oarepo_runtime/records/systemfields/mapping.py +41 -24
  14. oarepo_runtime/records/systemfields/publication_status.py +59 -0
  15. oarepo_runtime/services/__init__.py +12 -0
  16. oarepo_runtime/services/config/__init__.py +15 -21
  17. oarepo_runtime/services/config/link_conditions.py +69 -75
  18. oarepo_runtime/services/config/permissions.py +62 -0
  19. oarepo_runtime/services/records/__init__.py +14 -1
  20. oarepo_runtime/services/records/links.py +21 -11
  21. oarepo_runtime/services/records/mapping.py +42 -0
  22. oarepo_runtime/services/results.py +98 -109
  23. oarepo_runtime/services/schema/__init__.py +12 -44
  24. oarepo_runtime/services/schema/i18n.py +47 -22
  25. oarepo_runtime/services/schema/i18n_ui.py +61 -24
  26. {oarepo_runtime-1.10.3.dist-info → oarepo_runtime-2.0.0.dev3.dist-info}/METADATA +9 -21
  27. oarepo_runtime-2.0.0.dev3.dist-info/RECORD +30 -0
  28. {oarepo_runtime-1.10.3.dist-info → oarepo_runtime-2.0.0.dev3.dist-info}/WHEEL +1 -2
  29. oarepo_runtime-2.0.0.dev3.dist-info/entry_points.txt +5 -0
  30. oarepo_runtime/cli/assets.py +0 -145
  31. oarepo_runtime/cli/base.py +0 -25
  32. oarepo_runtime/cli/cf.py +0 -15
  33. oarepo_runtime/cli/check.py +0 -167
  34. oarepo_runtime/cli/configuration.py +0 -51
  35. oarepo_runtime/cli/fixtures.py +0 -167
  36. oarepo_runtime/cli/index.py +0 -272
  37. oarepo_runtime/cli/permissions/__init__.py +0 -6
  38. oarepo_runtime/cli/permissions/base.py +0 -26
  39. oarepo_runtime/cli/permissions/evaluate.py +0 -63
  40. oarepo_runtime/cli/permissions/list.py +0 -239
  41. oarepo_runtime/cli/permissions/search.py +0 -121
  42. oarepo_runtime/cli/validate.py +0 -150
  43. oarepo_runtime/datastreams/__init__.py +0 -38
  44. oarepo_runtime/datastreams/asynchronous.py +0 -247
  45. oarepo_runtime/datastreams/catalogue.py +0 -150
  46. oarepo_runtime/datastreams/datastreams.py +0 -152
  47. oarepo_runtime/datastreams/errors.py +0 -54
  48. oarepo_runtime/datastreams/ext.py +0 -41
  49. oarepo_runtime/datastreams/fixtures.py +0 -265
  50. oarepo_runtime/datastreams/json.py +0 -4
  51. oarepo_runtime/datastreams/readers/__init__.py +0 -39
  52. oarepo_runtime/datastreams/readers/attachments.py +0 -51
  53. oarepo_runtime/datastreams/readers/excel.py +0 -123
  54. oarepo_runtime/datastreams/readers/json.py +0 -27
  55. oarepo_runtime/datastreams/readers/service.py +0 -54
  56. oarepo_runtime/datastreams/readers/yaml.py +0 -14
  57. oarepo_runtime/datastreams/semi_asynchronous.py +0 -91
  58. oarepo_runtime/datastreams/synchronous.py +0 -70
  59. oarepo_runtime/datastreams/transformers.py +0 -18
  60. oarepo_runtime/datastreams/types.py +0 -323
  61. oarepo_runtime/datastreams/utils.py +0 -131
  62. oarepo_runtime/datastreams/writers/__init__.py +0 -21
  63. oarepo_runtime/datastreams/writers/attachments_file.py +0 -92
  64. oarepo_runtime/datastreams/writers/attachments_service.py +0 -118
  65. oarepo_runtime/datastreams/writers/publish.py +0 -70
  66. oarepo_runtime/datastreams/writers/service.py +0 -175
  67. oarepo_runtime/datastreams/writers/utils.py +0 -30
  68. oarepo_runtime/datastreams/writers/validation_errors.py +0 -20
  69. oarepo_runtime/datastreams/writers/yaml.py +0 -56
  70. oarepo_runtime/ext_config.py +0 -67
  71. oarepo_runtime/i18n/__init__.py +0 -3
  72. oarepo_runtime/info/__init__.py +0 -0
  73. oarepo_runtime/info/check.py +0 -95
  74. oarepo_runtime/info/permissions/__init__.py +0 -0
  75. oarepo_runtime/info/permissions/debug.py +0 -191
  76. oarepo_runtime/info/views.py +0 -586
  77. oarepo_runtime/profile.py +0 -60
  78. oarepo_runtime/records/dumpers/__init__.py +0 -8
  79. oarepo_runtime/records/dumpers/edtf_interval.py +0 -38
  80. oarepo_runtime/records/dumpers/multilingual_dumper.py +0 -34
  81. oarepo_runtime/records/entity_resolvers/__init__.py +0 -13
  82. oarepo_runtime/records/entity_resolvers/proxies.py +0 -57
  83. oarepo_runtime/records/mappings/__init__.py +0 -0
  84. oarepo_runtime/records/mappings/rdm_parent_mapping.json +0 -483
  85. oarepo_runtime/records/owners/__init__.py +0 -3
  86. oarepo_runtime/records/owners/registry.py +0 -22
  87. oarepo_runtime/records/relations/__init__.py +0 -22
  88. oarepo_runtime/records/relations/base.py +0 -296
  89. oarepo_runtime/records/relations/internal.py +0 -46
  90. oarepo_runtime/records/relations/lookup.py +0 -28
  91. oarepo_runtime/records/relations/pid_relation.py +0 -102
  92. oarepo_runtime/records/systemfields/featured_file.py +0 -45
  93. oarepo_runtime/records/systemfields/has_draftcheck.py +0 -47
  94. oarepo_runtime/records/systemfields/icu.py +0 -371
  95. oarepo_runtime/records/systemfields/owner.py +0 -115
  96. oarepo_runtime/records/systemfields/record_status.py +0 -35
  97. oarepo_runtime/records/systemfields/selectors.py +0 -98
  98. oarepo_runtime/records/systemfields/synthetic.py +0 -130
  99. oarepo_runtime/resources/__init__.py +0 -4
  100. oarepo_runtime/resources/config.py +0 -12
  101. oarepo_runtime/resources/file_resource.py +0 -15
  102. oarepo_runtime/resources/json_serializer.py +0 -27
  103. oarepo_runtime/resources/localized_ui_json_serializer.py +0 -54
  104. oarepo_runtime/resources/resource.py +0 -53
  105. oarepo_runtime/resources/responses.py +0 -20
  106. oarepo_runtime/services/components.py +0 -429
  107. oarepo_runtime/services/config/draft_link.py +0 -23
  108. oarepo_runtime/services/config/permissions_presets.py +0 -174
  109. oarepo_runtime/services/config/service.py +0 -117
  110. oarepo_runtime/services/custom_fields/__init__.py +0 -80
  111. oarepo_runtime/services/custom_fields/mappings.py +0 -188
  112. oarepo_runtime/services/entity/__init__.py +0 -0
  113. oarepo_runtime/services/entity/config.py +0 -14
  114. oarepo_runtime/services/entity/schema.py +0 -9
  115. oarepo_runtime/services/entity/service.py +0 -48
  116. oarepo_runtime/services/expansions/__init__.py +0 -0
  117. oarepo_runtime/services/expansions/expandable_fields.py +0 -21
  118. oarepo_runtime/services/expansions/service.py +0 -4
  119. oarepo_runtime/services/facets/__init__.py +0 -33
  120. oarepo_runtime/services/facets/base.py +0 -12
  121. oarepo_runtime/services/facets/date.py +0 -72
  122. oarepo_runtime/services/facets/enum.py +0 -11
  123. oarepo_runtime/services/facets/facet_groups_names.py +0 -17
  124. oarepo_runtime/services/facets/max_facet.py +0 -13
  125. oarepo_runtime/services/facets/multilingual_facet.py +0 -33
  126. oarepo_runtime/services/facets/nested_facet.py +0 -32
  127. oarepo_runtime/services/facets/params.py +0 -192
  128. oarepo_runtime/services/facets/year_histogram.py +0 -200
  129. oarepo_runtime/services/files/__init__.py +0 -8
  130. oarepo_runtime/services/files/components.py +0 -62
  131. oarepo_runtime/services/files/service.py +0 -16
  132. oarepo_runtime/services/generators.py +0 -10
  133. oarepo_runtime/services/permissions/__init__.py +0 -3
  134. oarepo_runtime/services/permissions/generators.py +0 -103
  135. oarepo_runtime/services/relations/__init__.py +0 -0
  136. oarepo_runtime/services/relations/components.py +0 -15
  137. oarepo_runtime/services/relations/errors.py +0 -18
  138. oarepo_runtime/services/relations/mapping.py +0 -38
  139. oarepo_runtime/services/schema/cf.py +0 -13
  140. oarepo_runtime/services/schema/i18n_validation.py +0 -7
  141. oarepo_runtime/services/schema/marshmallow.py +0 -44
  142. oarepo_runtime/services/schema/marshmallow_to_json_schema.py +0 -72
  143. oarepo_runtime/services/schema/oneofschema.py +0 -192
  144. oarepo_runtime/services/schema/polymorphic.py +0 -21
  145. oarepo_runtime/services/schema/rdm.py +0 -146
  146. oarepo_runtime/services/schema/rdm_ui.py +0 -156
  147. oarepo_runtime/services/schema/ui.py +0 -251
  148. oarepo_runtime/services/schema/validation.py +0 -70
  149. oarepo_runtime/services/search.py +0 -282
  150. oarepo_runtime/services/service.py +0 -61
  151. oarepo_runtime/tasks.py +0 -6
  152. oarepo_runtime/translations/cs/LC_MESSAGES/messages.mo +0 -0
  153. oarepo_runtime/translations/cs/LC_MESSAGES/messages.po +0 -95
  154. oarepo_runtime/translations/default_translations.py +0 -6
  155. oarepo_runtime/translations/en/LC_MESSAGES/messages.mo +0 -0
  156. oarepo_runtime/translations/en/LC_MESSAGES/messages.po +0 -97
  157. oarepo_runtime/translations/messages.pot +0 -100
  158. oarepo_runtime/uow.py +0 -146
  159. oarepo_runtime/utils/__init__.py +0 -0
  160. oarepo_runtime/utils/functools.py +0 -37
  161. oarepo_runtime/utils/identity_utils.py +0 -35
  162. oarepo_runtime/utils/index.py +0 -11
  163. oarepo_runtime/utils/path.py +0 -97
  164. oarepo_runtime-1.10.3.dist-info/RECORD +0 -163
  165. oarepo_runtime-1.10.3.dist-info/entry_points.txt +0 -16
  166. oarepo_runtime-1.10.3.dist-info/top_level.txt +0 -2
  167. tests/marshmallow_to_json/__init__.py +0 -0
  168. tests/marshmallow_to_json/test_datacite_ui_schema.py +0 -1410
  169. tests/marshmallow_to_json/test_simple_schema.py +0 -52
  170. tests/pkg_data/__init__.py +0 -0
  171. {oarepo_runtime-1.10.3.dist-info → oarepo_runtime-2.0.0.dev3.dist-info}/licenses/LICENSE +0 -0
@@ -1,118 +0,0 @@
1
- from io import BytesIO
2
-
3
- from invenio_access.permissions import system_identity
4
- from invenio_records_resources.proxies import current_service_registry
5
- from invenio_records_resources.services.uow import UnitOfWork
6
-
7
- from ...uow import BulkUnitOfWork
8
- from ...utils.identity_utils import get_user_and_identity
9
- from ..types import StreamBatch, StreamEntry
10
- from ..utils import attachments_requests, get_file_service_for_record_service
11
- from . import BaseWriter
12
- from .utils import record_invenio_exceptions
13
-
14
-
15
- class AttachmentsServiceWriter(BaseWriter):
16
- """Writes the entries to a repository instance using a Service object."""
17
-
18
- def __init__(
19
- self,
20
- *,
21
- service,
22
- identity=None,
23
- update=False,
24
- **kwargs,
25
- ):
26
- """Constructor.
27
- :param service_or_name: a service instance or a key of the
28
- service registry.
29
- :param identity: access identity.
30
- :param update: if True it will update records if they exist.
31
- :param write_files: if True it will write files to the file service.
32
- :param uow: UnitOfWork fully qualified class name or class to use for the unit of work.
33
- """
34
- super().__init__(**kwargs)
35
-
36
- if isinstance(service, str):
37
- service = current_service_registry.get(service)
38
-
39
- if isinstance(identity, str):
40
- _, identity = get_user_and_identity(email=identity)
41
- elif isinstance(identity, int):
42
- _, identity = get_user_and_identity(user_id=identity)
43
- self._identity = identity or system_identity
44
- self._update = update
45
-
46
- self._file_service = None
47
- self._record_cls = getattr(service.config, "record_cls", None)
48
-
49
- self._file_service = get_file_service_for_record_service(service)
50
-
51
- def _get_stream_entry_id(self, entry: StreamEntry):
52
- return entry.id
53
-
54
- def write(self, batch: StreamBatch):
55
- """Writes the input entry using the given service."""
56
-
57
- with BulkUnitOfWork() as uow:
58
- for entry in batch.entries:
59
- if not entry.ok or entry.deleted or not entry.entry["files"]["enabled"]:
60
- continue
61
- with record_invenio_exceptions(entry):
62
- self._write_attachments(entry, uow)
63
-
64
- uow.commit()
65
-
66
- return batch
67
-
68
- def _write_attachments(self, stream_entry: StreamEntry, uow: UnitOfWork):
69
- service_kwargs = {}
70
- if uow:
71
- service_kwargs["uow"] = uow
72
- entry_id = self._get_stream_entry_id(stream_entry)
73
-
74
- existing_files = self._file_service.list_files(self._identity, entry_id)
75
- existing_files = {f["key"]: f for f in existing_files.entries}
76
-
77
- for f in stream_entry.files:
78
- if f.metadata["key"] in existing_files:
79
- if not self._update:
80
- continue
81
- # TODO: compare if the file should be deleted and re-created
82
- # if so, delete the file and create again
83
- self._file_service.delete_file(
84
- self._identity, entry_id, f.metadata["key"], **service_kwargs
85
- )
86
-
87
- self._file_service.init_files(
88
- self._identity,
89
- entry_id,
90
- [{"key": f.metadata["key"]}],
91
- **service_kwargs,
92
- )
93
- metadata = f.metadata.get("metadata", {})
94
- if metadata:
95
- self._file_service.update_file_metadata(
96
- self._identity,
97
- entry_id,
98
- file_key=f.metadata["key"],
99
- data=metadata,
100
- **service_kwargs,
101
- )
102
- self._file_service.set_file_content(
103
- self._identity,
104
- entry_id,
105
- f.metadata["key"],
106
- BytesIO(attachments_requests.get(f.content_url).content),
107
- **service_kwargs,
108
- )
109
- self._file_service.commit_file(
110
- self._identity, entry_id, f.metadata["key"], **service_kwargs
111
- )
112
- new_files_keys = set(f.metadata["key"] for f in stream_entry.files)
113
-
114
- for existing_file_key in existing_files:
115
- if existing_file_key not in new_files_keys:
116
- self._file_service.delete_file(
117
- self._identity, entry_id, existing_file_key, **service_kwargs
118
- )
@@ -1,70 +0,0 @@
1
- from invenio_access.permissions import system_identity
2
- from invenio_records_resources.proxies import current_service_registry
3
-
4
- from oarepo_runtime.datastreams.types import StreamBatch, StreamEntry
5
- from oarepo_runtime.datastreams.writers import BaseWriter
6
- from oarepo_runtime.datastreams.writers.utils import record_invenio_exceptions
7
-
8
- from ...utils.identity_utils import get_user_and_identity
9
-
10
-
11
- class PublishWriter(BaseWriter):
12
- def __init__(
13
- self,
14
- *,
15
- service,
16
- request_name="publish_draft",
17
- identity=None,
18
- direct_call=True,
19
- **kwargs
20
- ):
21
- if isinstance(service, str):
22
- service = current_service_registry.get(service)
23
-
24
- self._service = service
25
- if isinstance(identity, str):
26
- _, identity = get_user_and_identity(email=identity)
27
- elif isinstance(identity, int):
28
- _, identity = get_user_and_identity(user_id=identity)
29
- self._identity = identity or system_identity
30
- self._request_name = request_name
31
- self._direct_call = direct_call
32
-
33
- def write(self, batch: StreamBatch) -> StreamBatch:
34
- for entry in batch.ok_entries:
35
- if entry.deleted:
36
- continue
37
-
38
- with record_invenio_exceptions(entry):
39
- self._write_entry(entry)
40
-
41
- def _write_entry(self, entry: StreamEntry):
42
- if self._direct_call:
43
- data = self._service.publish(self._identity, entry.id)
44
- else:
45
- data = self._publish_via_request(self._identity, entry.id)
46
-
47
- entry.entry = data.to_dict()
48
-
49
- def _publish_via_request(self, identity, entry_id):
50
- from invenio_requests.proxies import (
51
- current_requests_service as current_invenio_requests_service,
52
- )
53
- from oarepo_requests.proxies import current_oarepo_requests_service
54
-
55
- draft = self._service.read_draft(identity, entry_id)
56
- request = current_oarepo_requests_service.create(
57
- identity=identity,
58
- data=None,
59
- request_type=self._request_name,
60
- topic=draft._record,
61
- )
62
-
63
- submit_result = current_invenio_requests_service.execute_action(
64
- identity, request.id, "submit"
65
- )
66
- accept_result = current_invenio_requests_service.execute_action(
67
- identity, request.id, "accept"
68
- )
69
-
70
- return self._service.read(identity, draft["id"])
@@ -1,175 +0,0 @@
1
- from invenio_access.permissions import system_identity
2
- from invenio_pidstore.errors import PIDDoesNotExistError
3
- from invenio_records_resources.proxies import current_service_registry
4
- from invenio_records_resources.services.uow import UnitOfWork
5
- from sqlalchemy.exc import NoResultFound
6
-
7
- from ...uow import BulkUnitOfWork
8
- from ...utils.identity_utils import get_user_and_identity
9
- from ..types import StreamBatch, StreamEntry, StreamEntryError
10
- from . import BaseWriter
11
- from .utils import record_invenio_exceptions
12
-
13
-
14
- class ServiceWriter(BaseWriter):
15
- """Writes the entries to a repository instance using a Service object."""
16
-
17
- def __init__(
18
- self,
19
- *,
20
- service,
21
- identity=None,
22
- update=False,
23
- **kwargs,
24
- ):
25
- """Constructor.
26
- :param service_or_name: a service instance or a key of the
27
- service registry.
28
- :param identity: access identity.
29
- :param update: if True it will update records if they exist.
30
- :param write_files: if True it will write files to the file service.
31
- :param uow: UnitOfWork fully qualified class name or class to use for the unit of work.
32
- """
33
- super().__init__(**kwargs)
34
-
35
- if isinstance(service, str):
36
- service = current_service_registry.get(service)
37
-
38
- self._service = service
39
- if isinstance(identity, str):
40
- _, identity = get_user_and_identity(email=identity)
41
- elif isinstance(identity, int):
42
- _, identity = get_user_and_identity(user_id=identity)
43
- self._identity = identity or system_identity
44
- self._update = update
45
-
46
- def _resolve(self, id_):
47
- if hasattr(self._service, "read_draft"):
48
- try:
49
- # try to read the draft first
50
- return self._service.read_draft(self._identity, id_)
51
- except PIDDoesNotExistError:
52
- pass
53
- try:
54
- # if the draft does not exist, read the published record
55
- # and create a draft for it
56
- rec = self._service.read(self._identity, id_)
57
- return self._service.edit(self._identity, id_)
58
- except PIDDoesNotExistError:
59
- pass
60
-
61
- else:
62
- try:
63
- return self._service.read(self._identity, id_)
64
- except PIDDoesNotExistError:
65
- pass
66
- except NoResultFound:
67
- # vocabularies do not raise a PIDDoesNotExistError, they raise sql exception
68
- pass
69
- return None
70
-
71
- def _get_stream_entry_id(self, entry: StreamEntry):
72
- return entry.id or entry.entry.get("id")
73
-
74
- def write(self, batch: StreamBatch):
75
- """Writes the input entry using the given service."""
76
- with BulkUnitOfWork() as uow:
77
- for entry in batch.entries:
78
- if entry.filtered or entry.errors:
79
- continue
80
- with record_invenio_exceptions(entry):
81
- if entry.deleted:
82
- self._delete_entry(entry, uow=uow)
83
- else:
84
- self._write_entry(entry, uow)
85
- uow.commit()
86
-
87
- return batch
88
-
89
- def _write_entry(self, stream_entry: StreamEntry, uow: UnitOfWork):
90
- entry = stream_entry.entry
91
- service_kwargs = {}
92
- if uow:
93
- service_kwargs["uow"] = uow
94
-
95
- do_create = True
96
- repository_entry = None # just to make linter happy
97
-
98
- entry_id = self._get_stream_entry_id(stream_entry)
99
-
100
- if entry_id:
101
- if self._update:
102
- repository_entry = self.try_update(entry_id, entry, **service_kwargs)
103
- if repository_entry:
104
- do_create = False
105
- else:
106
- current = self._resolve(entry_id)
107
- if current:
108
- do_create = False
109
-
110
- if do_create:
111
- repository_entry = self._service.create(
112
- self._identity, entry, **service_kwargs
113
- )
114
-
115
- if repository_entry:
116
- stream_entry.entry = repository_entry.data
117
- stream_entry.id = repository_entry.id
118
-
119
- stream_entry.context["revision_id"] = repository_entry._record.revision_id
120
- if repository_entry.errors:
121
- for err in repository_entry.errors:
122
- field = err.get("field")
123
- messages = err.get("messages")
124
- for message in messages:
125
- stream_entry.errors.append(
126
- StreamEntryError(
127
- code="validation", message=message, location=field
128
- )
129
- )
130
-
131
- def try_update(self, entry_id, entry, **service_kwargs):
132
- current = self._resolve(entry_id)
133
- if current:
134
- updated = dict(current.to_dict(), **entry)
135
- # might raise exception here but that's ok - we know that the entry
136
- # exists in db as it was _resolved
137
- if hasattr(self._service, "update_draft"):
138
- # try to update draft first
139
- return self._service.update_draft(
140
- self._identity, entry_id, updated, **service_kwargs
141
- )
142
- else:
143
- return self._service.update(
144
- self._identity, entry_id, updated, **service_kwargs
145
- )
146
-
147
- def _delete_entry(self, stream_entry: StreamEntry, uow=None):
148
- entry_id = self._get_stream_entry_id(stream_entry)
149
- if not entry_id:
150
- return
151
- service_kwargs = {}
152
- if uow:
153
- service_kwargs["uow"] = uow
154
- deletion_exceptions = []
155
- deletion_tries = 0
156
-
157
- # if the service has drafts, try to delete it first
158
- if hasattr(self._service, "delete_draft"):
159
- # delete draft
160
- deletion_tries += 1
161
- try:
162
- self._service.delete_draft(self._identity, entry_id, **service_kwargs)
163
- except Exception as e:
164
- deletion_exceptions.append(e)
165
-
166
- # delete the record if it was published
167
- deletion_tries += 1
168
- try:
169
- self._service.delete(self._identity, entry_id, **service_kwargs)
170
- except Exception as e:
171
- deletion_exceptions.append(e)
172
-
173
- if len(deletion_exceptions) == deletion_tries:
174
- # all deletion attempts failed
175
- raise deletion_exceptions[-1]
@@ -1,30 +0,0 @@
1
- import contextlib
2
-
3
- from invenio_records.systemfields.relations.errors import InvalidRelationValue
4
- from marshmallow import ValidationError
5
-
6
- from oarepo_runtime.datastreams import StreamEntry
7
-
8
- from ..types import StreamEntry, StreamEntryError
9
- from .validation_errors import format_validation_error
10
-
11
-
12
- @contextlib.contextmanager
13
- def record_invenio_exceptions(stream_entry: StreamEntry):
14
- try:
15
- yield
16
- except ValidationError as err:
17
- validation_errors = format_validation_error(err.messages)
18
- for err_path, err_value in validation_errors.items():
19
- stream_entry.errors.append(
20
- StreamEntryError(
21
- code="MARHSMALLOW", message=err_value, location=err_path
22
- )
23
- )
24
- except InvalidRelationValue as err:
25
- # TODO: better formatting for this kind of error
26
- stream_entry.errors.append(
27
- StreamEntryError.from_exception(err, message=err.args[0])
28
- )
29
- except Exception as err:
30
- stream_entry.errors.append(StreamEntryError.from_exception(err))
@@ -1,20 +0,0 @@
1
- def format_validation_error(err_messages):
2
- msg = {}
3
- for err, path in flatten_errors(err_messages, ""):
4
- if path.endswith("._schema") and err == "Unknown field.":
5
- continue
6
- path = path.replace(".value.", ".")
7
- msg[path] = err
8
- return msg
9
-
10
-
11
- def flatten_errors(err_data, path):
12
- if isinstance(err_data, (list, tuple)):
13
- for err in err_data:
14
- yield from flatten_errors(err, path)
15
- elif isinstance(err_data, dict):
16
- for k, v in err_data.items():
17
- subpath = f"{path}.{k}" if path else k
18
- yield from flatten_errors(v, subpath)
19
- else:
20
- yield str(err_data), path
@@ -1,56 +0,0 @@
1
- from io import StringIO
2
- from pathlib import Path
3
-
4
- import yaml
5
-
6
- from oarepo_runtime.datastreams import BaseWriter, StreamBatch
7
-
8
-
9
- class YamlWriter(BaseWriter):
10
- """Writes the entries to a YAML file."""
11
-
12
- def __init__(self, *, target, base_path=None, **kwargs):
13
- """Constructor.
14
- :param file_or_path: path of the output file.
15
- """
16
- super().__init__(**kwargs)
17
- if hasattr(target, "write"):
18
- # opened file
19
- self._file = target
20
- self._stream = target
21
- else:
22
- if base_path:
23
- self._file = Path(base_path).joinpath(target)
24
- else:
25
- self._file = target
26
- self._stream = open(self._file, "w")
27
-
28
- self._started = False
29
-
30
- def write(self, batch: StreamBatch):
31
- """Writes the input stream entry using a given service."""
32
-
33
- for entry in batch.entries:
34
- if not entry.ok:
35
- continue
36
-
37
- self._write_entry_separator()
38
-
39
- try:
40
- io = StringIO()
41
- yaml.safe_dump(entry.entry, io)
42
- self._stream.write(io.getvalue())
43
- except Exception as e:
44
- entry.errors.append(e)
45
-
46
- return batch
47
-
48
- def _write_entry_separator(self):
49
- if not self._started:
50
- self._started = True
51
- else:
52
- self._stream.write("---\n")
53
-
54
- def finish(self):
55
- """Finalizes writing"""
56
- self._stream.close()
@@ -1,67 +0,0 @@
1
- from invenio_records_resources.services.custom_fields import BooleanCF
2
-
3
- from oarepo_runtime.datastreams.fixtures import default_config_generator
4
- from oarepo_runtime.datastreams.readers.excel import ExcelReader
5
- from oarepo_runtime.datastreams.readers.json import JSONLinesReader, JSONReader
6
- from oarepo_runtime.datastreams.readers.service import ServiceReader
7
- from oarepo_runtime.datastreams.readers.yaml import YamlReader
8
- from oarepo_runtime.datastreams.writers.attachments_file import AttachmentsFileWriter
9
- from oarepo_runtime.datastreams.writers.attachments_service import (
10
- AttachmentsServiceWriter,
11
- )
12
- from oarepo_runtime.datastreams.writers.publish import PublishWriter
13
- from oarepo_runtime.datastreams.writers.service import ServiceWriter
14
- from oarepo_runtime.datastreams.writers.yaml import YamlWriter
15
- from oarepo_runtime.records.entity_resolvers import UserResolver
16
- from oarepo_runtime.services.config.permissions_presets import (
17
- AuthenticatedPermissionPolicy,
18
- EveryonePermissionPolicy,
19
- OaiHarvesterPermissionPolicy,
20
- ReadOnlyPermissionPolicy,
21
- )
22
- from oarepo_runtime.services.facets.facet_groups_names import facet_groups_names
23
-
24
- OAREPO_PERMISSIONS_PRESETS = {
25
- "read_only": ReadOnlyPermissionPolicy,
26
- "everyone": EveryonePermissionPolicy,
27
- "oai_harvester": OaiHarvesterPermissionPolicy,
28
- "authenticated": AuthenticatedPermissionPolicy,
29
- }
30
-
31
-
32
- DATASTREAMS_READERS = {
33
- "excel": ExcelReader,
34
- "yaml": YamlReader,
35
- "json": JSONReader,
36
- "json-lines": JSONLinesReader,
37
- "service": ServiceReader,
38
- }
39
-
40
- DATASTREAMS_READERS_BY_EXTENSION = {
41
- "xlsx": "excel",
42
- "yaml": "yaml",
43
- "yml": "yaml",
44
- "json": "json",
45
- "json5": "json",
46
- "jsonl": "json-lines",
47
- }
48
-
49
- DATASTREAMS_WRITERS = {
50
- "service": ServiceWriter,
51
- "attachments_service": AttachmentsServiceWriter,
52
- "yaml": YamlWriter,
53
- "attachments_file": AttachmentsFileWriter,
54
- "publish": PublishWriter,
55
- }
56
-
57
- DATASTREAMS_TRANSFORMERS = {}
58
-
59
- DATASTREAMS_CONFIG_GENERATOR = default_config_generator
60
-
61
- HAS_DRAFT_CUSTOM_FIELD = [BooleanCF("has_draft")]
62
-
63
- OAREPO_FACET_GROUP_NAME = facet_groups_names
64
-
65
- OWNER_ENTITY_RESOLVERS = [
66
- UserResolver(),
67
- ]
@@ -1,3 +0,0 @@
1
- from flask_babel import get_locale, gettext, lazy_gettext
2
-
3
- __all__ = ("gettext", "lazy_gettext", "get_locale")
File without changes
@@ -1,95 +0,0 @@
1
- import json, random
2
- from flask import Response, Blueprint
3
- from flask import current_app as flask_current_app
4
- from invenio_db import db # sql alchemy session
5
- from invenio_cache import current_cache # redis
6
- import redis
7
- from invenio_search import current_search_client # opensearch
8
- from celery import current_app as celery_current_app, shared_task
9
-
10
-
11
- def check_db_connection():
12
- if not has_database_connection():
13
- return "DB connection failed"
14
- else:
15
- return "ok"
16
-
17
- def has_database_connection():
18
- try:
19
- db.session.execute("select * from alembic_version").scalar()
20
- return True
21
- except:
22
- return False
23
- finally:
24
- db.session.rollback()
25
-
26
- def check_cache_connection():
27
- try:
28
- rand = random.randint(1, 1000)
29
- if current_cache.set('mykey', str(rand)):
30
- val = current_cache.get('mykey')
31
- if val == str(rand):
32
- return "ok"
33
- else:
34
- return "Cache returned unexpected value."
35
- else:
36
- return "Failed to set cache key."
37
- except redis.exceptions.ConnectionError as e:
38
- if isinstance(e.__cause__, ConnectionRefusedError):
39
- return "Cache connection error"
40
- return "Cache exception"
41
- except Exception as other:
42
- return str(other)
43
-
44
-
45
-
46
- # https://github.com/celery/celery/issues/4283
47
- def check_message_queue():
48
- from kombu.exceptions import OperationalError
49
- try:
50
- #celery_current_app.autodiscover_tasks(['oarepo_runtime.info'])
51
- ping_task = celery_current_app.send_task('ping')
52
- if ping_task.get(timeout=2) == 'pong':
53
- return "ok"
54
- except OperationalError as e:
55
- if isinstance(e.__cause__, ConnectionRefusedError):
56
- return "RabbitMQ connection refused"
57
- return "Other RabbitMQ-related error"
58
- except Exception as other:
59
- return str(other)
60
-
61
-
62
- def check_opensearch():
63
- try:
64
- is_available = current_search_client.ping()
65
- if is_available:
66
- return "ok"
67
- else:
68
- return "OpenSearch is not available"
69
- except Exception as e:
70
- return str(e)
71
-
72
-
73
- blueprint = Blueprint("repository-check", __name__, url_prefix="/.well-known")
74
-
75
- @blueprint.route("/check")
76
- def check_connections() -> Response:
77
- """
78
- Function to check all necessary connections (database, redis, rabbitmq, opensearch)
79
- Return Response 200 if everything is OK or Response 500 with json and all failed tests
80
- """
81
- check_list = {}
82
- with flask_current_app.app_context():
83
- check_list['db'] = check_db_connection()
84
- check_list['cache'] = check_cache_connection()
85
- check_list['mq'] = check_message_queue()
86
- check_list['opensearch'] = check_opensearch()
87
-
88
- failed_checks = {key: value for key, value in check_list.items() if value != 'ok'}
89
-
90
- if failed_checks:
91
- return Response(json.dumps(failed_checks), status=500, content_type='application/json')
92
-
93
- return Response(json.dumps(check_list), status=200, content_type='application/json') # good
94
-
95
-
File without changes