|
29 | 29 | from pyld import jsonld as ld
|
30 | 30 |
|
31 | 31 | from renku._compat import Path
|
| 32 | +from renku.models._locals import ReferenceMixin, with_reference |
32 | 33 |
|
33 | 34 | KEY = '__json_ld'
|
34 | 35 | KEY_CLS = '__json_ld_cls'
|
@@ -62,7 +63,10 @@ def wrap(cls):
|
62 | 63 | jsonld_cls = attr.s(cls, **attrs_kwargs)
|
63 | 64 |
|
64 | 65 | if not issubclass(jsonld_cls, JSONLDMixin):
|
65 |
| - jsonld_cls = make_type(cls.__name__, (jsonld_cls, JSONLDMixin), {}) |
| 66 | + jsonld_cls = attr.s( |
| 67 | + make_type(cls.__name__, (jsonld_cls, JSONLDMixin), {}), |
| 68 | + **attrs_kwargs |
| 69 | + ) |
66 | 70 |
|
67 | 71 | # Merge types
|
68 | 72 | for subcls in jsonld_cls.mro():
|
@@ -291,13 +295,13 @@ def convert_value(v):
|
291 | 295 | return rv
|
292 | 296 |
|
293 | 297 |
|
294 |
| -class JSONLDMixin(object): |
| 298 | +class JSONLDMixin(ReferenceMixin): |
295 | 299 | """Mixin for loading a JSON-LD data."""
|
296 | 300 |
|
297 | 301 | __type_registry__ = {}
|
298 | 302 |
|
299 | 303 | @classmethod
|
300 |
| - def from_jsonld(cls, data): |
| 304 | + def from_jsonld(cls, data, __reference__=None): |
301 | 305 | """Instantiate a JSON-LD class from data."""
|
302 | 306 | if isinstance(data, cls):
|
303 | 307 | return data
|
@@ -328,10 +332,33 @@ def from_jsonld(cls, data):
|
328 | 332 | # assert compacted['@type'] == cls._jsonld_type, '@type must be equal'
|
329 | 333 | # TODO update self(not cls)._jsonld_context with data['@context']
|
330 | 334 | fields = cls._jsonld_fields
|
331 |
| - return cls( |
332 |
| - **{k.lstrip('_'): v |
333 |
| - for k, v in compacted.items() if k in fields} |
334 |
| - ) |
| 335 | + |
| 336 | + if __reference__: |
| 337 | + with with_reference(__reference__): |
| 338 | + self = cls( |
| 339 | + **{ |
| 340 | + k.lstrip('_'): v |
| 341 | + for k, v in compacted.items() if k in fields |
| 342 | + } |
| 343 | + ) |
| 344 | + else: |
| 345 | + self = cls( |
| 346 | + **{ |
| 347 | + k.lstrip('_'): v |
| 348 | + for k, v in compacted.items() if k in fields |
| 349 | + } |
| 350 | + ) |
| 351 | + return self |
| 352 | + |
| 353 | + @classmethod |
| 354 | + def from_yaml(cls, path): |
| 355 | + """Return an instance from a YAML file.""" |
| 356 | + import yaml |
| 357 | + |
| 358 | + with path.open(mode='r') as fp: |
| 359 | + self = cls.from_jsonld(yaml.load(fp) or {}, __reference__=path) |
| 360 | + |
| 361 | + return self |
335 | 362 |
|
336 | 363 |
|
337 | 364 | s = attrs
|
|
0 commit comments