esd-services-api-client 2.0.8__py3-none-any.whl → 2.0.9__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.
@@ -1 +1 @@
1
- __version__ = '2.0.8'
1
+ __version__ = '2.0.9'
@@ -20,7 +20,7 @@ import socketserver
20
20
  import threading
21
21
  from dataclasses import dataclass
22
22
  from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
23
- from typing import Dict, Optional
23
+ from typing import Dict, Optional, Any
24
24
 
25
25
  import pandas
26
26
  from adapta.metrics import MetricsProvider
@@ -36,6 +36,7 @@ from esd_services_api_client.nexus.configurations.algorithm_configuration import
36
36
  NexusConfiguration,
37
37
  )
38
38
  from esd_services_api_client.nexus.core.app_core import Nexus
39
+ from esd_services_api_client.nexus.abstractions.nexus_object import AlgorithmResult
39
40
  from esd_services_api_client.nexus.algorithms import MinimalisticAlgorithm
40
41
  from esd_services_api_client.nexus.input import InputReader, InputProcessor
41
42
 
@@ -229,8 +230,19 @@ class MyInputProcessor(InputProcessor):
229
230
  "y_ready": inputs["y"].assign(c=[-1, 1]),
230
231
  }
231
232
 
233
+ @dataclass
234
+ class MyResult(AlgorithmResult):
235
+ x: pandas.DataFrame
236
+ y: pandas.DataFrame
237
+
238
+ def dataframe(self) -> pandas.DataFrame:
239
+ return pandas.concat([self.x, self.y])
232
240
 
233
- class MyAlgorithm(MinimalisticAlgorithm[MyAlgorithmPayload, pandas.DataFrame]):
241
+ def to_kwargs(self) -> dict[str, Any]:
242
+ pass
243
+
244
+
245
+ class MyAlgorithm(MinimalisticAlgorithm[MyAlgorithmPayload]):
234
246
  async def _context_open(self):
235
247
  pass
236
248
 
@@ -241,8 +253,8 @@ class MyAlgorithm(MinimalisticAlgorithm[MyAlgorithmPayload, pandas.DataFrame]):
241
253
  def __init__(self, metrics_provider: MetricsProvider, logger_factory: LoggerFactory, input_processor: MyInputProcessor):
242
254
  super().__init__(metrics_provider, logger_factory, input_processor)
243
255
 
244
- async def _run(self, x_ready: pandas.DataFrame, y_ready: pandas.DataFrame, **kwargs) -> pandas.DataFrame:
245
- return pandas.concat([x_ready, y_ready])
256
+ async def _run(self, x_ready: pandas.DataFrame, y_ready: pandas.DataFrame, **kwargs) -> MyResult:
257
+ return MyResult(x_ready, y_ready)
246
258
 
247
259
 
248
260
  async def main():
@@ -20,7 +20,7 @@ import re
20
20
 
21
21
 
22
22
  from abc import ABC, abstractmethod
23
- from typing import Generic, TypeVar
23
+ from typing import Generic, TypeVar, Union, Any
24
24
 
25
25
  import pandas
26
26
  import polars
@@ -29,6 +29,24 @@ from adapta.metrics import MetricsProvider
29
29
  from esd_services_api_client.nexus.abstractions.logger_factory import LoggerFactory
30
30
 
31
31
 
32
+ class AlgorithmResult(ABC):
33
+ """
34
+ Interface for algorithm run result. You can store arbitrary data here, but `dataframe` method must be implemented.
35
+ """
36
+
37
+ @abstractmethod
38
+ def dataframe(self) -> Union[pandas.DataFrame, polars.DataFrame]:
39
+ """
40
+ Returns the main result dataframe. This will be written to the linked output storage.
41
+ """
42
+
43
+ @abstractmethod
44
+ def to_kwargs(self) -> dict[str, Any]:
45
+ """
46
+ Convert result to kwargs for the next iteration (for recursive algorithms)
47
+ """
48
+
49
+
32
50
  TPayload = TypeVar("TPayload") # pylint: disable=C0103
