runnable 0.12.3__py3-none-any.whl → 0.14.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. runnable/__init__.py +0 -11
  2. runnable/catalog.py +27 -5
  3. runnable/cli.py +122 -26
  4. runnable/datastore.py +71 -35
  5. runnable/defaults.py +0 -1
  6. runnable/entrypoints.py +107 -32
  7. runnable/exceptions.py +6 -2
  8. runnable/executor.py +28 -9
  9. runnable/graph.py +37 -12
  10. runnable/integration.py +7 -2
  11. runnable/nodes.py +15 -17
  12. runnable/parameters.py +27 -8
  13. runnable/pickler.py +1 -1
  14. runnable/sdk.py +101 -33
  15. runnable/secrets.py +3 -1
  16. runnable/tasks.py +246 -34
  17. runnable/utils.py +41 -13
  18. {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info}/METADATA +25 -31
  19. runnable-0.14.0.dist-info/RECORD +24 -0
  20. {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info}/WHEEL +1 -1
  21. runnable-0.14.0.dist-info/entry_points.txt +40 -0
  22. runnable/extensions/__init__.py +0 -0
  23. runnable/extensions/catalog/__init__.py +0 -21
  24. runnable/extensions/catalog/file_system/__init__.py +0 -0
  25. runnable/extensions/catalog/file_system/implementation.py +0 -234
  26. runnable/extensions/catalog/k8s_pvc/__init__.py +0 -0
  27. runnable/extensions/catalog/k8s_pvc/implementation.py +0 -16
  28. runnable/extensions/catalog/k8s_pvc/integration.py +0 -59
  29. runnable/extensions/executor/__init__.py +0 -649
  30. runnable/extensions/executor/argo/__init__.py +0 -0
  31. runnable/extensions/executor/argo/implementation.py +0 -1194
  32. runnable/extensions/executor/argo/specification.yaml +0 -51
  33. runnable/extensions/executor/k8s_job/__init__.py +0 -0
  34. runnable/extensions/executor/k8s_job/implementation_FF.py +0 -259
  35. runnable/extensions/executor/k8s_job/integration_FF.py +0 -69
  36. runnable/extensions/executor/local/__init__.py +0 -0
  37. runnable/extensions/executor/local/implementation.py +0 -71
  38. runnable/extensions/executor/local_container/__init__.py +0 -0
  39. runnable/extensions/executor/local_container/implementation.py +0 -446
  40. runnable/extensions/executor/mocked/__init__.py +0 -0
  41. runnable/extensions/executor/mocked/implementation.py +0 -154
  42. runnable/extensions/executor/retry/__init__.py +0 -0
  43. runnable/extensions/executor/retry/implementation.py +0 -168
  44. runnable/extensions/nodes.py +0 -855
  45. runnable/extensions/run_log_store/__init__.py +0 -0
  46. runnable/extensions/run_log_store/chunked_file_system/__init__.py +0 -0
  47. runnable/extensions/run_log_store/chunked_file_system/implementation.py +0 -111
  48. runnable/extensions/run_log_store/chunked_k8s_pvc/__init__.py +0 -0
  49. runnable/extensions/run_log_store/chunked_k8s_pvc/implementation.py +0 -21
  50. runnable/extensions/run_log_store/chunked_k8s_pvc/integration.py +0 -61
  51. runnable/extensions/run_log_store/db/implementation_FF.py +0 -157
  52. runnable/extensions/run_log_store/db/integration_FF.py +0 -0
  53. runnable/extensions/run_log_store/file_system/__init__.py +0 -0
  54. runnable/extensions/run_log_store/file_system/implementation.py +0 -140
  55. runnable/extensions/run_log_store/generic_chunked.py +0 -557
  56. runnable/extensions/run_log_store/k8s_pvc/__init__.py +0 -0
  57. runnable/extensions/run_log_store/k8s_pvc/implementation.py +0 -21
  58. runnable/extensions/run_log_store/k8s_pvc/integration.py +0 -56
  59. runnable/extensions/secrets/__init__.py +0 -0
  60. runnable/extensions/secrets/dotenv/__init__.py +0 -0
  61. runnable/extensions/secrets/dotenv/implementation.py +0 -100
  62. runnable-0.12.3.dist-info/RECORD +0 -64
  63. runnable-0.12.3.dist-info/entry_points.txt +0 -41
  64. {runnable-0.12.3.dist-info → runnable-0.14.0.dist-info/licenses}/LICENSE +0 -0
