wizata-dsapi 1.3.40__tar.gz → 1.3.42__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.
Files changed (54) hide show
  1. {wizata_dsapi-1.3.40/wizata_dsapi.egg-info → wizata_dsapi-1.3.42}/PKG-INFO +1 -1
  2. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/api_dto.py +6 -0
  3. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/mlmodel.py +52 -5
  4. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/pipeline.py +23 -3
  5. wizata_dsapi-1.3.42/wizata_dsapi/version.py +1 -0
  6. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/wizata_dsapi_client.py +66 -9
  7. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42/wizata_dsapi.egg-info}/PKG-INFO +1 -1
  8. wizata_dsapi-1.3.40/wizata_dsapi/version.py +0 -1
  9. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/LICENSE.txt +0 -0
  10. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/README.rst +0 -0
  11. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/setup.cfg +0 -0
  12. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/setup.py +0 -0
  13. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/__init__.py +0 -0
  14. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/api_config.py +0 -0
  15. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/api_interface.py +0 -0
  16. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/bucket.py +0 -0
  17. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/business_label.py +0 -0
  18. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/context.py +0 -0
  19. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/dataframe_toolkit.py +0 -0
  20. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/datapoint.py +0 -0
  21. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/datastore.py +0 -0
  22. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/ds_dataframe.py +0 -0
  23. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/dsapi_json_encoder.py +0 -0
  24. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/evaluation.py +0 -0
  25. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/execution.py +0 -0
  26. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/experiment.py +0 -0
  27. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/group_system.py +0 -0
  28. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/ilogger.py +0 -0
  29. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/insight.py +0 -0
  30. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/model_toolkit.py +0 -0
  31. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/models/__init__.py +0 -0
  32. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/models/common.py +0 -0
  33. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/paged_query_result.py +0 -0
  34. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/pipeline_image.py +0 -0
  35. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/plot.py +0 -0
  36. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/plots/__init__.py +0 -0
  37. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/plots/common.py +0 -0
  38. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/request.py +0 -0
  39. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/script.py +0 -0
  40. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/scripts/__init__.py +0 -0
  41. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/scripts/common.py +0 -0
  42. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/solution_component.py +0 -0
  43. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/streamlit_utils.py +0 -0
  44. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/template.py +0 -0
  45. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/trigger.py +0 -0
  46. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/twin.py +0 -0
  47. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/twinregistration.py +0 -0
  48. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/wizard_function.py +0 -0
  49. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/wizard_request.py +0 -0
  50. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi/words.py +0 -0
  51. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi.egg-info/SOURCES.txt +0 -0
  52. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
  53. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi.egg-info/requires.txt +0 -0
  54. {wizata_dsapi-1.3.40 → wizata_dsapi-1.3.42}/wizata_dsapi.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 1.3.40
3
+ Version: 1.3.42
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -2,6 +2,12 @@ import uuid
2
2
  from enum import Enum
3
3
 
4
4
 
5
+ class ApiDtoInterface:
6
+
7
+ def load_model(self, model):
8
+ pass
9
+
10
+
5
11
  class VarType(Enum):
6
12
  """
7
13
  defines possible type for a defined variable.
@@ -1,6 +1,6 @@
1
1
  from typing import List, Iterator, Union, Optional
2
2
  import os
3
- from .api_dto import ApiDto
3
+ from .api_dto import ApiDto, ApiDtoInterface
4
4
  from datetime import datetime, timezone
5
5
 
6
6
 
@@ -165,6 +165,17 @@ class ModelInfo:
165
165
  self.has_target_feat = False
166
166
  self.label_counts = 0
167
167
 
168
+ # api
169
+ self._api = None
170
+
171
+ def bind_api(self, api:ApiDtoInterface):
172
+ """
173
+ internal method to bind the api to the dto.
174
+ :param api: api client
175
+ :return: None
176
+ """
177
+ self._api = api
178
+
168
179
  @classmethod
169
180
  def split_identifier(cls, identifier: str):
170
181
  """
@@ -279,6 +290,19 @@ class ModelInfo:
279
290
  self.is_active = get_bool(obj, name="is_active")
280
291
  if "updatedDate" in obj.keys() and obj["updatedDate"] is not None:
281
292
  self.updated_date = obj["updatedDate"]
293
+ if "files" in obj.keys():
294
+ for obj_file in obj["files"]:
295
+ model_file = ModelFile()
296
+ model_file.from_json(obj_file)
297
+ self.add_file(model_file)
298
+
299
+ def load(self):
300
+ """
301
+ load the trained model from the repository.
302
+ """
303
+ if self._api is None:
304
+ raise RuntimeError("api is not bound to the dto use bind_api()")
305
+ self._api.load_model(self)
282
306
 
283
307
 
284
308
  class ModelList:
