oarepo-runtime 1.5.29__py3-none-any.whl → 1.5.31__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.
@@ -68,11 +68,14 @@ def prepare_cf_indices():
68
68
  service: RecordService
69
69
  for service in current_service_registry._services.values():
70
70
  config: RecordServiceConfig = service.config
71
- prepare_cf_index(config)
71
+ record_class = getattr(config, "record_cls", None)
72
+ if record_class:
73
+ prepare_cf_index(record_class, config)
74
+ parent_class = getattr(record_class, "parent_record_cls", None)
75
+ prepare_cf_index(parent_class, config)
72
76
 
73
77
 
74
- def prepare_cf_index(config: RecordServiceConfig):
75
- record_class = getattr(config, "record_cls", None)
78
+ def prepare_cf_index(record_class, config):
76
79
  if not record_class:
77
80
  return
78
81
 
@@ -6,6 +6,11 @@ from invenio_records_resources.services.records.results import (
6
6
  )
7
7
 
8
8
 
9
+ class ResultsComponent:
10
+ def update_data(self, identity, record, projection, expand):
11
+ raise NotImplementedError
12
+
13
+
9
14
  class RecordItem(BaseRecordItem):
10
15
  """Single record result."""
11
16
 
@@ -17,7 +22,12 @@ class RecordItem(BaseRecordItem):
17
22
  return self._data
18
23
  _data = super().data
19
24
  for c in self.components:
20
- c.update_data(self._identity, self._record, _data)
25
+ c.update_data(
26
+ identity=self._identity,
27
+ record=self._record,
28
+ projection=_data,
29
+ expand=self._expand,
30
+ )
21
31
  return _data
22
32
 
23
33
 
@@ -47,6 +57,12 @@ class RecordList(BaseRecordList):
47
57
  projection["links"] = self._links_item_tpl.expand(
48
58
  self._identity, record
49
59
  )
60
+ # todo optimization viz FieldsResolver
50
61
  for c in self.components:
51
- c.update_data(self._identity, record, projection)
62
+ c.update_data(
63
+ identity=self._identity,
64
+ record=self._record,
65
+ projection=projection,
66
+ expand=self._expand,
67
+ )
52
68
  yield projection
