ocean-runner 0.2.2__tar.gz → 0.2.3__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ocean-runner
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: A fluent API for OceanProtocol algorithms
5
5
  Project-URL: Homepage, https://github.com/AgrospAI/ocean-runner
6
6
  Project-URL: Issues, https://github.com/AgrospAI/ocean-runner/issues
@@ -1,28 +1,41 @@
1
+ import os
1
2
  from dataclasses import asdict, dataclass, field
2
3
  from logging import Logger
3
- import os
4
4
  from pathlib import Path
5
- from typing import Callable, Iterable, TypeVar
5
+ from typing import Callable, Iterable, Literal, TypeVar
6
6
 
7
7
  T = TypeVar("T")
8
8
 
9
9
 
10
- @dataclass(frozen=True)
10
+ @dataclass
11
11
  class Environment:
12
12
  """Environment variables mock"""
13
13
 
14
- base_dir: str | None = field(default=os.environ.get("BASE_DIR", None))
14
+ base_dir: str | None = field(
15
+ default_factory=lambda: os.environ.get("BASE_DIR", None),
16
+ )
15
17
  """Base data directory, defaults to '/data'"""
16
18
 
17
- dids: str = field(default=os.environ.get("DIDS"))
19
+ dids: str = field(
20
+ default_factory=lambda: os.environ.get("DIDS"),
21
+ )
18
22
  """Datasets DID's, format: '["XXXX"]'"""
19
23
 
20
- transformation_did: str = field(default=os.environ.get("TRANSFORMATION_DID"))
24
+ transformation_did: str = field(
25
+ default_factory=lambda: os.environ.get("TRANSFORMATION_DID"),
26
+ )
21
27
  """Transformation (algorithm) DID"""
22
28
 
23
- secret: str = field(default=os.environ.get("SECRET"))
29
+ secret: str = field(
30
+ default_factory=lambda: os.environ.get("SECRET"),
31
+ )
24
32
  """Super secret secret"""
25
33
 
34
+ runtime: Literal["dev", "test"] = field(
35
+ default_factory=lambda: os.environ.get("RUNTIME", "dev").lower()
36
+ )
37
+ """Select runtime mode"""
38
+
26
39
  dict = asdict
27
40
 
28
41
 
@@ -44,5 +57,7 @@ class Config:
44
57
  )
45
58
  """Paths that should be included so the code executes correctly"""
46
59
 
47
- environment: Environment = Environment()
60
+ environment: Environment = field(
61
+ default_factory=lambda: Environment(),
62
+ )
48
63
  """Mock of environment data"""
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from dataclasses import InitVar, asdict, dataclass, field
2
4
  from logging import Logger
3
5
  from pathlib import Path
@@ -6,6 +8,7 @@ from typing import Callable, Generic, Self, TypeVar
6
8
  from oceanprotocol_job_details import JobDetails
7
9
 
8
10
  from ocean_runner.config import Config
11
+ from ocean_runner.runtime_mode import RuntimeMode
9
12
 