@@ -304,15 +328,23 @@ class ModelList:
304
328
  """
305
329
  return any(model_in_list.identifier(include_alias=True) == model.identifier(include_alias=True) for model_in_list in self.models)
306
330
 
307
- def __getitem__(self, key: Union[int, ModelInfo]) -> ModelInfo:
331
+ def __getitem__(self, key: Union[int, str, ModelInfo]) -> ModelInfo:
308
332
  """
309
- find a model within list based on key or ModelInfo.
310
- :param key: ModelInfo or index
333
+ find a model within list based on index, identifier or ModelInfo.
334
+ :param key: identifier or ModelInfo or index
311
335
  :return: the model_info
312
336
  """
313
337
  if isinstance(key, int):
314
338
  return self.models[key]
315
339
 
340
+ elif isinstance(key, str):
341
+ if "@" not in key:
342
+ return self.select_active_model(identifier=key)
343
+ for model in self.models:
344
+ if model.identifier(include_alias=True) == key:
345
+ return model
346
+ raise KeyError(f"model with identifier '{key}' not found within this ModelList.")
347
+
316
348
  elif isinstance(key, ModelInfo):
317
349
  identifier = key.identifier(include_alias=True)
318
350
  for model in self.models:
@@ -321,7 +353,22 @@ class ModelList:
321
353
  raise KeyError(f"model with identifier '{identifier}' not found within this ModelList.")
322
354
 
323
355
  else:
324
- raise TypeError("ModelList indices must be int or ModelInfo.")
356
+ raise TypeError("ModelList indices must be int, str or ModelInfo.")
357
+
358
+ def select_active_model(self, identifier: str) -> ModelInfo:
359
+ """
360
+ return the active model based on active status or latest one if none active.
361
+ :param identifier: identifier
362
+ :return: active model
363
+ """
364
+ models = []
365
+ for model in self.models:
366
+ if model.identifier(include_alias=False) == identifier:
367
+ if model.is_active:
368
+ return model
369
+ else:
370
+ models.append(model)
371
+ return max(models, key=lambda f: f.updated_date, default=None)
325
372
 
326
373
  def append(self, model: ModelInfo):
327
374
  self.models.append(model)
@@ -1,5 +1,6 @@
1
1
  import uuid
2
2
  import json
3
+ import sys
3
4
 
4
5
  import pandas
5
6
  import wizata_dsapi
@@ -159,13 +160,13 @@ class PipelineIO(ApiDto):
159
160
  obj["columns"] = self.columns
160
161
  return obj
161
162
 
162
- def prepare(self, df: pandas.DataFrame) -> pandas.DataFrame:
163
+ def _prepare_df(self, df: pandas.DataFrame) -> pandas.DataFrame:
163
164
  """
164
- prepare the dataframe based in information from this pipeline I/O definition.
165
- perform mapping, selection and drops.
165
+ prepare dataframe in both 3.9 and 3.11+
166
166
  :param pandas.DataFrame df: dataframe to prepare.
167
167
  :return: prepared dataframe.
168
168
  """
169
+
169
170
  try:
170
171
  prepare_df = df.copy()
171
172
 
@@ -186,6 +187,25 @@ class PipelineIO(ApiDto):
186
187
  except Exception as e:
187
188
  raise RuntimeError(f'not able to prepare your dataframe following Pipeline I/O directives {e}')
188
189
 
190
+ if sys.version_info >= (3, 11):
191
+
192
+ ## with torch support
193
+ import torch
194
+ from typing import Union
195
+
196
+ def prepare(self, df: Union[pandas.DataFrame, torch.Tensor]) -> Union[pandas.DataFrame, torch.Tensor]:
197
+ import torch
198
+ if isinstance(df, torch.Tensor):
199
+ return df
200
+ else:
201
+ return self._prepare_df(df)
202
+
203
+ else:
204
+
205
+ ## without torch support
206
+ def prepare(self, df: pandas.DataFrame) -> pandas.DataFrame:
207
+ return self._prepare_df(df)
208
+
189
209
  @classmethod
190
210
  def from_obj(cls, obj):
191
211
  """
@@ -0,0 +1 @@
1
+ __version__ = "1.3.42"
@@ -16,11 +16,13 @@ import types
16
16
  import wizata_dsapi
17
17
  import urllib.parse
18
18
  import base64
19
+ import joblib
20
+ import io
19
21
 
20
22
  import string
21
23
  import random
22
24
 
23
- from .api_dto import ApiDto, VarType
25
+ from .api_dto import ApiDto, VarType, ApiDtoInterface
24
26
  from .business_label import BusinessLabel
25
27
  from .plot import Plot
26
28
  from .request import Request
@@ -69,7 +71,7 @@ def parse_string_list(s):
69
71
  return []
70
72
 
71
73
 
