|
3 | 3 | from pathlib import Path |
4 | 4 | from tempfile import TemporaryDirectory |
5 | 5 | from typing import Iterator, Optional |
| 6 | +import inspect |
6 | 7 |
|
7 | 8 | import networkx as nx |
8 | 9 | import rdflib |
@@ -69,7 +70,9 @@ def from_rdf(cls, rdf: rdflib.Graph, uri: str, |
69 | 70 | return self |
70 | 71 |
|
71 | 72 | @classmethod |
72 | | - def from_noodles_promise(cls, noodles_promise): |
| 73 | + def from_noodles_promise(cls, noodles_promise, description: str = None, label: str = None, |
| 74 | + is_pplan_plan: bool = True, derived_from=None): |
| 75 | + self = cls(description=description, label=label, is_pplan_plan=is_pplan_plan, derived_from=derived_from) |
73 | 76 | self.noodles_promise = noodles_promise |
74 | 77 |
|
75 | 78 | def _extract_steps(self, rdf, uri, fetch_steps=False): |
@@ -395,3 +398,35 @@ def __str__(self): |
395 | 398 | s += self._rdf.serialize(format='trig').decode('utf-8') |
396 | 399 | return s |
397 | 400 |
|
| 401 | + |
| 402 | +def is_fairworkflow(label: str = None, is_pplan_plan: bool = True): |
| 403 | + """Mark a function as returning a FAIR workflow. |
| 404 | +
|
| 405 | + Use as decorator to mark a function as a FAIR workflow. Set properties of the fair workflow using |
| 406 | + arguments to the decorator. |
| 407 | +
|
| 408 | + The raw code of the function will be used to set the description of the fair workflow. |
| 409 | +
|
| 410 | + The type annotations of the input arguments and return statement will be used to |
| 411 | + automatically set inputs and outputs of the FAIR workflow. |
| 412 | +
|
| 413 | + Args: |
| 414 | + label (str): Label of the fair workflow (corresponds to rdfs:label predicate) |
| 415 | + is_pplan_plan (str): Denotes whether this workflow is a pplan:Plan |
| 416 | +
|
| 417 | + """ |
| 418 | + def _modify_function(func): |
| 419 | + """ |
| 420 | + Store FairStep object as _fairstep attribute of the function. Use inspection to get the |
| 421 | + description, inputs, and outputs of the step based on the function specification. |
| 422 | + """ |
| 423 | + def _wrapper(*args, **kwargs): |
| 424 | + promise = func(*args, **kwargs) |
| 425 | + |
| 426 | + # Description of workflow is the raw function code |
| 427 | + description = inspect.getsource(func) |
| 428 | + |
| 429 | + return FairWorkflow.from_noodles_promise(promise, description=description, label=label, |
| 430 | + is_pplan_plan=is_pplan_plan, derived_from=None) |
| 431 | + return _wrapper |
| 432 | + return _modify_function |
0 commit comments