Skip to content

Commit 0bd2458

Browse files
committed
Solve merge conflicts
2 parents 69ef8e2 + 65d7f27 commit 0bd2458

7 files changed

Lines changed: 78 additions & 144 deletions

File tree

fairworkflows/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
# Generated workflow directory names
99
PYTHON_DIR = 'scripts'
1010
PLEX_DIR = 'plex'
11+
12+
DUMMY_FAIRWORKFLOWS_URI = 'http://fairworkflows.org'

fairworkflows/fairstep.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
from typing import Callable, get_type_hints, List, Union
55
from urllib.parse import urldefrag
66

7+
import noodles
78
import rdflib
89
from rdflib import RDF, RDFS, DCTERMS
910

10-
import noodles
11-
1211
from fairworkflows import namespaces
13-
from fairworkflows.rdf_wrapper import RdfWrapper
12+
from fairworkflows.config import DUMMY_FAIRWORKFLOWS_URI
13+
from fairworkflows.rdf_wrapper import RdfWrapper, replace_in_rdf
1414

1515
class FairVariable:
1616
"""Represents a variable.
@@ -104,7 +104,13 @@ def __init__(self, label: str = None, description: str = None, uri=None,
104104
self.inputs = inputs
105105
if outputs is not None:
106106
self.outputs = outputs
107+
# Set temporary URI to refer to this step in workflows
108+
# (i.e. 'http://fairworkflows.org#8769029329049')
109+
if uri is None:
110+
self._uri = DUMMY_FAIRWORKFLOWS_URI + '#step' + str(hash(self))
111+
107112
self._is_modified = False
113+
self._workflows = set()
108114

109115
@classmethod
110116
def from_rdf(cls, rdf, uri, fetch_references: bool = False, force: bool = False,
@@ -346,6 +352,17 @@ def validate(self, shacl=False):
346352
if shacl:
347353
self.shacl_validate()
348354

355+
def register_workflow(self, workflow):
356+
"""Register workflow that this step is part of."""
357+
self._workflows.add(workflow)
358+
359+
def _update_registered_workflows(self):
360+
"""Update the workflows that this step is part of.
361+
NB: it could be that a step was deleted from a workflow
362+
"""
363+
self._workflows = {workflow for workflow in self._workflows
364+
if self in workflow}
365+
349366
def publish_as_nanopub(self, use_test_server=False, **kwargs):
350367
"""
351368
Publish this rdf as a nanopublication.
@@ -360,7 +377,23 @@ def publish_as_nanopub(self, use_test_server=False, **kwargs):
360377
Returns:
361378
a dictionary with publication info, including 'nanopub_uri', and 'concept_uri'
362379
"""
363-
return self._publish_as_nanopub(use_test_server=use_test_server, **kwargs)
380+
self._update_registered_workflows()
381+
old_uri = self.uri
382+
self._publish_as_nanopub(use_test_server=use_test_server, **kwargs)
383+
var_names = [var.name for var in (self.inputs + self.outputs)]
384+
for workflow in self._workflows:
385+
replace_in_rdf(workflow.rdf, oldvalue=rdflib.URIRef(old_uri),
386+
newvalue=rdflib.URIRef(self.uri))
387+
388+
# Similarly replace old URIs for variable name bindings
389+
published_step_uri_defrag, _ = urldefrag(self.uri)
390+
for var_name in var_names:
391+
old_var_uri = old_uri + '#' + var_name
392+
new_var_uri = published_step_uri_defrag + '#' + var_name
393+
replace_in_rdf(self.rdf, oldvalue=rdflib.URIRef(old_var_uri),
394+
newvalue=rdflib.URIRef(new_var_uri))
395+
del workflow._steps[old_uri]
396+
workflow._steps[self.uri] = self
364397

365398
def __str__(self):
366399
"""

fairworkflows/fairworkflow.py

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1+
import inspect
12
import warnings
23
from copy import deepcopy
34
from pathlib import Path
45
from tempfile import TemporaryDirectory
56
from typing import Iterator, Optional
6-
import inspect
7-
from urllib.parse import urldefrag
87

98
import networkx as nx
109
import rdflib
1110
from rdflib import RDF, RDFS, DCTERMS
1211
from rdflib.tools.rdf2dot import rdf2dot
1312
from requests import HTTPError
1413

15-
1614
from fairworkflows import namespaces
1715
from fairworkflows.fairstep import FairStep
18-
from fairworkflows.rdf_wrapper import RdfWrapper, replace_in_rdf
16+
from fairworkflows.rdf_wrapper import RdfWrapper
1917
import nanopub
2018

