ocean-runner 0.2.14__py3-none-any.whl → 0.2.16__py3-none-any.whl

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.
ocean_runner/runner.py CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  from dataclasses import InitVar, asdict, dataclass, field
4
4
  from logging import Logger
5
5
  from pathlib import Path
6
- from typing import Callable, Generic, Self, TypeVar
6
+ from typing import Callable, Generic, TypeVar
7
7
 
8
8
  from oceanprotocol_job_details import JobDetails
9
9
 
@@ -42,14 +42,15 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
42
42
  _job_details: JobDetails[JobDetailsT] = field(init=False)
43
43
  _result: ResultT | None = field(default=None, init=False)
44
44
 
45
- error_callback: Callable[[Algorithm, Exception], None] = default_error_callback
46
-
47
45
  # Decorator-registered callbacks
48
46
  _validate_fn: Callable[[Algorithm], None] | None = field(default=None, init=False)
49
47
  _run_fn: Callable[[Algorithm], ResultT] | None = field(default=None, init=False)
50
48
  _save_fn: Callable[[ResultT, Path, Algorithm], None] | None = field(
51
49
  default=None, init=False
52
50
  )
51
+ _error_callback: Callable[[Algorithm, Exception], None] = field(
52
+ default=default_error_callback, init=False
53
+ )
53
54
 
54
55
  def __post_init__(self, config: Config | None) -> None:
55
56
  config: Config = config or Config()
@@ -110,20 +111,20 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
110
111
  # Decorators (FastAPI-style)
111
112
  # ---------------------------
112
113
 
113
- def validate(self, fn: Callable[[Self], None]) -> Callable[[Self], None]:
114
+ def validate(self, fn: Callable[[], None]) -> Callable[[], None]:
114
115
  self._validate_fn = fn
115
116
  return fn
116
117
 
117
- def run(self, fn: Callable[[Self], ResultT]) -> Callable[[Self], ResultT]:
118
+ def run(self, fn: Callable[[], ResultT]) -> Callable[[], ResultT]:
118
119
  self._run_fn = fn
119
120
  return fn
120
121
 
121
- def save_results(self, fn: Callable[[ResultT, Path, Algorithm], None]) -> Callable:
122
+ def save_results(self, fn: Callable[[ResultT, Path], None]) -> Callable:
122
123
  self._save_fn = fn
123
124
  return fn
124
125
 
125
- def on_error(self, fn: Callable[[Algorithm, Exception], None]) -> Callable:
126
- self.error_callback = fn
126
+ def on_error(self, fn: Callable[[Exception], None]) -> Callable:
127
+ self._error_callback = fn
127
128
  return fn
128
129
 
129
130
  # ---------------------------
@@ -136,7 +137,7 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
136
137
  # Validation step
137
138
  if self._validate_fn:
138
139
  self.logger.info("Running custom validation...")
139
- self._validate_fn(self)
140
+ self._validate_fn()
140
141
  else:
141
142
  self.logger.info("Running default validation...")
142
143
  default_validation(self)
@@ -144,7 +145,7 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
144
145
  # Run step
145
146
  if self._run_fn:
146
147
  self.logger.info("Running algorithm...")
147
- self._result = self._run_fn(self)
148
+ self._result = self._run_fn()
148
149
  else:
149
150
  self.logger.warning("No run() function defined. Skipping execution.")
150
151
  self._result = None
@@ -155,7 +156,6 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
155
156
  self._save_fn(
156
157
  self._result,
157
158
  self.job_details.paths.outputs,
158
- self,
159
159
  )
160
160
  else:
161
161
  self.logger.info("No save_results() defined. Using default.")
@@ -167,6 +167,6 @@ class Algorithm(Generic[JobDetailsT, ResultT]):
167
167
 
168
168
  except Exception as e:
169
169
  self.logger.exception("Error during algorithm execution")
170
- self.error_callback(self, e)
170
+ self._error_callback(e)
171
171
 
172
172
  return self._result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ocean-runner
3
- Version: 0.2.14
3
+ Version: 0.2.16
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
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
23
23
 
24
24
  # ocean-runner
25
25
 
26
- Ocean Runner is a package that brings a fluent API for APP creation and running in the scope of OceanProtocol.
26
+ Ocean Runner is a package that eases algorithm creation in the scope of OceanProtocol.
27
27
 
28
28
 
29
29
  ## Installation
@@ -40,33 +40,40 @@ uv add ocean-runner
40
40
 
