wizata-dsapi 2.1.0.dev21__tar.gz → 2.1.0.dev23__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 (67) hide show
  1. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/PKG-INFO +1 -1
  2. wizata_dsapi-2.1.0.dev23/wizata_dsapi/version.py +1 -0
  3. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/wizata_dsapi_client.py +86 -63
  4. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi.egg-info/PKG-INFO +1 -1
  5. wizata_dsapi-2.1.0.dev21/wizata_dsapi/version.py +0 -1
  6. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/LICENSE.txt +0 -0
  7. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/README.rst +0 -0
  8. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/setup.cfg +0 -0
  9. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/setup.py +0 -0
  10. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/__init__.py +0 -0
  11. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/api_config.py +0 -0
  12. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/api_dto.py +0 -0
  13. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/api_interface.py +0 -0
  14. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/bucket.py +0 -0
  15. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/business_label.py +0 -0
  16. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/context.py +0 -0
  17. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/dashboard.py +0 -0
  18. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/dataframe_toolkit.py +0 -0
  19. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/datapoint.py +0 -0
  20. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/datastore.py +0 -0
  21. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/deployment.py +0 -0
  22. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/ds_dataframe.py +0 -0
  23. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/dsapi_json_encoder.py +0 -0
  24. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/edge_config.py +0 -0
  25. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/edge_device.py +0 -0
  26. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/edge_module.py +0 -0
  27. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/evaluation.py +0 -0
  28. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/execution.py +0 -0
  29. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/execution_log.py +0 -0
  30. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/experiment.py +0 -0
  31. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/graylog_log.py +0 -0
  32. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/group_system.py +0 -0
  33. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/ilogger.py +0 -0
  34. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/insight.py +0 -0
  35. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/mlmodel.py +0 -0
  36. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/mobile_asset.py +0 -0
  37. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/model_toolkit.py +0 -0
  38. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/models/__init__.py +0 -0
  39. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/models/common.py +0 -0
  40. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/notification.py +0 -0
  41. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/paged_query_result.py +0 -0
  42. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/pipeline.py +0 -0
  43. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/pipeline_image.py +0 -0
  44. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/plot.py +0 -0
  45. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/plots/__init__.py +0 -0
  46. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/plots/common.py +0 -0
  47. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/plots/theme.py +0 -0
  48. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/request.py +0 -0
  49. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/script.py +0 -0
  50. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/scripts/__init__.py +0 -0
  51. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/scripts/common.py +0 -0
  52. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/search.py +0 -0
  53. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/solution_component.py +0 -0
  54. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/streamlit_utils.py +0 -0
  55. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/template.py +0 -0
  56. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/template_config.py +0 -0
  57. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/trigger.py +0 -0
  58. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/twin.py +0 -0
  59. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/twinregistration.py +0 -0
  60. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/user.py +0 -0
  61. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/wizard_function.py +0 -0
  62. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/wizard_request.py +0 -0
  63. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi/words.py +0 -0
  64. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi.egg-info/SOURCES.txt +0 -0
  65. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
  66. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/wizata_dsapi.egg-info/requires.txt +0 -0
  67. {wizata_dsapi-2.1.0.dev21 → wizata_dsapi-2.1.0.dev23}/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: 2.1.0.dev21
3
+ Version: 2.1.0.dev23
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -0,0 +1 @@
1
+ __version__ = "2.1.0.dev23"
@@ -213,8 +213,15 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
213
213
  raise a formatted error from an API response.
214
214
  :param response: response from the server.