@@ -0,0 +1,192 @@
1
+ import typing
2
+
3
+ from marshmallow import Schema, ValidationError
4
+
5
+
6
+ class OneOfSchema(Schema):
7
+ """
8
+ This is a special kind of schema that actually multiplexes other schemas
9
+ based on object type. When serializing values, it uses get_obj_type() method
10
+ to get object type name. Then it uses `type_schemas` name-to-Schema mapping
11
+ to get schema for that particular object type, serializes object using that
12
+ schema and adds an extra "type" field with name of object type.
13
+ Deserialization is reverse.
14
+
15
+ Example:
16
+
17
+ class Foo(object):
18
+ def __init__(self, foo):
19
+ self.foo = foo
20
+
21
+ class Bar(object):
22
+ def __init__(self, bar):
23
+ self.bar = bar
24
+
25
+ class FooSchema(marshmallow.Schema):
26
+ foo = marshmallow.fields.String(required=True)
27
+
28
+ @marshmallow.post_load
29
+ def make_foo(self, data, **kwargs):
30
+ return Foo(**data)
31
+
32
+ class BarSchema(marshmallow.Schema):
33
+ bar = marshmallow.fields.Integer(required=True)
34
+
35
+ @marshmallow.post_load
36
+ def make_bar(self, data, **kwargs):
37
+ return Bar(**data)
38
+
39
+ class MyUberSchema(marshmallow.OneOfSchema):
40
+ type_schemas = {
41
+ 'foo': FooSchema,
42
+ 'bar': BarSchema,
43
+ }
44
+
45
+ def get_obj_type(self, obj):
46
+ if isinstance(obj, Foo):
47
+ return 'foo'
48
+ elif isinstance(obj, Bar):
49
+ return 'bar'
50
+ else:
51
+ raise Exception('Unknown object type: %s' % repr(obj))
52
+
53
+ MyUberSchema().dump([Foo(foo='hello'), Bar(bar=123)], many=True)
54
+ # => [{'type': 'foo', 'foo': 'hello'}, {'type': 'bar', 'bar': 123}]
55
+
56
+ You can control type field name added to serialized object representation by
57
+ setting `type_field` class property.
58
+ """
59
+
60
+ type_field = "type"
61
+ type_field_remove = True
62
+ type_schemas: typing.Mapping[str, typing.Union[typing.Type[Schema], Schema]] = {}
63
+
64
+ def get_obj_type(self, obj):
65
+ """Returns name of the schema during dump() calls, given the object
66
+ being dumped."""
67
+ return obj.__class__.__name__
68
+
69
+ def get_data_type(self, data):
70
+ """Returns name of the schema during load() calls, given the data being
71
+ loaded. Defaults to looking up `type_field` in the data."""
72
+ data_type = data.get(self.type_field)
73
+ if self.type_field in data and self.type_field_remove:
74
+ data.pop(self.type_field)
75
+ return data_type
76
+
77
+ def dump(self, obj, *, many=None, **kwargs):
78
+ errors = {}
79
+ result_data = []
80
+ result_errors = {}
81
+ many = self.many if many is None else bool(many)
82
+ if not many:
83
+ result = result_data = self._dump(obj, **kwargs)
84
+ else:
85
+ for idx, o in enumerate(obj):
86
+ try:
87
+ result = self._dump(o, **kwargs)
88
+ result_data.append(result)
89
+ except ValidationError as error:
90
+ result_errors[idx] = error.normalized_messages()
91
+ result_data.append(error.valid_data)
92
+
93
+ result = result_data
94
+ errors = result_errors
95
+
96
+ if not errors:
97
+ return result
98
+ else:
99
+ exc = ValidationError(errors, data=obj, valid_data=result)
100
+ raise exc
101
+
102
+ def _dump(self, obj, *, update_fields=True, **kwargs):
103
+ obj_type = self.get_obj_type(obj)
104
+ if obj_type is None:
105
+ return (
106
+ None,
107
+ {"_schema": "Unknown object class: %s" % obj.__class__.__name__},
108
+ )
109
+
110
+ type_schema = self.type_schemas.get(obj_type)
111
+ if not type_schema:
112
+ return None, {"_schema": "Unsupported object type: %s" % obj_type}
113
+
114
+ schema = type_schema if isinstance(type_schema, Schema) else type_schema()
115
+
116
+ schema.context.update(getattr(self, "context", {}))
117
+
118
+ result = schema.dump(obj, many=False, **kwargs)
119
+ if result is not None:
120
+ result[self.type_field] = obj_type
121
+ return result
122
+
123
+ def load(self, data, *, many=None, partial=None, unknown=None, **kwargs):
124
+ errors = {}
125
+ result_data = []
126
+ result_errors = {}
127
+ many = self.many if many is None else bool(many)
128
+ if partial is None:
129
+ partial = self.partial
130
+ if not many:
131
+ try:
132
+ result_data = self._load(
133
+ data, partial=partial, unknown=unknown, **kwargs
134
+ )
135
+ except ValidationError as error:
136
+ result_errors = error.normalized_messages()
137
+ result_data = error.valid_data
138
+ else:
139
+ for idx, item in enumerate(data):
140
+ try:
141
+ result = self._load(item, partial=partial, **kwargs)
142
+ result_data.append(result)
143
+ except ValidationError as error:
144
+ result_errors[idx] = error.normalized_messages()
145
+ result_data.append(error.valid_data)
146
+
147
+ result = result_data
148
+ errors = result_errors
149
+
150
+ if not errors:
151
+ return result
152
+ else:
153
+ exc = ValidationError(errors, data=data, valid_data=result)
154
+ raise exc
155
+
156
+ def _load(self, data, *, partial=None, unknown=None, **kwargs):
157
+ if not isinstance(data, dict):
158
+ raise ValidationError({"_schema": "Invalid data type: %s" % data})
159
+
160
+ data = dict(data)
161
+ unknown = unknown or self.unknown
162
+ data_type = self.get_data_type(data)
163
+
164
+ if data_type is None:
165
+ raise ValidationError(
166
+ {self.type_field: ["Missing data for required field."]}
167
+ )
168
+
169
+ try:
170
+ type_schema = self.type_schemas.get(data_type)
171
+ except TypeError as error:
172
+ # data_type could be unhashable
173
+ raise ValidationError(
174
+ {self.type_field: ["Invalid value: %s" % data_type]}
175
+ ) from error
176
+ if not type_schema:
177
+ raise ValidationError(
178
+ {self.type_field: ["Unsupported value: %s" % data_type]}
179
+ )
180
+
181
+ schema = type_schema if isinstance(type_schema, Schema) else type_schema()
182
+
183
+ schema.context.update(getattr(self, "context", {}))
184
+
185
+ return schema.load(data, many=False, partial=partial, unknown=unknown, **kwargs)
186
+
187
+ def validate(self, data, *, many=None, partial=None):
188
+ try:
189
+ self.load(data, many=many, partial=partial)
190
+ except ValidationError as ve:
191
+ return ve.messages
192
+ return {}
@@ -1,8 +1,8 @@
1
1
  from functools import cached_property