41
41
  ```python
42
42
  import random
43
- from ocean_runner import Algorithm, Config
43
+ from ocean_runner import Algorithm
44
+
45
+ algorithm = Algorithm()
46
+
44
47
 
48
+ @algorithm.run
49
+ def run():
50
+ return random.randint()
45
51
 
46
- Algorithm().run(lambda _: random.randint()).save_results()
52
+
53
+ if __name__ == "__main__":
54
+ algorithm()
47
55
  ```
48
56
 
49
- To use minimally the API, you can just provide a callback to the run method, defaulting for the rest of behaviours. This code snippet will:
57
+ This code snippet will:
50
58
 
51
- - Read the OceanProtocol JobDetails from the environment variables and use default file paths.
52
- - Generate a random integer.
53
- - Store the result in a "result.txt" file within the default outputs path.
59
+ - Read the OceanProtocol JobDetails from the environment variables and use default configuration file paths.
60
+ - Execute the run function.
61
+ - Execute the default saving function, storing the result in a "result.txt" file within the default outputs path.
54
62
 
55
63
  ### Tuning
56
64
 
57
65
  #### Application Config
58
66
 
59
- The application configuration can be tweaked by passing a Config instance to its' constructor.
67
+ The application configuration can be tweaked by passing a Config instance to its constructor.
60
68
 
61
69
  ```python
62
- Algorithm(
70
+ from ocean_runner import Algorithm, Config
71
+
72
+ algorithm = Algorithm(
63
73
  Config(
64
74
  custom_input: ... # dataclass
65
75
  # Custom algorithm parameters dataclass.
66
76
 
67
- error_callback: ... # Callable[[Exception], None]
68
- # Callback to run on exceptions.
69
-
70
77
  logger: ... # type: logging.Logger
71
78
  # Custom logger to use.
72
79
 
@@ -82,6 +89,8 @@ Algorithm(
82
89
  ```python
83
90
  import logging
84
91
 
92
+ from ocean_runner import Algorithm, Config
93
+
85
94
 
86
95
  @dataclass
87
96
  class CustomInput:
@@ -91,19 +100,13 @@ class CustomInput:
91
100
  logger = logging.getLogger(__name__)
92
101
 
93
102
 