215
215
  """
216
- if 'Content-Type' in response.headers and response.headers['Content-Type'] == 'application/json':
217
- json_content = response.json()
216
+ if ('Content-Type' in response.headers
217
+ and response.headers['Content-Type'] == 'application/json'
218
+ and response.content):
219
+ try:
220
+ json_content = response.json()
221
+ except ValueError:
222
+ # A body that claims to be JSON and is not. Reporting the status is
223
+ # useful; replacing the real failure with a decoding error is not.
224
+ return RuntimeError(str(response.status_code) + " - " + response.reason)
218
225
  if "errors" in json_content.keys():
219
226
  message = json_content["errors"][0]["message"]
220
227
  return RuntimeError(str(response.status_code) + " - " + message)
@@ -303,11 +310,17 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
303
310
  print(f' * Warning - version mismatch - server {server_version} vs local {wizata_dsapi.__version__}')
304
311
  print(f' python -m pip install --upgrade pip')
305
312
  print(f' pip install wizata_dsapi=={server_version}')
306
- if response.status_code == 200:
313
+ if 200 <= response.status_code < 300:
307
314
  if 'Wizata-Roles' in response.headers:
308
315
  self.roles = parse_string_list(response.headers['Wizata-Roles'])
309
316
  if 'Wizata-Twins' in response.headers:
310
317
  self.twins = parse_string_list(response.headers['Wizata-Twins'])
318
+ if not response.content:
319
+ # 204 No Content, which is what a delete answers. Only 200 counted
320
+ # as success before, so a delete fell through to the error path and
321
+ # raised JSONDecodeError parsing an empty body — the call had
322
+ # worked, and the caller had to catch an exception to find out.
323
+ return None
311
324
  if result_type == "list":
312
325
  obj_list = []
313
326
  for obj_json in response.json():
@@ -1971,72 +1984,82 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
1971
1984
  else:
1972
1985
  raise self.__raise_error(response)
1973
1986
 
1987
+ #: Executions are streamed per runner, and the two do not mix: a scheduled run
1988
+ #: is logged by the pipeline runner, an experiment by the experiment runner.
1989
+ #: Searching the wrong one returns a confident, complete, empty answer.
1990
+ PRODUCTION_RUNS = "pipeline_runner"
1991
+ EXPERIMENT_RUNS = "experiment_runner"
1992
+
1974
1993
  def search_executions(self,
1994
+ search_query=None,
1995
+ service: str = PRODUCTION_RUNS,
1996
+ pipeline: str = None,
1997
+ twin: str = None,
1998
+ status=None,
1975
1999
  page: int = 1,
1976
- size: int = 20,
1977
- sort: str = "id",
1978
- direction: str = "asc",
1979
- pipeline_id: uuid.UUID = None,
1980
- twin_id: uuid.UUID = None,
1981
- template_id: uuid.UUID = None,
1982
- status: ExecutionStatus = None) -> PagedQueryResult:
2000
+ size: int = 20) -> PagedQueryResult:
2001
+ """
2002
+ Search executions with filters, sorting and pagination.
2003
+
2004
+ Executions are searched per runner. ``service`` selects which: scheduled
2005
+ runs are logged by :attr:`PRODUCTION_RUNS`, experiments by
2006
+ :attr:`EXPERIMENT_RUNS`. They are separate streams, so looking in the wrong
2007
+ one answers "no executions" rather than telling you that you asked the
2008
+ wrong question.
2009
+
2010
+ :param search_query: SearchQuery or dict for the full query. When given,
2011
+ the convenience arguments below are ignored.
2012
+ :param service: which runner's executions to search.
2013
+ :param pipeline: pipeline KEY, not id - executions are labelled by key.
2014
+ :param twin: twin hardware id.
2015
+ :param status: ExecutionStatus, or its value.
2016
+ :param page: page number, from 1.
2017
+ :param size: results per page.
2018
+ :return: PagedQueryResult with Execution results.
1983
2019
  """
1984
- get executions with a paged query.
1985
- :param page: numero of the page - default 1.
1986
- :param size: quantity per page - default 20 max 100.
1987
- :param sort: column to sort results - default id.
1988
- :param direction: sorting direction by default asc, accept also desc.
1989
- :param pipeline_id: filter on a specific pipeline.
1990
- :param twin_id: filter on a specific twin.
1991
- :param template_id: filter on a specific template.
1992
- :param status: filter on a specific status.
1993
- :return: PagedQueryResults, check total for number of potential results and results for the list of entity.
1994
- """
1995
- query = PagedQueryResult(
1996
- page=page,
1997
- size=size,
1998
- sort=sort,
1999
- direction=direction
2000
- )
2001
-
2002
- if sort not in ["id", "pipelineId", "twinId", "templateId",
2003
- "createdDate" , "createdById",
2004
- "updatedDate", "updatedById",
2005
- "status"]:
2006
- raise ValueError("invalid sort column")
2007
-
2008
- parameter_str = "?page=" + str(page) + "&size=" + str(size) + "&sort=" + str(sort) + "&direction=" + str(direction)
2009
-
2010
- if pipeline_id is not None:
2011
- parameter_str += "&pipelineId=" + sanitize_url_parameter(str(pipeline_id))
2012
-
2013
- if twin_id is not None:
2014
- parameter_str += "&twinId=" + sanitize_url_parameter(str(twin_id))
2015
-
2016
- if template_id is not None:
2017
- parameter_str += "&templateId=" + sanitize_url_parameter(str(template_id))
2018
-
2019
- if status is not None:
2020
- if not isinstance(status, ExecutionStatus):
2021
- raise ValueError(f'status is not a valid ExecutionStatus')
2022
- parameter_str += "&status=" + sanitize_url_parameter(status.value)
2020
+ if search_query is None:
2021
+ search_query = SearchQuery()
2022
+ search_query.page = page
2023
+ search_query.size = size
2024
+ search_query.service_name = service
2025
+ filters = {}
2026
+ if pipeline is not None:
2027
+ filters["pipeline"] = {"eq": str(pipeline)}
2028
+ if twin is not None:
2029
+ filters["twin"] = {"eq": str(twin)}
2030
+ if status is not None:
2031
+ value = status.value if isinstance(status, ExecutionStatus) else status
2032
+ filters["status"] = {"eq": str(value)}
2033
+ search_query.filters = filters
2034
+ elif isinstance(search_query, dict):
2035
+ search_query = SearchQuery.from_dict(search_query)
2023
2036
 