2119
class FairWorkflow(RdfWrapper):
@@ -54,8 +52,7 @@ def from_rdf(cls, rdf: rdflib.Graph, uri: str,
5452
possibly it's associated steps. Should use plex ontology.
5553
uri: URI of the workflow
5654
fetch_references: toggles fetching steps. I.e. if we encounter steps
57-
that are part of the workflow, but are not specified in the
58-
RDF we try fetching them from nanopub
55+
that are part of the workflow we try fetching them from nanopub
5956
force: Toggle forcing creation of object even if url is not in any of the subjects of
6057
the passed RDF
6158
remove_irrelevant_triples: Toggle removing irrelevant triples for this FairWorkflow.
@@ -106,19 +103,18 @@ def from_noodles_promise(cls, noodles_promise, description: str = None, label: s
106103

107104
return self
108105

109-
def _extract_steps(self, rdf, uri, fetch_steps=False):
106+
def _extract_steps(self, rdf, uri, fetch_steps=True):
110107
"""Extract FairStep objects from rdf.
111108
112-
Create FairStep objects for all steps in the passed RDF. Removes
113-
triples describing steps from rdf, those will be represented in
114-
the separate step RDF. Optionally try to fetch steps from nanopub.
109+
Create FairStep objects for all steps in the passed RDF.
110+
Optionally try to fetch steps from nanopub.
115111
"""
116112
step_refs = rdf.subjects(predicate=namespaces.PPLAN.isStepOfPlan,
117113
object=rdflib.URIRef(uri))
118114
for step_ref in step_refs:
119115
step_uri = str(step_ref)
120-
step = self._extract_step_from_rdf(step_uri, rdf)
121-
if step is None and fetch_steps:
116+
step = None
117+
if fetch_steps:
122118
step = self._fetch_step(uri=step_uri)
123119
if step is None:
124120
warnings.warn(f'Could not get detailed information for '
@@ -153,19 +149,6 @@ def _get_relevant_triples(uri, rdf):
153149
g.add(triple)
154150
return g
155151

156-
@staticmethod
157-
def _extract_step_from_rdf(uri, rdf: rdflib.Graph()) -> Optional[FairStep]:
158-
relevant_triples = FairStep._get_relevant_triples(uri, rdf)
159-
step_rdf = rdflib.Graph()
160-
for triple in relevant_triples:
161-
step_rdf.add(triple)
162-
rdf.remove(triple)
163-
164-
if len(step_rdf) > 0:
165-
return FairStep.from_rdf(step_rdf, uri=uri, remove_irrelevant_triples=False)
166-
else:
167-
return None
168-
169152
@staticmethod
170153
def _fetch_step(uri: str) -> Optional[FairStep]:
171154
try:
@@ -207,6 +190,7 @@ def _add_step(self, step: FairStep):
207190
self._rdf.add((rdflib.URIRef(step.uri), namespaces.PPLAN.isStepOfPlan,
208191
self.self_ref))
209192
self._last_step_added = step
193+
step.register_workflow(self)
210194

211195
def add(self, step: FairStep, follows: FairStep = None):
212196
"""Add a step.
@@ -472,8 +456,10 @@ def draw(self, filepath):
472456
def publish_as_nanopub(self, use_test_server=False, **kwargs):
473457
"""Publish to nanopub server.
474458
475-
First publish the steps, use the URIs of the published steps in the workflow. Then
476-
publish the workflow.
459+
Publish the workflow as nanopublication to the nanopub server.
460+
461+
Raises:
462+
RuntimeError: If one of the steps of the workflow was not published yet.
477463
478464
Args:
479465
use_test_server (bool): Toggle using the test nanopub server.
@@ -489,25 +475,8 @@ def publish_as_nanopub(self, use_test_server=False, **kwargs):
489475
for step in self:
490476
if step.is_modified or not step._is_published:
491477
self._is_modified = True # If one of the steps is modified the workflow is too.
492-
old_uri = step.uri
493-
var_names = [var.name for var in (step.inputs + step.outputs)]
494-
495-
step.publish_as_nanopub(use_test_server=use_test_server, **kwargs)
496-
published_step_uri = step.uri
497-
498-
replace_in_rdf(self.rdf, oldvalue=rdflib.URIRef(old_uri),
499-
newvalue=rdflib.URIRef(published_step_uri))
500-
501-
# Similarly replace old URIs for variable name bindings
502-
published_step_uri_defrag, _ = urldefrag(published_step_uri)
503-
for var_name in var_names:
504-
old_var_uri = old_uri + '#' + var_name
505-
new_var_uri = published_step_uri_defrag + '#' + var_name
506-
replace_in_rdf(self.rdf, oldvalue=rdflib.URIRef(old_var_uri),
507-
newvalue=rdflib.URIRef(new_var_uri))
478+
raise RuntimeError(f'{step} was not published yet, please publish steps first')
508479

509-
del self._steps[old_uri]
510-
self._steps[published_step_uri] = step
511480
return self._publish_as_nanopub(use_test_server=use_test_server, **kwargs)
512481

513482
def __str__(self):

fairworkflows/rdf_wrapper.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import warnings
2-
32
from typing import List
43
from urllib.parse import urldefrag
54

@@ -8,8 +7,8 @@
87
from nanopub import Publication, NanopubClient
98

109
from fairworkflows import namespaces
11-
1210
from fairworkflows.config import PACKAGE_DIR
11+
1312
PLEX_SHAPES_SHACL_FILEPATH = str(PACKAGE_DIR / 'resources' / 'plex-shapes.ttl')
1413

1514

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
@prefix this: <http://www.example.org/workflow1> .
2-
@prefix sub: <http://www.example.org/workflow1#> .
32
@prefix pplan: <http://purl.org/net/p-plan#> .
43
@prefix terms: <http://purl.org/dc/terms/> .
54
@prefix pwo: <http://purl.org/spar/pwo/> .
5+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
66

77
{
88
this: a pplan:Plan ;
99
terms:description "This is a test workflow." ;
10-
pwo:hasFirstStep sub:step1 .
10+
pwo:hasFirstStep <http://www.example.org/step1> ;
11+
rdfs:label 'Test workflow' .
1112

12-
sub:step1 pplan:isStepOfPlan this: .
13+
<http://www.example.org/step1> pplan:isStepOfPlan this: .
1314
}

tests/resources/test_workflow_including_steps.trig

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)