94
- Algorithm(
103
+ algorithm = Algorithm(
95
104
  Config(
96
105
  custom_input: CustomInput,
97
106
  """
98
107
  Load the Algorithm's Custom Input into a CustomInput dataclass instance.
99
108
  """
100
109
 
101
- error_callback: lambda ex: logger.exception(ex),
102
- """
103
- Run this callback when an exception is caught
104
- NOTE: it's not recommended to catch exceptions this way. Should re-raise and halt the execution.
105
- """
106
-
107
110
  source_paths: [Path("/algorithm/src")],
108
111
  """
109
112
  Source paths to include in the PATH. '/algorithm/src' is the default since our templates place the algorithm source files there.
@@ -143,44 +146,72 @@ Algorithm(
143
146
 
144
147
  ```
145
148
 
146
- ## Default behaviours
149
+ #### Behaviour Config
147
150
 
148
- ### Default implementations
149
-
150
- As seen in the minimal example, all methods implemented in `Algorithm` have a default implementation which will be commented here.
151
+ To fully configure the behaviour of the algorithm as in the [Minimal Example](#minimal-example), you can do it decorating your defined function as in the following example, which features all the possible algorithm customization.
151
152
 
152
153
  ```python
154
+ from pathlib import Path
153
155
 
154
- (
155
- Algorithm()
156
-
157
- """
158
- Default constructor, will use default values of Config.
159
- """
160
-
161
- .validate()
162
-
163
- """
164
- Will validate the algorithm's job detail instance, checking for the existence of:
165
- - `job_details.ddos`
166
- - `job_details.files`
167
- """
156
+ import pandas as pd
157
+ from ocean_runner import Algorithm
168
158
 
169
- .run()
159
+ algorithm = Algorithm()
170
160
 
171
- """
172
- Has NO default implementation, must pass a callback that returns a result of any type.
173
- """
174
161
 
175
- .save_results()
162
+ @algorithm.on_error
163
+ def error_callback(ex: Exception):
164
+ algorithm.logger.exception(ex)
165
+ raise algorithm.Error() from ex
176
166
 
177
- """
178
- Stores the result of running the algorithm in "outputs/results.txt"
179
- """
180
167
 
181
- )
168
+ @algorithm.validate
169
+ def val():
170
+ assert algorithm.job_details.files, "Empty input dir"
171
+
172
+
173
+ @algorithm.run
174
+ def run() -> pd.DataFrame:
175
+ _, filename = next(algorithm.job_details.next_path())
176
+ return pd.read_csv(filename).describe(include="all")
177
+
178
+
179
+ @algorithm.save_results
180
+ def save(results: pd.DataFrame, path: Path):
181
+ algorithm.logger.info(f"Descriptive statistics: {results}")
182
+ results.to_csv(path / "results.csv")
183
+
184
+
185
+ if __name__ == "__main__":
186
+ algorithm()
187
+ ```
188
+
189
+
190
+
191
+ ### Default implementations
192
+
193
+ As seen in the minimal example, all methods implemented in `Algorithm` have a default implementation which will be commented here.
194
+
195
+ ```python
196
+ .validate()
197
+
198
+ """
199
+ Will validate the algorithm's job detail instance, checking for the existence of:
200
+ - `job_details.ddos`
201
+ - `job_details.files`
202
+ """
203
+
204
+ .run()
205
+
206
+ """
207
+ Has NO default implementation, must pass a callback that returns a result of any type.
208
+ """
182
209
 
210
+ .save_results()
183
211
 
212
+ """
213
+ Stores the result of running the algorithm in "outputs/results.txt"
214
+ """
184
215
  ```
185
216
 
186
217
  ### Job Details
@@ -188,7 +219,7 @@ As seen in the minimal example, all methods implemented in `Algorithm` have a de
188
219
  To load the OceanProtocol JobDetails instance, the program will read some environment variables, they can be mocked passing an instance of `Environment` through the configuration of the algorithm.
189
220
 
190
221
  Environment variables:
191
- - `DIDS` Input dataset(s) DID's, must have format: `["abc..90"]`
192
- - `TRANSFORMATION_DID` Algorithm DID, must have format: `abc..90`
193
- - `SECRET` Algorithm secret.
222
+ - `DIDS` (optional) Input dataset(s) DID's, must have format: `["abc..90"]`. Defaults to reading them automatically from the `DDO` data directory.
223
+ - `TRANSFORMATION_DID` (optional, default="DEFAULT"): Algorithm DID, must have format: `abc..90`.
224
+ - `SECRET` (optional, default="DEFAULT"): Algorithm secret.
194
225
  - `BASE_DIR` (optional, default="/data"): Base path to the OceanProtocol data directories.
@@ -0,0 +1,7 @@
1
+ ocean_runner/__init__.py,sha256=awAmE6kZhuwcrD3gT7qFZArdhiuzW-EFTA6tGKhw06k,138
2
+ ocean_runner/config.py,sha256=gyyUotPJ7n8wPPdsJZIBUT4zBlkoNbhV876JDTdPNsY,1398
3
+ ocean_runner/runner.py,sha256=mPxnJCP-XYl0akRAI4HdAku0KlsTCrXTVPCwlQj5JoY,5721
4
+ ocean_runner-0.2.16.dist-info/METADATA,sha256=s4MrShZfoQzbWIXZRV06Rt0S4lhqYuRjK_OG9QKJoKg,6562
5
+ ocean_runner-0.2.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ ocean_runner-0.2.16.dist-info/licenses/LICENSE,sha256=_B25KqK4amoADWkMN150tnZFm_Fy7VvZpvIC8ZydWdI,1053
7
+ ocean_runner-0.2.16.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- ocean_runner/__init__.py,sha256=awAmE6kZhuwcrD3gT7qFZArdhiuzW-EFTA6tGKhw06k,138
2
- ocean_runner/config.py,sha256=gyyUotPJ7n8wPPdsJZIBUT4zBlkoNbhV876JDTdPNsY,1398
3
- ocean_runner/runner.py,sha256=AM4GlgpGGOSLa_TfO8rAdWmTGTPTZoTT84LNtUswTXw,5762
4
- ocean_runner-0.2.14.dist-info/METADATA,sha256=bIdyxazZ4mWCOUW7JULJaykDgDCd03yZ91CWG4BbsT8,5919
5
- ocean_runner-0.2.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
- ocean_runner-0.2.14.dist-info/licenses/LICENSE,sha256=_B25KqK4amoADWkMN150tnZFm_Fy7VvZpvIC8ZydWdI,1053
7
- ocean_runner-0.2.14.dist-info/RECORD,,