2024
- response = requests.request("GET",
2025
- self.__url() + "execute/filter" + parameter_str,
2026
- headers=self.__header()
2027
- )
2028
- if response.status_code == 200:
2029
- response_obj = response.json()
2030
- query.total = int(response_obj["total"])
2031
- query.results = []
2032
- for obj in response_obj["results"]:
2033
- execution = Execution()
2034
- execution.from_json(obj)
2035
- query.results.append(execution)
2036
- return query
2037
- else:
2037
+ response = requests.post(
2038
+ self.__url() + "execute/search",
2039
+ headers=self.__header(),
2040
+ data=json.dumps(search_query.to_dict())
2041
+ )
2042
+ if response.status_code != 200:
2038
2043
  raise self.__raise_error(response)
2039
2044
 
2045
+ body = response.json()
2046
+ # PagedQueryResult refuses a null sort, so a response that omits it would
2047
+ # raise on an answer that succeeded. The executions endpoint orders by
2048
+ # timestamp descending unless told otherwise; say so rather than break.
2049
+ query = PagedQueryResult(
2050
+ page=body.get("page", page),
2051
+ size=body.get("size", size),
2052
+ sort=body.get("sort") or "timestamp",
2053
+ direction=body.get("direction") or "desc"
2054
+ )
2055
+ query.total = int(body.get("total", 0))
2056
+ # ExecutionLog, not Execution: this endpoint answers with log rows, whose
2057
+ # id is a uuid and whose pipeline, twin and template are keys rather than
2058
+ # ids. Execution.from_json reads id as an int and raises on the first row.
2059
+ query.results = [ExecutionLog.from_dict(obj)
2060
+ for obj in body.get("results", [])]
2061
+ return query
2062
+
2040
2063
  def search_execution(self, search_query=None) -> PagedQueryResult:
2041
2064
  """
2042
2065
  search executions using filters, sorting and pagination via POST.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 2.1.0.dev21
3
+ Version: 2.1.0.dev23
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__ = "2.1.0.dev21"