10
13
  JobDetailsT = TypeVar(
11
14
  "JobDetailsT",
@@ -13,24 +16,37 @@ JobDetailsT = TypeVar(
13
16
  ResultT = TypeVar("ResultT")
14
17
 
15
18
 
16
- def default_error_callback(e: Exception) -> None:
19
+ def default_error_callback(_: Algorithm, e: Exception) -> None:
17
20
  raise e
18
21
 
19
22
 
20
- def default_validation(algorithm: "Algorithm") -> None:
23
+ def default_validation(algorithm: Algorithm) -> None:
21
24
  algorithm.logger.info("Validating input using default validation")
22
25
 
23
26
  assert algorithm.job_details.ddos, "DDOs missing"
24
27
  assert algorithm.job_details.files, "Files missing"
25
28
 
26
29
 
27
- def default_save(*, result: ResultT, base: Path, algorithm: "Algorithm") -> None:
30
+ def default_save(*, result: ResultT, base: Path, algorithm: Algorithm) -> None:
28
31
  algorithm.logger.info("Saving results using default save")
29
32
 
30
33
  with open(base / "result.txt", "w+") as f:
31
34
  f.write(str(result))
32
35
 
33
36
 
37
+ def default_test_run(algorithm: Algorithm) -> int:
38
+ import pytest
39
+
40
+ result = pytest.main()
41
+
42
+ if result == 0:
43
+ algorithm.logger.info("Passed all tests")
44
+ else:
45
+ algorithm.logger.error("Some tests failed")
46
+
47
+ return result
48
+
49
+
34
50
  @dataclass
35
51
  class Algorithm(Generic[JobDetailsT, ResultT]):
36
52
 
@@ -38,16 +54,18 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
38
54
 
39
55
  # Load from config
40
56
  logger: Logger = field(init=False)
41
- error_callback: Callable[[Exception], None] = field(init=False)
42
57
 
43
58
  _job_details: JobDetails[JobDetailsT] = field(init=False)
44
59
  _result: ResultT | None = field(default=None, init=False)
60
+ _runtime: RuntimeMode = field(default=RuntimeMode.DEV, init=False)
61
+
62
+ error_callback = default_error_callback
45
63
 
46
64
  def __post_init__(self, config: Config | None) -> None:
47
- config = config or Config()
65
+ config: Config = config or Config()
48
66
 
49
- # Use config or use a default implementation
50
- self.error_callback = config.error_callback or default_error_callback
67
+ if config.error_callback:
68
+ self.error_callback = config.error_callback
51
69
 
52
70
  if config.logger:
53
71
  self.logger = config.logger
@@ -71,9 +89,14 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
71
89
  sys.path.extend([str(path.absolute()) for path in config.source_paths])
72
90
  self.logger.debug(f"Added [{len(config.source_paths)}] entries to PATH")
73
91
 
92
+ self._runtime = RuntimeMode(config.environment.runtime) or self._runtime
93
+
74
94
  self._job_details = JobDetails.load(
75
- config.custom_input,
76
- **config.environment.dict(),
95
+ _type=config.custom_input,
96
+ base_dir=config.environment.base_dir,
97
+ dids=config.environment.dids,
98
+ transformation_did=config.environment.transformation_did,
99
+ secret=config.environment.secret,
77
100
  )
78
101
 
79
102
  self.logger.info("Loaded JobDetails")
@@ -103,8 +126,11 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
103
126
  return self
104
127
 
105
128
  def run(self, callable: Callable[[Self], ResultT]) -> Self:
106
- self.logger.info("Running algorithm ...")
129
+ self.logger.info("Running algorithm...")
107
130
  try:
131
+ if self._runtime == RuntimeMode.TEST:
132
+ callable = default_test_run
133
+
108
134
  self._result = callable(self)
109
135
  except Exception as e:
110
136
  self.error_callback(e)
@@ -113,7 +139,7 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
113
139
 
114
140
  def save_results(
115
141
  self,
116
- callable: Callable[[ResultT, Path, "Algorithm"], None] = default_save,
142
+ callable: Callable[[ResultT, Path, Algorithm], None] = default_save,
117
143
  ) -> None:
118
144
  self.logger.info("Saving results...")
119
145
  try:
@@ -124,3 +150,6 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
124
150
  )
125
151
  except Exception as e:
126
152
  self.error_callback(e)
153
+
154
+
155
+ __all__ = [Algorithm]
@@ -0,0 +1,6 @@
1
+ from enum import Enum
2
+
3
+
4
+ class RuntimeMode(Enum):
5
+ DEV = "dev"
6
+ TEST = "test"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ocean-runner"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  description = "A fluent API for OceanProtocol algorithms"
5
5
  authors = [
6
6
  { name = "AgrospAI", email = "agrospai@udl.cat" },
File without changes
File without changes
File without changes