33
51
  TResult = TypeVar( # pylint: disable=C0103
34
52
  "TResult", pandas.DataFrame, polars.DataFrame
@@ -20,3 +20,4 @@
20
20
  from esd_services_api_client.nexus.algorithms.minimalistic import *
21
21
  from esd_services_api_client.nexus.algorithms.recursive import *
22
22
  from esd_services_api_client.nexus.algorithms.distributed import *
23
+ from esd_services_api_client.nexus.algorithms._baseline_algorithm import *
@@ -28,12 +28,13 @@ from esd_services_api_client.nexus.abstractions.nexus_object import (
28
28
  NexusObject,
29
29
  TPayload,
30
30
  TResult,
31
+ AlgorithmResult,
31
32
  )
32
33
  from esd_services_api_client.nexus.abstractions.logger_factory import LoggerFactory
33
34
  from esd_services_api_client.nexus.input.input_processor import InputProcessor
34
35
 
35
36
 
36
- class BaselineAlgorithm(NexusObject[TPayload, TResult]):
37
+ class BaselineAlgorithm(NexusObject[TPayload, AlgorithmResult]):
37
38
  """
38
39
  Base class for all algorithm implementations.
39
40
  """
@@ -48,17 +49,19 @@ class BaselineAlgorithm(NexusObject[TPayload, TResult]):
48
49
  self._input_processors = input_processors
49
50
 
50
51
  @abstractmethod
51
- async def _run(self, **kwargs) -> TResult:
52
+ async def _run(self, **kwargs) -> AlgorithmResult:
52
53
  """
53
54
  Core logic for this algorithm. Implementing this method is mandatory.
54
55
  """
55
56
 
56
- async def run(self, **kwargs) -> TResult:
57
+ async def run(self, **kwargs) -> AlgorithmResult:
57
58
  """
58
59
  Coroutine that executes the algorithm logic.
59
60
  """
60
61
 
61
- async def _process(processor: InputProcessor) -> dict[str, TResult]:
62
+ async def _process(
63
+ processor: InputProcessor[TPayload, TResult]
64
+ ) -> dict[str, TResult]:
62
65
  async with processor as instance:
63
66
  return await instance.process_input(**kwargs)
64
67
 
@@ -21,13 +21,16 @@
21
21
  import asyncio
22
22
  from abc import ABC, abstractmethod
23
23
 
24
- from esd_services_api_client.nexus.abstractions.nexus_object import TResult, TPayload
24
+ from esd_services_api_client.nexus.abstractions.nexus_object import (
25
+ TPayload,
26
+ AlgorithmResult,
27
+ )
25
28
  from esd_services_api_client.nexus.algorithms._baseline_algorithm import (
26
29
  BaselineAlgorithm,
27
30
  )
28
31
 
29
32
 
30
- class DistributedAlgorithm(BaselineAlgorithm[TPayload, TResult], ABC):
33
+ class DistributedAlgorithm(BaselineAlgorithm[TPayload], ABC):
31
34
  """
32
35
  Distributed algorithm base class.
33
36
  """
@@ -39,12 +42,12 @@ class DistributedAlgorithm(BaselineAlgorithm[TPayload, TResult], ABC):
39
42
  """
40
43
 
41
44
  @abstractmethod
42
- async def _fold(self, *split_tasks: asyncio.Task) -> TResult:
45
+ async def _fold(self, *split_tasks: asyncio.Task) -> AlgorithmResult:
43
46
  """
44
47
  Sub-problem result aggregator.
45
48
  """
46
49
 
47
- async def _run(self, **kwargs) -> TResult:
50
+ async def _run(self, **kwargs) -> AlgorithmResult:
48
51
  splits = await self._split(**kwargs)
49
52
  tasks = [asyncio.create_task(split.run(**kwargs)) for split in splits]
50
53
 
@@ -23,14 +23,14 @@ from adapta.metrics import MetricsProvider
23
23
  from injector import inject
24
24
 
25
25
  from esd_services_api_client.nexus.abstractions.logger_factory import LoggerFactory
26
- from esd_services_api_client.nexus.abstractions.nexus_object import TResult, TPayload
26
+ from esd_services_api_client.nexus.abstractions.nexus_object import TPayload
27
27
  from esd_services_api_client.nexus.algorithms._baseline_algorithm import (
28
28
  BaselineAlgorithm,
29
29
  )
30
30
  from esd_services_api_client.nexus.input import InputProcessor
31
31
 
32
32
 
33
- class MinimalisticAlgorithm(BaselineAlgorithm[TPayload, TResult], ABC):
33
+ class MinimalisticAlgorithm(BaselineAlgorithm[TPayload], ABC):
34
34
  """
35
35
  Simple algorithm base class.
36
36
  """
@@ -24,14 +24,17 @@ from adapta.metrics import MetricsProvider
24
24
  from injector import inject
25
25
 
26
26
  from esd_services_api_client.nexus.abstractions.logger_factory import LoggerFactory
27
- from esd_services_api_client.nexus.abstractions.nexus_object import TResult, TPayload
27
+ from esd_services_api_client.nexus.abstractions.nexus_object import (
28
+ TPayload,
29
+ AlgorithmResult,
30
+ )
28
31
  from esd_services_api_client.nexus.algorithms._baseline_algorithm import (
29
32
  BaselineAlgorithm,
30
33
  )
31
34
  from esd_services_api_client.nexus.input import InputProcessor
32
35
 
33
36
 
34
- class RecursiveAlgorithm(BaselineAlgorithm[TPayload, TResult]):
37
+ class RecursiveAlgorithm(BaselineAlgorithm[TPayload]):
35
38
  """
36
39
  Recursive algorithm base class.
37
40
  """
@@ -49,8 +52,8 @@ class RecursiveAlgorithm(BaselineAlgorithm[TPayload, TResult]):
49
52
  async def _is_finished(self, **kwargs) -> bool:
50
53
  """ """
51
54
 
52
- async def run(self, **kwargs) -> TResult:
55
+ async def run(self, **kwargs) -> AlgorithmResult:
53
56
  result = await self._run(**kwargs)
54
- if self._is_finished(**result):
57
+ if self._is_finished(**result.to_kwargs()):
55
58
  return result
56
- return await self.run(**result)
59
+ return await self.run(**result.to_kwargs())
@@ -33,8 +33,6 @@ from adapta.storage.blob.base import StorageClient
33
33
  from adapta.storage.models.format import DataFrameJsonSerializationFormat
34
34
  from injector import Injector
35
35
 
36
- from pandas import DataFrame as PandasDataFrame
37
-
38
36
  import esd_services_api_client.nexus.exceptions
39
37
  from esd_services_api_client.crystal import (
40
38
  add_crystal_args,
@@ -43,7 +41,8 @@ from esd_services_api_client.crystal import (
43
41
  AlgorithmRunResult,
44
42
  CrystalEntrypointArguments,
45
43
  )
46
- from esd_services_api_client.nexus.algorithms._baseline_algorithm import (
44
+ from esd_services_api_client.nexus.abstractions.nexus_object import AlgorithmResult
45
+ from esd_services_api_client.nexus.algorithms import (
47
46
  BaselineAlgorithm,
48
47
  )
49
48
  from esd_services_api_client.nexus.configurations.algorithm_configuration import (
@@ -181,7 +180,7 @@ class Nexus:
181
180
 
182
181
  async def _submit_result(
183
182
  self,
184
- result: Optional[PandasDataFrame] = None,
183
+ result: Optional[AlgorithmResult] = None,
185
184
  ex: Optional[BaseException] = None,
186
185
  ) -> None:
187
186
  @backoff.on_exception(
@@ -193,7 +192,7 @@ class Nexus:
193
192
  max_time=10,
194
193
  raise_on_giveup=True,
195
194
  )
196
- def save_result(data: PandasDataFrame) -> str:
195
+ def save_result(data: AlgorithmResult) -> str:
197
196
  """
198
197
  Saves blob and returns the uri
199
198
 
@@ -209,7 +208,7 @@ class Nexus:
209
208
  data_path=output_path, alias="output", data_format="null"
210
209
  ).parse_data_path()