2
2
 
3
3
  import marshmallow as ma
4
- from marshmallow_oneofschema import OneOfSchema
5
-
4
+ #from marshmallow_oneofschema import OneOfSchema
5
+ from oarepo_runtime.services.schema.oneofschema import OneOfSchema
6
6
 
7
7
  class PolymorphicSchema(OneOfSchema):
8
8
  type_field_remove = False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oarepo-runtime
3
- Version: 1.5.29
3
+ Version: 1.5.31
4
4
  Summary: A set of runtime extensions of Invenio repository
5
5
  Description-Content-Type: text/markdown
6
6
  License-File: LICENSE
@@ -70,13 +70,13 @@ oarepo_runtime/resources/localized_ui_json_serializer.py,sha256=3V9cJaG_e1PMXKVX
70
70
  oarepo_runtime/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
71
  oarepo_runtime/services/components.py,sha256=9wt9CmoCFA8Utbb8eNA-Mvzo5LCApHT9zHpWIWZNyXY,1506
72
72
  oarepo_runtime/services/generators.py,sha256=V582uA813AIXnFhzqUwakmDgBOI1SQe3XZeJtUXNbwM,872
73
- oarepo_runtime/services/results.py,sha256=F3A0U3MRUOYlxNglJPQeGMKdD8QNq1il106jQZ0c9gQ,1499
73
+ oarepo_runtime/services/results.py,sha256=gcITj-bWPwrGdNGGEiNWroRC-JLUoBaZbAMOZeDrQRg,1955
74
74
  oarepo_runtime/services/search.py,sha256=ywfwGH7oAM44WeOSjlIsY_qoCMZJ1TlTLd_NgE2ow3Y,5296
75
75
  oarepo_runtime/services/config/__init__.py,sha256=SCqww5sV8qh3gmev6TE8EyJbD58juIEDCm_7MEHxtSg,440
76
76
  oarepo_runtime/services/config/permissions_presets.py,sha256=zApeA-2DYAlD--SzVz3vq_OFjq48Ko0pe08e4o2vxr4,6114
77
77
  oarepo_runtime/services/config/service.py,sha256=2aq5jobPH22T1QqlJDommvAxJwo9aQGiqK5q-k-l9CA,4668
78
78
  oarepo_runtime/services/custom_fields/__init__.py,sha256=xJ7XEyMJHPfIgX5JKpgpwh7SYc9Zee2dC5oC8cm99Qc,2282
79
- oarepo_runtime/services/custom_fields/mappings.py,sha256=1mb8nYeUlQxbBolsKURGKUIpIV1NDb-7Mcur32jjIjg,4433
79
+ oarepo_runtime/services/custom_fields/mappings.py,sha256=CYJJAGo4k6Bv6D5FLy4Js9EjhWWNThJBkosAMdZIXzI,4600
80
80
  oarepo_runtime/services/expansions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
