oarepo-runtime 1.5.65__py3-none-any.whl → 1.5.67__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.
- oarepo_runtime/info/views.py +16 -4
- oarepo_runtime/records/systemfields/selectors.py +11 -17
- oarepo_runtime/resources/json_serializer.py +27 -0
- oarepo_runtime/services/schema/marshmallow_to_json_schema.py +72 -0
- {oarepo_runtime-1.5.65.dist-info → oarepo_runtime-1.5.67.dist-info}/METADATA +1 -1
- {oarepo_runtime-1.5.65.dist-info → oarepo_runtime-1.5.67.dist-info}/RECORD +13 -8
- tests/marshmallow_to_json/__init__.py +0 -0
- tests/marshmallow_to_json/test_datacite_ui_schema.py +1410 -0
- tests/marshmallow_to_json/test_simple_schema.py +52 -0
- {oarepo_runtime-1.5.65.dist-info → oarepo_runtime-1.5.67.dist-info}/LICENSE +0 -0
- {oarepo_runtime-1.5.65.dist-info → oarepo_runtime-1.5.67.dist-info}/WHEEL +0 -0
- {oarepo_runtime-1.5.65.dist-info → oarepo_runtime-1.5.67.dist-info}/entry_points.txt +0 -0
- {oarepo_runtime-1.5.65.dist-info → oarepo_runtime-1.5.67.dist-info}/top_level.txt +0 -0
oarepo_runtime/info/views.py
CHANGED
@@ -105,6 +105,7 @@ class InfoResource(Resource):
|
|
105
105
|
if model_data.get("type") != "model":
|
106
106
|
continue
|
107
107
|
|
108
|
+
resource_config_class = self._get_resource_config_class(model_data)
|
108
109
|
service = self._get_service(model_data)
|
109
110
|
service_class = self._get_service_class(model_data)
|
110
111
|
if not service or type(service) != service_class:
|
@@ -143,7 +144,7 @@ class InfoResource(Resource):
|
|
143
144
|
"links": links,
|
144
145
|
# TODO: we also need to get previous schema versions here if we support
|
145
146
|
# multiple version of the same schema at the same time
|
146
|
-
"
|
147
|
+
"accept": self._get_model_accept_types(service, resource_config_class),
|
147
148
|
}
|
148
149
|
)
|
149
150
|
self.call_components("model", data=data)
|
@@ -273,16 +274,27 @@ class InfoResource(Resource):
|
|
273
274
|
logger.exception("Failed to get model model endpoint")
|
274
275
|
return None
|
275
276
|
|
276
|
-
def
|
277
|
+
def _get_model_accept_types(self, service, resource_config):
|
277
278
|
try:
|
278
279
|
record_cls = service.config.record_cls
|
279
280
|
schema = getattr(record_cls, "schema", None)
|
280
|
-
|
281
|
-
|
281
|
+
accept_types = []
|
282
|
+
for accept_type, handler in resource_config.response_handlers.items():
|
283
|
+
curr_item = {'accept': accept_type}
|
284
|
+
if handler.serializer is not None and hasattr(handler.serializer, "info"):
|
285
|
+
curr_item.update(handler.serializer.info(service))
|
286
|
+
accept_types.append(curr_item)
|
287
|
+
|
288
|
+
return accept_types
|
282
289
|
except: # NOSONAR noqa
|
283
290
|
logger.exception("Failed to get model schemas")
|
284
291
|
return {}
|
285
292
|
|
293
|
+
|
294
|
+
def _get_resource_config_class(self, model_data):
|
295
|
+
model_class = model_data['resource-config']['class']
|
296
|
+
return obj_or_import_string(model_class)()
|
297
|
+
|
286
298
|
def _get_service(self, model_data):
|
287
299
|
service_id = model_data["service-config"]["service-id"]
|
288
300
|
try:
|
@@ -1,7 +1,10 @@
|
|
1
|
-
|
1
|
+
import dataclasses
|
2
|
+
from typing import Any, Callable, List, Protocol, Tuple
|
2
3
|
|
4
|
+
from oarepo_runtime.records.relations.lookup import lookup_key
|
3
5
|
|
4
|
-
|
6
|
+
|
7
|
+
class Selector(Protocol):
|
5
8
|
def select(self, record) -> List[Any]:
|
6
9
|
return []
|
7
10
|
|
@@ -25,6 +28,7 @@ class FirstItemSelector(PathSelector):
|
|
25
28
|
return []
|
26
29
|
|
27
30
|
|
31
|
+
@dataclasses.dataclass
|
28
32
|
class FilteredSelector(Selector):
|
29
33
|
"""
|
30
34
|
Selector which filters output of another selector
|
@@ -43,17 +47,9 @@ class FilteredSelector(Selector):
|
|
43
47
|
}
|
44
48
|
}
|
45
49
|
"""
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
selector: Selector,
|
50
|
-
filter: Callable[[Any], bool],
|
51
|
-
projection: Callable[[Any], Any] | str = None,
|
52
|
-
):
|
53
|
-
|
54
|
-
self.selector = selector
|
55
|
-
self.filter = filter
|
56
|
-
self.projection = projection
|
50
|
+
selector: Selector
|
51
|
+
filter: Callable[[Any], bool]
|
52
|
+
projection: Callable[[Any], Any] | str = None
|
57
53
|
|
58
54
|
def select(self, record):
|
59
55
|
selected = self.selector.select(record)
|
@@ -62,10 +58,7 @@ class FilteredSelector(Selector):
|
|
62
58
|
ret = []
|
63
59
|
for select_element in selected:
|
64
60
|
if isinstance(self.projection, str):
|
65
|
-
|
66
|
-
result = select_element[self.projection]
|
67
|
-
else:
|
68
|
-
result = []
|
61
|
+
result = [x.value for x in lookup_key(select_element, self.projection)]
|
69
62
|
else:
|
70
63
|
result = self.projection(select_element)
|
71
64
|
if isinstance(result, list):
|
@@ -77,6 +70,7 @@ class FilteredSelector(Selector):
|
|
77
70
|
return ret
|
78
71
|
|
79
72
|
|
73
|
+
@dataclasses.dataclass
|
80
74
|
class MultiSelector(Selector):
|
81
75
|
"""Selector concatenating outputs of multiple selectors"""
|
82
76
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from flask import url_for
|
2
|
+
from flask_resources import JSONSerializer as FlaskJSONSerializer
|
3
|
+
from invenio_records_resources.services import Service
|
4
|
+
|
5
|
+
|
6
|
+
class JSONSerializer(FlaskJSONSerializer):
|
7
|
+
|
8
|
+
def info(self, service:Service) -> dict:
|
9
|
+
ret = {'description': "Invenio RDM JSON Serialization",
|
10
|
+
'name': "JSON Serialization"
|
11
|
+
}
|
12
|
+
|
13
|
+
schema_value = service.config.record_cls.schema.value
|
14
|
+
if schema_value:
|
15
|
+
ret['schema'] = schema_value
|
16
|
+
if schema_value.startswith("local://"):
|
17
|
+
schema_value = schema_value.replace("local://", "")
|
18
|
+
ret['schema_url'] = url_for(
|
19
|
+
"oarepo_runtime_info.schema",
|
20
|
+
schema= schema_value,
|
21
|
+
_external=True,
|
22
|
+
)
|
23
|
+
elif schema_value.startwith("http://") or schema_value.startwith("https://"):
|
24
|
+
ret['schema_url'] = schema_value
|
25
|
+
|
26
|
+
|
27
|
+
return ret
|
@@ -0,0 +1,72 @@
|
|
1
|
+
from marshmallow import Schema, fields
|
2
|
+
from oarepo_runtime.services.schema.ui import (
|
3
|
+
LocalizedEDTFTime,
|
4
|
+
LocalizedDateTime,
|
5
|
+
LocalizedEDTF,
|
6
|
+
LocalizedEDTFInterval,
|
7
|
+
LocalizedEDTFTimeInterval,
|
8
|
+
LocalizedTime
|
9
|
+
)
|
10
|
+
|
11
|
+
field_type_converters = {
|
12
|
+
fields.String : lambda field: {"type" : "string"},
|
13
|
+
fields.Integer: lambda field: {"type": "integer"},
|
14
|
+
fields.Float: lambda field: {"type": "number"},
|
15
|
+
fields.Boolean: lambda field: {"type": "boolean"},
|
16
|
+
fields.List: lambda field: {
|
17
|
+
"type": "array",
|
18
|
+
"items": convert_field_to_json_schema(field.inner)
|
19
|
+
},
|
20
|
+
fields.Nested: lambda field: {
|
21
|
+
"type": "object",
|
22
|
+
"properties": marshmallow_to_json_schema(field.schema)["properties"]
|
23
|
+
},
|
24
|
+
fields.Raw: lambda field: {
|
25
|
+
"type": "object",
|
26
|
+
'additionalProperties' : True
|
27
|
+
},
|
28
|
+
LocalizedEDTFTime: lambda field: {
|
29
|
+
"type": "string",
|
30
|
+
"format": "date-time",
|
31
|
+
},
|
32
|
+
LocalizedDateTime: lambda field: {
|
33
|
+
"type": "string",
|
34
|
+
"format": "date-time",
|
35
|
+
},
|
36
|
+
LocalizedTime: lambda field: {
|
37
|
+
"type": "string",
|
38
|
+
"format": "time",
|
39
|
+
},
|
40
|
+
LocalizedEDTF: lambda field: {
|
41
|
+
"type": "string",
|
42
|
+
"format": "date",
|
43
|
+
},
|
44
|
+
LocalizedEDTFInterval: lambda field: {
|
45
|
+
"type": "string",
|
46
|
+
"format": "date-time",
|
47
|
+
},
|
48
|
+
LocalizedEDTFTimeInterval: lambda field: {
|
49
|
+
"type": "string",
|
50
|
+
"format": "date-time",
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
def marshmallow_to_json_schema(schema:Schema) -> dict:
|
55
|
+
json_schema = {
|
56
|
+
'type': 'object',
|
57
|
+
'properties': {}
|
58
|
+
}
|
59
|
+
|
60
|
+
for field_name, field in schema.fields.items():
|
61
|
+
json_schema["properties"][field_name] = convert_field_to_json_schema(field)
|
62
|
+
|
63
|
+
return json_schema
|
64
|
+
|
65
|
+
|
66
|
+
def convert_field_to_json_schema(field:fields) -> dict:
|
67
|
+
for field_type in type(field).mro():
|
68
|
+
if field_type in field_type_converters:
|
69
|
+
return field_type_converters[field_type](field)
|
70
|
+
|
71
|
+
# no converter found, just string
|
72
|
+
return {"type":"string"}
|
@@ -43,7 +43,7 @@ oarepo_runtime/datastreams/writers/yaml.py,sha256=XchUJHQ58E2Mfgs8elImXbL38jFtI8
|
|
43
43
|
oarepo_runtime/i18n/__init__.py,sha256=h0knW_HwiyIt5TBHfdGqN7_BBYfpz1Fw6zhVy0C28fM,111
|
44
44
|
oarepo_runtime/info/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
45
45
|
oarepo_runtime/info/check.py,sha256=WWAqMIBmc7veQKflRBe97_PoDsvJ1DrDrJuTDNeGDaI,3076
|
46
|
-
oarepo_runtime/info/views.py,sha256=
|
46
|
+
oarepo_runtime/info/views.py,sha256=q9PG46aM-1ihaVxJGjfcD5HvJWanM28gMefao8FIQk4,12440
|
47
47
|
oarepo_runtime/records/__init__.py,sha256=3vzRsAPxl4d5QOnGyls-vUg4E6PunmR4ACObtacMAIQ,1038
|
48
48
|
oarepo_runtime/records/dumpers/__init__.py,sha256=OmzNhLdMNKibmCksnj9eTX9xPBG30dziiK3j3bAAp3k,233
|
49
49
|
oarepo_runtime/records/dumpers/edtf_interval.py,sha256=YCShZAoqBQYaxVilEVotS-jXZsxxoXO67yu2urhkaMA,1198
|
@@ -64,10 +64,11 @@ oarepo_runtime/records/systemfields/icu.py,sha256=sSGAgi5WhsAY4cCBL7-7nMpvHAuctp
|
|
64
64
|
oarepo_runtime/records/systemfields/mapping.py,sha256=tXOK_jkdY1pOUO7_VfChfDNB8UTi21GUXaidpugTnO8,1017
|
65
65
|
oarepo_runtime/records/systemfields/owner.py,sha256=dYRVBinniW7ECHuSnTAjeN6x1KhhJtNR9vxmD1KswMs,3805
|
66
66
|
oarepo_runtime/records/systemfields/record_status.py,sha256=U3kem4-JkNsT17e0iAl3HIAZ2MvO5lY_0U757aZvTKE,935
|
67
|
-
oarepo_runtime/records/systemfields/selectors.py,sha256=
|
67
|
+
oarepo_runtime/records/systemfields/selectors.py,sha256=Q9jE1smSN3heT2LIpK_jB6bIRjll1kX0AW9AhTsIYiU,2830
|
68
68
|
oarepo_runtime/records/systemfields/synthetic.py,sha256=UustvhzcDGuaNZLDeHbWwshoxQR-qRIuHDCct5RXmrI,4287
|
69
69
|
oarepo_runtime/resources/__init__.py,sha256=v8BGrOTu_FjKzd0eozV7Q4GoGxyfybsL2cI-tbP5Pys,185
|
70
70
|
oarepo_runtime/resources/file_resource.py,sha256=Ta3bFce7l0xwqkkOMOEu9mxbB8BbKj5HUHRHmidhnl8,414
|
71
|
+
oarepo_runtime/resources/json_serializer.py,sha256=82_-xQEtxKaPakv8R1oBAFbGnxskF_Ve4tcfcy4PetI,963
|
71
72
|
oarepo_runtime/resources/localized_ui_json_serializer.py,sha256=3V9cJaG_e1PMXKVX_wKfBp1LmbeForwHyBNYdyha4uQ,1878
|
72
73
|
oarepo_runtime/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
73
74
|
oarepo_runtime/services/components.py,sha256=zaZroTqzV5fz8yVAtRFLbbkTT9iD_dx9jFYANm3JIfI,3285
|
@@ -106,6 +107,7 @@ oarepo_runtime/services/schema/i18n.py,sha256=NACu0SqXWuuwKVpBZdz4K8tVfBaCEI9Ypc
|
|
106
107
|
oarepo_runtime/services/schema/i18n_ui.py,sha256=MnEDW0gcZPvEODbJ6XzldxNCJ2suhfmdHQ4wkcAG6zA,2179
|
107
108
|
oarepo_runtime/services/schema/i18n_validation.py,sha256=fyMTi2Rw-KiHv7c7HN61zGxRVa9sAjAEEkAL5wUyKNo,236
|
108
109
|
oarepo_runtime/services/schema/marshmallow.py,sha256=LmcSxvbZ9jIhkNHCqqxt1SA2UNijoDmIzqli1MkoTrE,1153
|
110
|
+
oarepo_runtime/services/schema/marshmallow_to_json_schema.py,sha256=VYLnVWHOoaxWCD_gqJO8-8u1SbaPEFBjDZ5HGgGr0Ow,2027
|
109
111
|
oarepo_runtime/services/schema/oneofschema.py,sha256=GnWH4Or_G5M0NgSmCoqMI6PBrJg5AC9RHrcB5QDKRq0,6661
|
110
112
|
oarepo_runtime/services/schema/polymorphic.py,sha256=bAbUoTIeDBiJPYPhpLEKKZekEdkHlpqkmNxk1hN3PDw,564
|
111
113
|
oarepo_runtime/services/schema/ui.py,sha256=xQgW-zLyZoHldGw47uVtXQj-5LexVNKTholyq4MiBZo,3777
|
@@ -120,10 +122,13 @@ oarepo_runtime/translations/en/LC_MESSAGES/messages.po,sha256=rZ2PGvkcJbmuwrWeFX
|
|
120
122
|
oarepo_runtime/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
121
123
|
oarepo_runtime/utils/functools.py,sha256=gKS9YZtlIYcDvdNA9cmYO00yjiXBYV1jg8VpcRUyQyg,1324
|
122
124
|
oarepo_runtime/utils/path.py,sha256=V1NVyk3m12_YLbj7QHYvUpE1wScO78bYsX1LOLeXDkI,3108
|
125
|
+
tests/marshmallow_to_json/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
126
|
+
tests/marshmallow_to_json/test_datacite_ui_schema.py,sha256=82iLj8nW45lZOUewpWbLX3mpSkpa9lxo-vK-Qtv_1bU,48552
|
127
|
+
tests/marshmallow_to_json/test_simple_schema.py,sha256=izZN9p0v6kovtSZ6AdxBYmK_c6ZOti2_z_wPT_zXIr0,1500
|
123
128
|
tests/pkg_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
124
|
-
oarepo_runtime-1.5.
|
125
|
-
oarepo_runtime-1.5.
|
126
|
-
oarepo_runtime-1.5.
|
127
|
-
oarepo_runtime-1.5.
|
128
|
-
oarepo_runtime-1.5.
|
129
|
-
oarepo_runtime-1.5.
|
129
|
+
oarepo_runtime-1.5.67.dist-info/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
|
130
|
+
oarepo_runtime-1.5.67.dist-info/METADATA,sha256=ez6B3ZQgi4B75qLsCQ3GX8Sk6BjB6P2CTyScWW4OiGQ,4720
|
131
|
+
oarepo_runtime-1.5.67.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
132
|
+
oarepo_runtime-1.5.67.dist-info/entry_points.txt,sha256=0cschM0RHc6UJ1uudhu4EP0hrVStPGpgMO-XEDGRtY4,430
|
133
|
+
oarepo_runtime-1.5.67.dist-info/top_level.txt,sha256=bHhlkT1_RQC4IkfTQCqA3iN4KCB6cSFQlsXpQMSP-bE,21
|
134
|
+
oarepo_runtime-1.5.67.dist-info/RECORD,,
|
File without changes
|