Skip to content

Commit 37d50ae

Browse files
feat(api): activity (#2911)
1 parent bc56b8b commit 37d50ae

File tree

29 files changed

+1183
-169
lines changed

29 files changed

+1183
-169
lines changed

docs/reference/api.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,14 @@ Renku Python API
3939

4040
.. automodule:: renku.ui.api.models.plan
4141

42-
.. _api-run:
42+
.. _api-activity:
43+
44+
``Activity``
45+
------------
46+
47+
.. automodule:: renku.ui.api.models.activity
48+
49+
.. _api-parameter:
4350

4451
``Inputs, Outputs, and Parameters``
4552
-----------------------------------

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,11 +325,12 @@ flake8-max-line-length = 120
325325
testpaths = ["docs", "tests", "renku", "conftest.py"]
326326
markers = [
327327
"integration: mark a test as a integration.",
328-
"service: mark a test as service test.",
329328
"jobs: mark a test as a job test.",
330329
"migration: mark a test as a migration test.",
331-
"shelled: mark a test as a shelled test.",
330+
"publish: mark tests that publish datasets to external providers.",
332331
"serial: mark a test that can not be run in parallel",
332+
"service: mark a test as service test.",
333+
"shelled: mark a test as a shelled test.",
333334
]
334335

335336
[tool.mypy]

renku/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ def find_spec(self, fullname, path, target=None):
9696
return None
9797

9898

99-
# NOTE: Patch python impoprt machinery with custom loader
99+
# NOTE: Patch python import machinery with custom loader
100100
sys.meta_path.insert(
101101
0,
102102
DeprecatedImportInterceptor(
@@ -105,7 +105,7 @@ def find_spec(self, fullname, path, target=None):
105105
"renku.core.metadata": ("renku.infrastructure", False),
106106
"renku.core.commands": ("renku.command", True),
107107
"renku.core.plugins": ("renku.core.plugin", True),
108-
"renku.api": ("renku.ui.api", True),
108+
"renku.api": ("renku.ui.api", False),
109109
"renku.cli": ("renku.ui.cli", True),
110110
}
111111
),

renku/command/command_builder/command.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def remove_injector():
102102

103103

104104
@contextlib.contextmanager
105-
def replace_injection(bindings, constructor_bindings=None):
105+
def replace_injection(bindings: Dict, constructor_bindings=None):
106106
"""Temporarily inject various test objects.
107107
108108
Args:

renku/core/interface/activity_gateway.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ def get_all_generation_paths(self) -> List[str]:
3535
"""Return all generation paths."""
3636
raise NotImplementedError
3737

38+
def get_activities_by_usage(self, path: Union[Path, str], checksum: Optional[str] = None) -> List[Activity]:
39+
"""Return the list of all activities that use a path."""
40+
raise NotImplementedError
41+
3842
def get_activities_by_generation(self, path: Union[Path, str], checksum: Optional[str] = None) -> List[Activity]:
3943
"""Return the list of all activities that generate a path."""
4044
raise NotImplementedError
@@ -43,6 +47,10 @@ def get_downstream_activities(self, activity: Activity, max_depth=None) -> Set[A
4347
"""Get downstream activities that depend on this activity."""
4448
raise NotImplementedError
4549

50+
def get_upstream_activities(self, activity: Activity, max_depth=None) -> Set[Activity]:
51+
"""Get upstream activities that this activity depends on."""
52+
raise NotImplementedError
53+
4654
def get_downstream_activity_chains(self, activity: Activity) -> List[Tuple[Activity, ...]]:
4755
"""Get a list of tuples of all downstream paths of this activity."""
4856
raise NotImplementedError

renku/core/migration/m_0005__2_cwl.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,13 @@ def _migrate_single_step(client, cmd_line_tool, path, commit=None, parent_commit
195195
if matched_output:
196196
outputs.remove(matched_output)
197197

198-
created_outputs = []
198+
generated_outputs = []
199199
workdir_requirements = [r for r in cmd_line_tool.requirements if isinstance(r, InitialWorkDirRequirement)]
200200

201201
for r in workdir_requirements:
202202
for listing in r.listing:
203203
if listing.entry == '$({"listing": [], "class": "Directory"})':
204-
created_outputs.append(listing.entryname)
204+
generated_outputs.append(listing.entryname)
205205

206206
# NOTE: multiple outputs might bind to the same input; we use this copy to find output bindings
207207
all_inputs = inputs.copy()
@@ -244,7 +244,7 @@ def _migrate_single_step(client, cmd_line_tool, path, commit=None, parent_commit
244244
if not (client.path / path).is_dir():
245245
check_path = path.parent
246246

247-
if check_path != "." and str(check_path) in created_outputs:
247+
if check_path != "." and str(check_path) in generated_outputs:
248248
create_folder = True
249249

250250
run.outputs.append(

renku/core/util/os.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818
"""OS utility functions."""
19-
19+
import fnmatch
2020
import hashlib
2121
import os
2222
import re
@@ -205,3 +205,17 @@ def safe_read_yaml(file: str) -> Dict[str, Any]:
205205
return yaml.read_yaml(file)
206206
except Exception as e:
207207
raise errors.ParameterError(e)
208+
209+
210+
def matches(path: Union[Path, str], pattern: str) -> bool:
211+
"""Check if a path matched a given pattern."""
212+
pattern = pattern.rstrip(os.sep)
213+
214+
path = Path(path)
215+
paths = [path] + list(path.parents)[:-1]
216+
217+
for parent in paths:
218+
if fnmatch.fnmatch(str(parent), pattern):
219+
return True
220+
221+
return False

renku/core/workflow/value_resolution.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ def apply(self) -> AbstractPlan:
8989
params_map = TemplateVariableFormatter.to_map(chain(self._plan.inputs, self._plan.parameters))
9090
for param in chain(self._plan.inputs, self._plan.parameters, self._plan.outputs):
9191
if isinstance(param.actual_value, str):
92+
actual_value_set_before = getattr(param, "_v_actual_value_set", False)
9293
param.actual_value = self._template_engine.apply(param.actual_value, params_map)
94+
param._v_actual_value_set = actual_value_set_before
9395

9496
self.missing_parameters = values_keys
9597

renku/domain_model/provenance/activity.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def from_plan(
134134
started_at_time: datetime,
135135
ended_at_time: datetime,
136136
annotations: List[Annotation] = None,
137+
id: Optional[str] = None,
137138
update_commits=False,
138139
):
139140
"""Convert a ``Plan`` to a ``Activity``."""
@@ -145,7 +146,7 @@ def from_plan(
145146
generations = {}
146147
parameter_values = []
147148

148-
activity_id = cls.generate_id()
149+
activity_id = id or cls.generate_id()
149150

150151
for input in plan.inputs:
151152
input_path = input.actual_value
@@ -212,6 +213,9 @@ def from_plan(
212213

213214
return activity
214215

216+
def __repr__(self):
217+
return f"<Activity '{self.id}': {self.association.plan.name} @ {self.ended_at_time}>"
218+
215219
@cached_property
216220
def plan_with_values(self) -> Plan:
217221
"""Get a copy of the associated plan with values from ParameterValues applied."""

renku/domain_model/provenance/parameter.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,9 @@
1717
# limitations under the License.
1818
"""Classes for tracking parameter values in provenance."""
1919

20-
from itertools import chain
2120
from typing import Any
2221
from uuid import uuid4
2322

24-
from renku.core import errors
2523
from renku.domain_model.workflow.plan import Plan
2624

2725

@@ -40,9 +38,5 @@ def generate_id(activity_id: str) -> str:
4038

4139
def apply_value_to_parameter(self, plan: Plan) -> None:
4240
"""Apply the current value as actual_value on the plan's parameter."""
43-
for parameter in chain(plan.inputs, plan.outputs, plan.parameters):
44-
if parameter.id == self.parameter_id:
45-
parameter.actual_value = self.value
46-
return
47-
48-
raise errors.ParameterError(f"Parameter {self.parameter_id} not found on plan {plan.id}.")
41+
parameter = plan.get_field_by_id(self.parameter_id)
42+
parameter.actual_value = self.value

0 commit comments

Comments
 (0)