runnable/__init__.py CHANGED
@@ -34,14 +34,3 @@ from runnable.sdk import ( # noqa
34
34
 
35
35
  # Needed to disable ploomber telemetry
36
36
  os.environ["PLOOMBER_STATS_ENABLED"] = "false"
37
-
38
- ## TODO: Summary should be a bit better for catalog.
39
- ## If the execution fails, hint them about the retry executor.
40
- # Make the retry executor loose!
41
-
42
- # TODO: Think of model registry as a central place to store models.
43
- # TODO: Implement Sagemaker pipelines as a executor.
44
-
45
-
46
- # TODO: Think of way of generating dag hash without executor configuration
47
- # Try to get a release
runnable/catalog.py CHANGED
@@ -11,6 +11,26 @@ from runnable.datastore import DataCatalog
11
11
  logger = logging.getLogger(defaults.LOGGER_NAME)
12
12
 
13
13
 
14
+ def is_catalog_out_of_sync(
15
+ catalog, synced_catalogs=Optional[List[DataCatalog]]
16
+ ) -> bool:
17
+ """
18
+ Check if the catalog items are out of sync from already cataloged objects.
19
+ If they are, return False.
20
+ If the object does not exist or synced catalog does not exist, return True
21
+ """
22
+ if not synced_catalogs:
23
+ return True # If nothing has been synced in the past
24
+
25
+ for synced_catalog in synced_catalogs:
26
+ if synced_catalog.catalog_relative_path == catalog.catalog_relative_path:
27
+ if synced_catalog.data_hash == catalog.data_hash:
28
+ return False
29
+ return True
30
+
31
+ return True # The object does not exist, sync it
32
+
33
+
14
34
  # --8<-- [start:docs]
15
35
 
16
36
 
@@ -26,8 +46,7 @@ class BaseCatalog(ABC, BaseModel):
26
46
  model_config = ConfigDict(extra="forbid")
27
47
 
28
48
  @abstractmethod
29
- def get_summary(self) -> Dict[str, Any]:
30
- ...
49
+ def get_summary(self) -> Dict[str, Any]: ...
31
50
 
32
51
  @property
33
52
  def _context(self):
@@ -38,7 +57,9 @@ class BaseCatalog(ABC, BaseModel):
38
57
  return defaults.COMPUTE_DATA_FOLDER
39
58
 
40
59
  @abstractmethod
41
- def get(self, name: str, run_id: str, compute_data_folder: str = "", **kwargs) -> List[DataCatalog]:
60
+ def get(
61
+ self, name: str, run_id: str, compute_data_folder: str = "", **kwargs
62
+ ) -> List[DataCatalog]:
42
63
  """
43
64
  Get the catalog item by 'name' for the 'run id' and store it in compute data folder.
44
65
 
@@ -119,7 +140,9 @@ class DoNothingCatalog(BaseCatalog):
119
140
  def get_summary(self) -> Dict[str, Any]:
120
141
  return {}
121
142
 
122
- def get(self, name: str, run_id: str, compute_data_folder: str = "", **kwargs) -> List[DataCatalog]:
143
+ def get(
144
+ self, name: str, run_id: str, compute_data_folder: str = "", **kwargs
145
+ ) -> List[DataCatalog]:
123
146
  """
124
147
  Does nothing
125
148
  """
@@ -145,4 +168,3 @@ class DoNothingCatalog(BaseCatalog):
145
168
  Does nothing
146
169
  """
147
170
  logger.info("Using a do-nothing catalog, doing nothing while sync between runs")
148
- ...
runnable/cli.py CHANGED
@@ -22,9 +22,13 @@ def cli():
22
22
 
23
23
 
24
24
  @cli.command("execute", short_help="Execute/translate a pipeline")
25
- @click.option("-f", "--file", default="pipeline.yaml", help="The pipeline definition file", show_default=True)
25
+ @click.argument("filename")
26
26
  @click.option(
27
- "-c", "--config-file", default=None, help="config file, in yaml, to be used for the run", show_default=True
27
+ "-c",
28
+ "--config-file",
29
+ default=None,
30
+ help="config file, in yaml, to be used for the run",
31
+ show_default=True,
28
32
  )
29
33
  @click.option(
30
34
  "-p",
@@ -41,8 +45,12 @@ def cli():
41
45
  type=click.Choice(["INFO", "DEBUG", "WARNING", "ERROR", "FATAL"]),
42
46
  )
43
47
  @click.option("--tag", default="", help="A tag attached to the run")
44
- @click.option("--run-id", help="An optional run_id, one would be generated if not provided")
45
- def execute(file, config_file, parameters_file, log_level, tag, run_id): # pragma: no cover
48
+ @click.option(
49
+ "--run-id", help="An optional run_id, one would be generated if not provided"
50
+ )
51
+ def execute(
52
+ filename, config_file, parameters_file, log_level, tag, run_id
53
+ ): # pragma: no cover
46
54
  """
47
55
  Execute a pipeline
48
56
 
@@ -64,20 +72,35 @@ def execute(file, config_file, parameters_file, log_level, tag, run_id): # prag
64
72
 
65
73
  entrypoints.execute(
66
74
  configuration_file=config_file,
67
- pipeline_file=file,
75
+ pipeline_file=filename,
68
76
  tag=tag,
69
77
  run_id=run_id,
70
78
  parameters_file=parameters_file,
71
79
  )
72
80
 
73
81
 
74
- @cli.command("execute_single_node", short_help="Internal entry point to execute a single node", hidden=True)
82
+ @cli.command(
83
+ "execute_single_node",
84
+ short_help="Internal entry point to execute a single node",
85
+ hidden=True,
86
+ )
75
87
  @click.argument("run_id")
76
88
  @click.argument("step_name")
77
- @click.option("--map-variable", default="", help="The map variable dictionary in str", show_default=True)
78
- @click.option("-f", "--file", default="", help="The pipeline definition file", show_default=True)
79
89
  @click.option(
80
- "-c", "--config-file", default=None, help="config file, in yaml, to be used for the run", show_default=True
90
+ "--map-variable",
91
+ default="",
92
+ help="The map variable dictionary in str",
93
+ show_default=True,
94
+ )
95
+ @click.option(
96
+ "-f", "--file", default="", help="The pipeline definition file", show_default=True
97
+ )
98
+ @click.option(
99
+ "-c",
100
+ "--config-file",
101
+ default=None,
102
+ help="config file, in yaml, to be used for the run",
103
+ show_default=True,
81
104
  )
82
105
  @click.option(
83
106
  "-p",
@@ -94,7 +117,9 @@ def execute(file, config_file, parameters_file, log_level, tag, run_id): # prag
94
117
  type=click.Choice(["INFO", "DEBUG", "WARNING", "ERROR", "FATAL"]),
95
118
  )
96
119
  @click.option("--tag", default="", help="A tag attached to the run")
97
- def execute_single_node(run_id, step_name, map_variable, file, config_file, parameters_file, log_level, tag):
120
+ def execute_single_node(
121
+ run_id, step_name, map_variable, file, config_file, parameters_file, log_level, tag
122
+ ):
98
123
  """
99
124
  Internal entrypoint for runnable to execute a single node.
100
125
 
@@ -119,7 +144,11 @@ def execute_single_node(run_id, step_name, map_variable, file, config_file, para
119
144
  @click.argument("filename")
120
145
  @click.option("--entrypoint", default=defaults.ENTRYPOINT.USER.value, hidden=True)
121
146
  @click.option(
122
- "-c", "--config-file", default=None, help="config file, in yaml, to be used for the run", show_default=True
147
+ "-c",
148
+ "--config-file",
149
+ default=None,
150
+ help="config file, in yaml, to be used for the run",
151
+ show_default=True,
123
152
  )
124
153
  @click.option(
125
154
  "-p",
@@ -136,10 +165,20 @@ def execute_single_node(run_id, step_name, map_variable, file, config_file, para
136
165
  type=click.Choice(["INFO", "DEBUG", "WARNING", "ERROR", "FATAL"]),
137
166
  )
138
167
  @click.option("--data-folder", "-d", default="data/", help="The catalog data folder")
139
- @click.option("--put-in-catalog", "-put", default=None, multiple=True, help="The data to put from the catalog")
140
- @click.option("--notebook-output-path", default="", help="The output path for the notebook")
168
+ @click.option(
169
+ "--put-in-catalog",
170
+ "-put",
171
+ default=None,
172
+ multiple=True,
173
+ help="The data to put from the catalog",
174
+ )
175
+ @click.option(
176
+ "--notebook-output-path", default="", help="The output path for the notebook"
177
+ )
141
178
  @click.option("--tag", help="A tag attached to the run")
142
- @click.option("--run-id", help="An optional run_id, one would be generated if not provided")
179
+ @click.option(
180
+ "--run-id", help="An optional run_id, one would be generated if not provided"
181
+ )
143
182
  def execute_notebook(
144
183
  filename,
145
184
  entrypoint,
@@ -159,7 +198,10 @@ def execute_notebook(
159
198
  The execution plan is unchained.
160
199
  """
161
200
  logger.setLevel(log_level)
162
- catalog_config = {"compute_data_folder": data_folder, "put": list(put_in_catalog) if put_in_catalog else None}
201
+ catalog_config = {
202
+ "compute_data_folder": data_folder,
203
+ "put": list(put_in_catalog) if put_in_catalog else None,
204
+ }
163
205
  if not filename.endswith(".ipynb"):
164
206
  raise Exception("A notebook should always have ipynb as the extension")
165
207
 
@@ -179,7 +221,11 @@ def execute_notebook(
179
221
  @click.argument("command")
180
222
  @click.option("--entrypoint", default=defaults.ENTRYPOINT.USER.value, hidden=True)
181
223
  @click.option(
182
- "-c", "--config-file", default=None, help="config file, in yaml, to be used for the run", show_default=True
224
+ "-c",
225
+ "--config-file",
226
+ default=None,
227
+ help="config file, in yaml, to be used for the run",
228
+ show_default=True,
183
229
  )
184
230
  @click.option(
185
231
  "-p",
@@ -196,11 +242,27 @@ def execute_notebook(
196
242
  type=click.Choice(["INFO", "DEBUG", "WARNING", "ERROR", "FATAL"]),
197
243
  )
198
244
  @click.option("--data-folder", "-d", default="data/", help="The catalog data folder")
199
- @click.option("--put-in-catalog", "-put", default=None, multiple=True, help="The data to put from the catalog")
245
+ @click.option(
246
+ "--put-in-catalog",
247
+ "-put",
248
+ default=None,
249
+ multiple=True,
250
+ help="The data to put from the catalog",
251
+ )
200
252
  @click.option("--tag", help="A tag attached to the run")
201
- @click.option("--run-id", help="An optional run_id, one would be generated if not provided")
253
+ @click.option(
254
+ "--run-id", help="An optional run_id, one would be generated if not provided"
255
+ )
202
256
  def execute_function(
203
- command, entrypoint, config_file, parameters_file, log_level, data_folder, put_in_catalog, tag, run_id
257
+ command,
258
+ entrypoint,
259
+ config_file,
260
+ parameters_file,
261
+ log_level,
262
+ data_folder,
263
+ put_in_catalog,
264
+ tag,
265
+ run_id,
204
266
  ):
205
267
  """
206
268
  External entry point to execute a python function in isolation.
@@ -209,7 +271,10 @@ def execute_function(
209
271
  The execution plan is unchained.
210
272
  """
211
273
  logger.setLevel(log_level)
212
- catalog_config = {"compute_data_folder": data_folder, "put": list(put_in_catalog) if put_in_catalog else None}
274
+ catalog_config = {
275
+ "compute_data_folder": data_folder,
276
+ "put": list(put_in_catalog) if put_in_catalog else None,
277
+ }
213
278
  entrypoints.execute_function(
214
279
  entrypoint=entrypoint,
215
280
  command=command,
@@ -221,14 +286,35 @@ def execute_function(
221
286
  )
222
287
 
223
288
 
224
- @cli.command("fan", short_help="Internal entry point to fan in or out a composite node", hidden=True)
289
+ @cli.command(
290
+ "fan",
291
+ short_help="Internal entry point to fan in or out a composite node",
292
+ hidden=True,
293
+ )
225
294
  @click.argument("run_id")
226
295
  @click.argument("step_name")
227
- @click.option("-m", "--mode", help="fan in or fan out", required=True, type=click.Choice(["in", "out"]))
228
- @click.option("--map-variable", default="", help="The map variable dictionary in str", show_default=True)
229
- @click.option("-f", "--file", default="", help="The pipeline definition file", show_default=True)
230
296
  @click.option(
231
- "-c", "--config-file", default=None, help="config file, in yaml, to be used for the run", show_default=True
297
+ "-m",
298
+ "--mode",
299
+ help="fan in or fan out",
300
+ required=True,
301
+ type=click.Choice(["in", "out"]),
302
+ )
303
+ @click.option(
304
+ "--map-variable",
305
+ default="",
306
+ help="The map variable dictionary in str",
307
+ show_default=True,
308
+ )
309
+ @click.option(
310
+ "-f", "--file", default="", help="The pipeline definition file", show_default=True
311
+ )
312
+ @click.option(
313
+ "-c",
314
+ "--config-file",
315
+ default=None,
316
+ help="config file, in yaml, to be used for the run",
317
+ show_default=True,
232
318
  )
233
319
  @click.option(
234
320
  "-p",
@@ -245,7 +331,17 @@ def execute_function(
245
331
  type=click.Choice(["INFO", "DEBUG", "WARNING", "ERROR", "FATAL"]),
246
332
  )
247
333
  @click.option("--tag", default="", help="A tag attached to the run")
248
- def fan(run_id, step_name, mode, map_variable, file, config_file, parameters_file, log_level, tag):
334
+ def fan(
335
+ run_id,
336
+ step_name,
337
+ mode,
338
+ map_variable,
339
+ file,
340
+ config_file,
341
+ parameters_file,
342
+ log_level,
343
+ tag,
344
+ ):
249
345
  """
250
346
  Internal entrypoint for runnable to fan in or out a composite node.
251
347
 
runnable/datastore.py CHANGED
@@ -18,7 +18,6 @@ from typing import (
18
18
 
19
19
  from pydantic import BaseModel, Field, computed_field
20
20
 
21
- import runnable.context as context
22
21
  from runnable import defaults, exceptions
23
22
 
24
23
  logger = logging.getLogger(defaults.LOGGER_NAME)
@@ -56,14 +55,11 @@ class DataCatalog(BaseModel, extra="allow"):
56
55
  return other.name == self.name
57
56
 
58
57
 
59
- """
60
- The theory behind reduced:
61
- parameters returned by steps in map node are only reduced by the end of the map step, fan-in.
62
- If they are accessed within the map step, the value should be the value returned by the step in the map step.
63
-
64
- Once the map state is complete, we can set the reduce to true and have the value as
65
- the reduced value. Its either a list or a custom function return.
66
- """
58
+ # The theory behind reduced:
59
+ # parameters returned by steps in map node are only reduced by the end of the map step, fan-in.
60
+ # If they are accessed within the map step, the value should be the value returned by the step in the map step.
61
+ # Once the map state is complete, we can set the reduce to true and have the value as
62
+ # the reduced value. Its either a list or a custom function return.
67
63
 
68
64
 
69
65
  class JsonParameter(BaseModel):
@@ -125,7 +121,9 @@ class ObjectParameter(BaseModel):
125
121
  os.remove(self.file_name) # Remove after loading
126
122
 
127
123
 
128
- Parameter = Annotated[Union[JsonParameter, ObjectParameter, MetricParameter], Field(discriminator="kind")]
124
+ Parameter = Annotated[
125
+ Union[JsonParameter, ObjectParameter, MetricParameter], Field(discriminator="kind")
126
+ ]
129
127
 
130
128
 
131
129
  class StepAttempt(BaseModel):
@@ -157,8 +155,12 @@ class CodeIdentity(BaseModel, extra="allow"):
157
155
 
158
156
  code_identifier: Optional[str] = "" # GIT sha code or docker image id
159
157
  code_identifier_type: Optional[str] = "" # git or docker
160
- code_identifier_dependable: Optional[bool] = False # If git, checks if the tree is clean.
161
- code_identifier_url: Optional[str] = "" # The git remote url or docker repository url
158
+ code_identifier_dependable: Optional[bool] = (
159
+ False # If git, checks if the tree is clean.
160
+ )
161
+ code_identifier_url: Optional[str] = (
162
+ "" # The git remote url or docker repository url
163
+ )
162
164
  code_identifier_message: Optional[str] = "" # Any optional message
163
165
 
164
166
 
@@ -185,18 +187,28 @@ class StepLog(BaseModel):
185
187
  summary: Dict[str, Any] = {}
186
188
 
187
189
  summary["Name"] = self.internal_name
188
- summary["Input catalog content"] = [dc.name for dc in self.data_catalog if dc.stage == "get"]
190
+ summary["Input catalog content"] = [
191
+ dc.name for dc in self.data_catalog if dc.stage == "get"
192
+ ]
189
193
  summary["Available parameters"] = [
190
- (p, v.description) for attempt in self.attempts for p, v in attempt.input_parameters.items()
194
+ (p, v.description)
195
+ for attempt in self.attempts
196
+ for p, v in attempt.input_parameters.items()
191
197
  ]
192
198
 
193
- summary["Output catalog content"] = [dc.name for dc in self.data_catalog if dc.stage == "put"]
199
+ summary["Output catalog content"] = [
200
+ dc.name for dc in self.data_catalog if dc.stage == "put"
201
+ ]
194
202
  summary["Output parameters"] = [
195
- (p, v.description) for attempt in self.attempts for p, v in attempt.output_parameters.items()
203
+ (p, v.description)
204
+ for attempt in self.attempts
205
+ for p, v in attempt.output_parameters.items()
196
206
  ]
197
207
 
198
208
  summary["Metrics"] = [
199
- (p, v.description) for attempt in self.attempts for p, v in attempt.user_defined_metrics.items()
209
+ (p, v.description)
210
+ for attempt in self.attempts
211
+ for p, v in attempt.user_defined_metrics.items()
200
212
  ]
201
213
 
202
214
  cis = []
@@ -312,10 +324,18 @@ class RunLog(BaseModel):
312
324
  summary["Catalog Location"] = _context.catalog_handler.get_summary()
313
325
  summary["Full Run log present at: "] = _context.run_log_store.get_summary()
314
326
 
315
- run_log = _context.run_log_store.get_run_log_by_id(run_id=_context.run_id, full=True)
327
+ run_log = _context.run_log_store.get_run_log_by_id(
328
+ run_id=_context.run_id, full=True
329
+ )
316
330
 
317
- summary["Final Parameters"] = {p: v.description for p, v in run_log.parameters.items()}
318
- summary["Collected metrics"] = {p: v.description for p, v in run_log.parameters.items() if v.kind == "metric"}
331
+ summary["Final Parameters"] = {
332
+ p: v.description for p, v in run_log.parameters.items()
333
+ }
334
+ summary["Collected metrics"] = {
335
+ p: v.description
336
+ for p, v in run_log.parameters.items()
337
+ if v.kind == "metric"
338
+ }
319
339
 
320
340
  return summary
321
341
 
@@ -338,7 +358,9 @@ class RunLog(BaseModel):
338
358
 
339
359
  return list(set(data_catalogs))
340
360
 
341
- def search_branch_by_internal_name(self, i_name: str) -> Tuple[Union[BranchLog, RunLog], Union[StepLog, None]]:
361
+ def search_branch_by_internal_name(
362
+ self, i_name: str
363
+ ) -> Tuple[Union[BranchLog, RunLog], Union[StepLog, None]]:
342
364
  """
343
365
  Given a branch internal name, search for it in the run log.
344
366
 
@@ -385,7 +407,9 @@ class RunLog(BaseModel):
385
407
 
386
408
  raise exceptions.BranchLogNotFoundError(self.run_id, i_name)
387
409
 
388
- def search_step_by_internal_name(self, i_name: str) -> Tuple[StepLog, Union[BranchLog, None]]:
410
+ def search_step_by_internal_name(
411
+ self, i_name: str
412
+ ) -> Tuple[StepLog, Union[BranchLog, None]]:
389
413
  """
390
414
  Given a steps internal name, search for the step name.
391
415
 
@@ -415,7 +439,9 @@ class RunLog(BaseModel):
415
439
  # Its odd, so we are in brach name
416
440
  current_branch = current_step.branches[".".join(dot_path[: i + 1])] # type: ignore
417
441
  current_steps = current_branch.steps
418
- logger.debug(f"Finding step log for {i_name} in branch: {current_branch}")
442
+ logger.debug(
443
+ f"Finding step log for {i_name} in branch: {current_branch}"
444
+ )
419
445
  else:
420
446
  # Its even, so we are in step, we start here!
421
447
  current_step = current_steps[".".join(dot_path[: i + 1])]
@@ -428,10 +454,6 @@ class RunLog(BaseModel):
428
454
  raise exceptions.StepLogNotFoundError(self.run_id, i_name)
429
455
 
430
456
 
431
- # All outside modules should interact with dataclasses using the RunLogStore to promote extensibility
432
- # If you want to customize dataclass, extend BaseRunLogStore and implement the methods as per the specification
433
-
434
-
435
457
  class BaseRunLogStore(ABC, BaseModel):
436
458
  """
437
459
  The base class of a Run Log Store with many common methods implemented.
@@ -441,8 +463,7 @@ class BaseRunLogStore(ABC, BaseModel):
441
463
  service_type: str = "run_log_store"
442
464
 
443
465
  @abstractmethod
444
- def get_summary(self) -> Dict[str, Any]:
445
- ...
466
+ def get_summary(self) -> Dict[str, Any]: ...
446
467
 
447
468
  @property
448
469
  def _context(self):
@@ -629,7 +650,9 @@ class BaseRunLogStore(ABC, BaseModel):
629
650
  RunLogNotFoundError: If the run log for run_id is not found in the datastore
630
651
  StepLogNotFoundError: If the step log for internal_name is not found in the datastore for run_id
631
652
  """
632
- logger.info(f"{self.service_name} Getting the step log: {internal_name} of {run_id}")
653
+ logger.info(
654
+ f"{self.service_name} Getting the step log: {internal_name} of {run_id}"
655
+ )
633
656
  run_log = self.get_run_log_by_id(run_id=run_id)
634
657
  step_log, _ = run_log.search_step_by_internal_name(internal_name)
635
658
  return step_log
@@ -675,10 +698,14 @@ class BaseRunLogStore(ABC, BaseModel):
675
698
  BranchLog: Uncommitted and initialized with defaults BranchLog object
676
699
  """
677
700
  # Create a new BranchLog
678
- logger.info(f"{self.service_name} Creating a Branch Log : {internal_branch_name}")
701
+ logger.info(
702
+ f"{self.service_name} Creating a Branch Log : {internal_branch_name}"
703
+ )
679
704
  return BranchLog(internal_name=internal_branch_name, status=defaults.CREATED)
680
705
 
681
- def get_branch_log(self, internal_branch_name: str, run_id: str, **kwargs) -> Union[BranchLog, RunLog]:
706
+ def get_branch_log(
707
+ self, internal_branch_name: str, run_id: str, **kwargs
708
+ ) -> Union[BranchLog, RunLog]:
682
709
  """
683
710
  Returns the branch log by the internal branch name for the run id
684
711
 
@@ -697,7 +724,9 @@ class BaseRunLogStore(ABC, BaseModel):
697
724
  branch, _ = run_log.search_branch_by_internal_name(internal_branch_name)
698
725
  return branch
699
726
 
700
- def add_branch_log(self, branch_log: Union[BranchLog, RunLog], run_id: str, **kwargs):
727
+ def add_branch_log(
728
+ self, branch_log: Union[BranchLog, RunLog], run_id: str, **kwargs
729
+ ):
701
730
  """
702
731
  The method should:
703
732
  # Get the run log
@@ -775,7 +804,9 @@ class BufferRunLogstore(BaseRunLogStore):
775
804
  """
776
805
 
777
806
  service_name: str = "buffered"
778
- run_log: Optional[RunLog] = Field(default=None, exclude=True) # For a buffered Run Log, this is the database
807
+ run_log: Optional[RunLog] = Field(
808
+ default=None, exclude=True
809
+ ) # For a buffered Run Log, this is the database
779
810
 
780
811
  def get_summary(self) -> Dict[str, Any]:
781
812
  summary = {"Type": self.service_name, "Location": "Not persisted"}
@@ -826,5 +857,10 @@ class BufferRunLogstore(BaseRunLogStore):
826
857
  # Puts the run log in the db
827
858
  # Raises Exception if not found
828
859
  """
829
- logger.info(f"{self.service_name} Putting the run log in the DB: {run_log.run_id}")
860
+ logger.info(
861
+ f"{self.service_name} Putting the run log in the DB: {run_log.run_id}"
862
+ )
830
863
  self.run_log = run_log
864
+
865
+
866
+ import runnable.context as context # noqa: F401, E402
runnable/defaults.py CHANGED
@@ -33,7 +33,6 @@ class RunnableConfig(TypedDict, total=False):
33
33
  secrets: Optional[ServiceConfig]
34
34
  catalog: Optional[ServiceConfig]
35
35
  executor: Optional[ServiceConfig]
36
- experiment_tracker: Optional[ServiceConfig]
37
36
  pickler: Optional[ServiceConfig]
38
37
 
39
38