72
- class WizataDSAPIClient(ApiInterface):
74
+ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
73
75
  """
74
76
  client wrapper to cloud data science API
75
77
 
@@ -603,11 +605,12 @@ class WizataDSAPIClient(ApiInterface):
603
605
  function=obj
604
606
  )
605
607
  if isinstance(obj, Script):
606
- response = requests.put(self.__url() + "scripts/",
608
+ function = dill.dumps(obj.function)
609
+ response = requests.post(self.__url() + f"scripts/{obj.name}",
607
610
  headers=self.__header(),
608
- data=dill.dumps(obj))
611
+ data=function)
609
612
  if response.status_code == 200:
610
- obj.script_id = uuid.UUID(response.json()['id'])
613
+ obj.script_id = uuid.UUID(response.json()["id"])
611
614
  return obj.script_id
612
615
  else:
613
616
  raise self.__raise_error(response)
@@ -1100,17 +1103,24 @@ class WizataDSAPIClient(ApiInterface):
1100
1103
  raise self.__raise_error(response)
1101
1104
 
1102
1105
  def upload_model(self,
1103
- model_info: ModelInfo):
1106
+ model_info: ModelInfo,
1107
+ bytes_content = None):
1104
1108
  """
1105
1109
  upload a model within the model repository.
1110
+ - by default use model_info.trained_model and convert it to a pickle
1111
+ - for already torch or pickle please pass the bytes_content
1112
+ - model_info.file_format must be set properly to 'pkl' or 'pt'
1106
1113
  :param model_info: model info, with at least key (+twin, +property, +alias) and trained_model.
1114
+ :param bytes_content: bytes[] of your torch or pickle model.
1107
1115
  """
1108
- if model_info.trained_model is None:
1109
- raise ValueError("model_info must have a trained model as bytes content pkl or pt")
1116
+ if model_info.trained_model is None and bytes_content is None:
1117
+ raise ValueError("model_info must have a trained model (to pickle) or bytes content")
1118
+ if bytes_content is None:
1119
+ bytes_content = pickle.dumps(model_info.trained_model)
1110
1120
  files = {
1111
1121
  "trained_model": (
1112
1122
  "trained_model." + model_info.file_format ,
1113
- model_info.trained_model,
1123
+ bytes_content,
1114
1124
  "application/octet-stream",
1115
1125
  )
1116
1126
  }
@@ -1849,6 +1859,27 @@ class WizataDSAPIClient(ApiInterface):
1849
1859
  else:
1850
1860
  raise self.__raise_error(response)
1851
1861
 
1862
+ def search_models(self) -> ModelList:
1863
+ """
1864
+ get all information related to models stored on Wizata.
1865
+ :return: ModelList structure model list
1866
+ """
1867
+ response = requests.request("GET",
1868
+ self.__url() + "models",
1869
+ headers=self.__header()
1870
+ )
1871
+ if response.status_code == 200:
1872
+ response_json = response.json()
1873
+ model_list = ModelList()
1874
+ for model_json in response_json:
1875
+ model_info = ModelInfo(model_json["key"])
1876
+ model_info.from_json(model_json)
1877
+ model_info._api = self
1878
+ model_list.append(model_info)
1879
+ return model_list
1880
+ else:
1881
+ raise self.__raise_error(response)
1882
+
1852
1883
  def abort(self, executions: list) -> str:
1853
1884
  """
1854
1885
  send an abort request for executions and return a result message
@@ -1905,6 +1936,32 @@ class WizataDSAPIClient(ApiInterface):
1905
1936
  image = PipelineImage.loads(pipeline_image_id=pipeline_image_id, g_bytes=response_bytes)
1906
1937
  return image
1907
1938
 
1939
+ def load_model(self, model):
1940
+ """
1941
+ load a model pickle or torch from the repository ready to be used.
1942
+ :param model: ModelInfo to load
1943
+ :return: ModelInfo with the trained model.
1944
+ """
1945
+ if not isinstance(model, ModelInfo):
1946
+ raise TypeError('model must be an instance of ModelInfo')
1947
+
1948
+ identifier = model.identifier(include_alias=True)
1949
+ extension = model.file_format
1950
+ response = requests.get(self.__url() + f"models/{identifier}/files/trained_model.{extension}/",
1951
+ headers=self.__header())
1952
+ if response.status_code == 200:
1953
+ if extension == 'pkl':
1954
+ model.trained_model = joblib.load(io.BytesIO(response.content))
1955
+ return model
1956
+ elif extension == 'pt':
1957
+ import torch
1958
+ model.trained_model = torch.jit.load(io.BytesIO(response.content))
1959
+ return model
1960
+ else:
1961
+ raise ValueError(f'unsupported file format {extension}')
1962
+ else:
1963
+ self.__raise_error(response)
1964
+
1908
1965
 
1909
1966
  def api() -> WizataDSAPIClient:
1910
1967
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 1.3.40
3
+ Version: 1.3.42
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -1 +0,0 @@
1
- __version__ = "1.3.40"
File without changes
File without changes
File without changes
File without changes