81
  oarepo_runtime/services/expansions/expandable_fields.py,sha256=7DWKFL6ml8J7zGI6wm9LO7Xd6R0LSylsuq4lyRumNHQ,745
82
82
  oarepo_runtime/services/expansions/service.py,sha256=HaEy76XOhDf__sQ91hi-8iH1hthM9q07pRhOmyZyVrs,144
@@ -100,7 +100,8 @@ oarepo_runtime/services/schema/i18n.py,sha256=myyg0tU8up0BmMt9IESKD91w5KC0V9v8Qa
100
100
  oarepo_runtime/services/schema/i18n_ui.py,sha256=18tA6uA067TP_wcit47hTel2M4hz88wYtwBgaeZDrew,1880
101
101
  oarepo_runtime/services/schema/i18n_validation.py,sha256=fyMTi2Rw-KiHv7c7HN61zGxRVa9sAjAEEkAL5wUyKNo,236
102
102
  oarepo_runtime/services/schema/marshmallow.py,sha256=LmcSxvbZ9jIhkNHCqqxt1SA2UNijoDmIzqli1MkoTrE,1153
103
- oarepo_runtime/services/schema/polymorphic.py,sha256=CkvXVUiXbrsLWFgoNnjjpUviQyzRMCmpsD3GWfV0WZA,494
103
+ oarepo_runtime/services/schema/oneofschema.py,sha256=X_pXzrkYcLGGAtGN1qltrz45OzD_atrJHkHkp3L01xg,6660
104
+ oarepo_runtime/services/schema/polymorphic.py,sha256=f9yC7MGVynAFGM0fXIq0NbqGJxI65Xpi8GaM2ZM4c6Q,561
104
105
  oarepo_runtime/services/schema/ui.py,sha256=caRca4vuUVoLew3gkhbPQYGaLXB8C67E5jxz45-9zkE,3663
105
106
  oarepo_runtime/services/schema/validation.py,sha256=fahqKGDdIYWux5ZeoljrEe8VD2fDZR9VpfvYmTYAmpw,1050
106
107
  oarepo_runtime/translations/default_translations.py,sha256=060GBlA1ghWxfeumo6NqxCCZDb-6OezOuF6pr-_GEOQ,104
@@ -114,9 +115,9 @@ oarepo_runtime/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
114
115
  oarepo_runtime/utils/functools.py,sha256=gKS9YZtlIYcDvdNA9cmYO00yjiXBYV1jg8VpcRUyQyg,1324
115
116
  oarepo_runtime/utils/path.py,sha256=V1NVyk3m12_YLbj7QHYvUpE1wScO78bYsX1LOLeXDkI,3108
116
117
  tests/pkg_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
- oarepo_runtime-1.5.29.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
118
- oarepo_runtime-1.5.29.dist-info/METADATA,sha256=CGu5jtrm_4D0h-vZma0WRJdTcjL5k6jLqIR8O0aQJcs,4680
119
- oarepo_runtime-1.5.29.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
120
- oarepo_runtime-1.5.29.dist-info/entry_points.txt,sha256=QrlXAKuPDVBinaSh_v3yO9_Nb9ZNmJCJ0VFcCW-z0Jg,327
121
- oarepo_runtime-1.5.29.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
122
- oarepo_runtime-1.5.29.dist-info/RECORD,,
118
+ oarepo_runtime-1.5.31.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
119
+ oarepo_runtime-1.5.31.dist-info/METADATA,sha256=may40TQGXta2TdoZNWFGiyYWRoaJxV54J2UtH6gaKzg,4680
120
+ oarepo_runtime-1.5.31.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
121
+ oarepo_runtime-1.5.31.dist-info/entry_points.txt,sha256=QrlXAKuPDVBinaSh_v3yO9_Nb9ZNmJCJ0VFcCW-z0Jg,327
122
+ oarepo_runtime-1.5.31.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
123
+ oarepo_runtime-1.5.31.dist-info/RECORD,,