211
210
  storage_client.save_data_as_blob(
212
- data=data,
211
+ data=data.dataframe(),
213
212
  blob_path=blob_path,
214
213
  serialization_format=DataFrameJsonSerializationFormat,
215
214
  overwrite=True,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: esd-services-api-client
3
- Version: 2.0.8
3
+ Version: 2.0.9
4
4
  Summary: Python clients for ESD services
5
5
  Home-page: https://github.com/SneaksAndData/esd-services-api-client
6
6
  License: Apache 2.0
@@ -1,5 +1,5 @@
1
1
  esd_services_api_client/__init__.py,sha256=rP0njtEgVSMm-sOVayVfcRUrrubl4lme7HI2zS678Lo,598
2
- esd_services_api_client/_version.py,sha256=ImzYQIMT0WJBqsWPWEXvp24h0GJq6HfzSgGSEEuoxcs,22
2
+ esd_services_api_client/_version.py,sha256=YHfSoqxCUyNphrTJsW3Ed3e2IVM5_H1IYKii1J5IND4,22
3
3
  esd_services_api_client/beast/__init__.py,sha256=NTaz_7YoLPK8MCLwbwqH7rW1zDWLxXu2T7fGmMmRxyg,718
4
4
  esd_services_api_client/beast/v3/__init__.py,sha256=TRjB4-T6eIORpMvdylb32_GinrIpYNFmAdshSC1HqHg,749
5
5
  esd_services_api_client/beast/v3/_connector.py,sha256=oPizDQ1KOKOfiyh-jAofKodlpRzrRiELv-rmP_o_oio,11473
@@ -15,21 +15,21 @@ esd_services_api_client/crystal/__init__.py,sha256=afSGQRkDic0ECsJfgu3b291kX8CyU
15
15
  esd_services_api_client/crystal/_api_versions.py,sha256=2BMiQRS0D8IEpWCCys3dge5alVBRCZrOuCR1QAn8UIM,832
16
16
  esd_services_api_client/crystal/_connector.py,sha256=WjfMezWXia41Z8aiNupaT577fk9Sx6uy6V23O6y9hfI,12870
17
17
  esd_services_api_client/crystal/_models.py,sha256=eRhGAl8LjglCyIFwf1bcFBhjbpSuRYucuF2LO388L2E,4025
18
- esd_services_api_client/nexus/README.md,sha256=e3rqD2023wFGoumhXU2q68QLwbJEVbODAwznQ6e9VO4,8381
18
+ esd_services_api_client/nexus/README.md,sha256=Q3laWkuCxqVBFsfP58mGAys-jVZeesroIRRMiaQMntc,8688
19
19
  esd_services_api_client/nexus/__init__.py,sha256=e7RPs-qJNQqDHj121TeYx-_YadZSOIyJuAPyhSSXRsE,622
20
20
  esd_services_api_client/nexus/abstractions/__init__.py,sha256=e7RPs-qJNQqDHj121TeYx-_YadZSOIyJuAPyhSSXRsE,622
21
21
  esd_services_api_client/nexus/abstractions/logger_factory.py,sha256=jw1xnrU2dEWSUhqNut4RzjRPZFmeNx6czOU_8-q4kuo,2014
22
- esd_services_api_client/nexus/abstractions/nexus_object.py,sha256=FucI7cHhOObJs0N9d3bBNR5J5cWv3Trfak4AKPBh1jE,2202
22
+ esd_services_api_client/nexus/abstractions/nexus_object.py,sha256=Y2jwpSa0cLyMtGxOSEpg3F8evvSMxYHx5t5KD92KotE,2759
23
23
  esd_services_api_client/nexus/abstractions/socket_provider.py,sha256=Mv9BWdxw8VY4Gi4EOrdxWK1zsR3-fqIbpyF1xHWchbE,1495
24
- esd_services_api_client/nexus/algorithms/__init__.py,sha256=uWX24NHUnUcnOJN2IIp1kaaozCC0rOmB36WxHBCapCY,823
25
- esd_services_api_client/nexus/algorithms/_baseline_algorithm.py,sha256=oQPEMFfWVYIYIyDzL5Trev9KMtIMapjkHGwdIUGTNPU,2350
26
- esd_services_api_client/nexus/algorithms/distributed.py,sha256=HM_uGr2V4tvRnDOn8Cd44IfnjcMDr1fwWlPEhQbtDM0,1669
27
- esd_services_api_client/nexus/algorithms/minimalistic.py,sha256=HMemgm6Ogp8DW6HDrkMQZQikrE0ogUSCVVimTsAUos8,1475
28
- esd_services_api_client/nexus/algorithms/recursive.py,sha256=wfhoiZ9D_NJFRGHd7gDVo4Kq1wrqKKPX6w8_l_YnPlg,1813
24
+ esd_services_api_client/nexus/algorithms/__init__.py,sha256=ySnLfuYuxi28EaqT18oW2Ka50ZR7WOvJlLhmIts-Xgw,898
25
+ esd_services_api_client/nexus/algorithms/_baseline_algorithm.py,sha256=_3QHWmBDnfByEJTftf4jKzje5GNqftb0_aCfp-8ksCU,2436
26
+ esd_services_api_client/nexus/algorithms/distributed.py,sha256=kZS4InM4GoT4T6UrXRnfoDn4zxE2iGuqLvxBrzBetZc,1697
27
+ esd_services_api_client/nexus/algorithms/minimalistic.py,sha256=DOU52Me_W0luUPWmIRBFkJdfapyEkPqVbbvy4V5yQZ8,1457
28
+ esd_services_api_client/nexus/algorithms/recursive.py,sha256=r4_LIlC_hhIBSrKtL99xE9md3SahctF3R3GT1tIwlg4,1857
29
29
  esd_services_api_client/nexus/configurations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  esd_services_api_client/nexus/configurations/algorithm_configuration.py,sha256=sg3ul-Vqd39li42cfMsdWtFJIBNfQ52XLmqKO2sryDg,1086
31
31
  esd_services_api_client/nexus/core/__init__.py,sha256=e7RPs-qJNQqDHj121TeYx-_YadZSOIyJuAPyhSSXRsE,622
32
- esd_services_api_client/nexus/core/app_core.py,sha256=7cT6ZEzKzq3lfio6YNxREpTTeXt1wjhHUOXxaezuFiQ,9393
32
+ esd_services_api_client/nexus/core/app_core.py,sha256=XvPWnr6wJckjNoM4vWg3CYBnrJOaWZFxiIil1sK-qNc,9420
33
33
  esd_services_api_client/nexus/core/app_dependencies.py,sha256=rIk6R-InJeF1P0DC4bhj4kJTNNxYg39Vhuz8AXfV6pk,6140
34
34
  esd_services_api_client/nexus/exceptions/__init__.py,sha256=JgPXhrvBIi0U1QOF90TYHS8jv_SBQEoRLsEg6rrtRoc,691
35
35
  esd_services_api_client/nexus/exceptions/_nexus_error.py,sha256=b3L8JnNvV2jdxNfuFWh9-j4kVb_VX7gNH5WHKcC-R78,890
@@ -40,7 +40,7 @@ esd_services_api_client/nexus/input/_functions.py,sha256=SonIImDN9Eiw_Eb2tKXXtLt
40
40
  esd_services_api_client/nexus/input/input_processor.py,sha256=lRtxrvxGXXmDWHsg4mTWCgM8ecu4kroMDqC3UQMGKYk,1827
41
41
  esd_services_api_client/nexus/input/input_reader.py,sha256=zVv_qYmf-kHfPmyo_mYyPO6HFk-lX8dItLkHtUGYxZQ,3092
42
42
  esd_services_api_client/nexus/input/payload_reader.py,sha256=__r_QjIFRAWwx56X5WUK1qensJUae0vZEb422dzOgSY,2511
43
- esd_services_api_client-2.0.8.dist-info/LICENSE,sha256=0gS6zXsPp8qZhzi1xaGCIYPzb_0e8on7HCeFJe8fOpw,10693
44
- esd_services_api_client-2.0.8.dist-info/METADATA,sha256=MzH3xRJfXQE7aZW3sf7ajjLGc4zH7sqGgVkcnEHNCv4,1332
45
- esd_services_api_client-2.0.8.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
46
- esd_services_api_client-2.0.8.dist-info/RECORD,,
43
+ esd_services_api_client-2.0.9.dist-info/LICENSE,sha256=0gS6zXsPp8qZhzi1xaGCIYPzb_0e8on7HCeFJe8fOpw,10693
44
+ esd_services_api_client-2.0.9.dist-info/METADATA,sha256=8wldbRYSsxJWGT8P_Lkl_sIvq9nrf9qt6e5O7xhoRWQ,1332
45
+ esd_services_api_client-2.0.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
46
+ esd_services_api_client-2.0.9.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.8.1
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any