wizata-dsapi 2.1.0.dev20__tar.gz → 2.1.0.dev22__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.dev20 → wizata_dsapi-2.1.0.dev22}/PKG-INFO +1 -1
  2. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/api_config.py +10 -0
  3. wizata_dsapi-2.1.0.dev22/wizata_dsapi/version.py +1 -0
  4. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/wizata_dsapi_client.py +71 -3
  5. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi.egg-info/PKG-INFO +1 -1
  6. wizata_dsapi-2.1.0.dev20/wizata_dsapi/version.py +0 -1
  7. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/LICENSE.txt +0 -0
  8. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/README.rst +0 -0
  9. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/setup.cfg +0 -0
  10. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/setup.py +0 -0
  11. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/__init__.py +0 -0
  12. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/api_dto.py +0 -0
  13. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/api_interface.py +0 -0
  14. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/bucket.py +0 -0
  15. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/business_label.py +0 -0
  16. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/context.py +0 -0
  17. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/dashboard.py +0 -0
  18. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/dataframe_toolkit.py +0 -0
  19. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/datapoint.py +0 -0
  20. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/datastore.py +0 -0
  21. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/deployment.py +0 -0
  22. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/ds_dataframe.py +0 -0
  23. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/dsapi_json_encoder.py +0 -0
  24. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/edge_config.py +0 -0
  25. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/edge_device.py +0 -0
  26. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/edge_module.py +0 -0
  27. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/evaluation.py +0 -0
  28. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/execution.py +0 -0
  29. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/execution_log.py +0 -0
  30. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/experiment.py +0 -0
  31. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/graylog_log.py +0 -0
  32. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/group_system.py +0 -0
  33. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/ilogger.py +0 -0
  34. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/insight.py +0 -0
  35. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/mlmodel.py +0 -0
  36. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/mobile_asset.py +0 -0
  37. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/model_toolkit.py +0 -0
  38. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/models/__init__.py +0 -0
  39. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/models/common.py +0 -0
  40. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/notification.py +0 -0
  41. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/paged_query_result.py +0 -0
  42. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/pipeline.py +0 -0
  43. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/pipeline_image.py +0 -0
  44. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/plot.py +0 -0
  45. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/plots/__init__.py +0 -0
  46. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/plots/common.py +0 -0
  47. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/plots/theme.py +0 -0
  48. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/request.py +0 -0
  49. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/script.py +0 -0
  50. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/scripts/__init__.py +0 -0
  51. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/scripts/common.py +0 -0
  52. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/search.py +0 -0
  53. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/solution_component.py +0 -0
  54. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/streamlit_utils.py +0 -0
  55. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/template.py +0 -0
  56. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/template_config.py +0 -0
  57. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/trigger.py +0 -0
  58. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/twin.py +0 -0
  59. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/twinregistration.py +0 -0
  60. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/user.py +0 -0
  61. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/wizard_function.py +0 -0
  62. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/wizard_request.py +0 -0
  63. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi/words.py +0 -0
  64. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi.egg-info/SOURCES.txt +0 -0
  65. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
  66. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/wizata_dsapi.egg-info/requires.txt +0 -0
  67. {wizata_dsapi-2.1.0.dev20 → wizata_dsapi-2.1.0.dev22}/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.dev20
3
+ Version: 2.1.0.dev22
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -32,6 +32,16 @@ from .edge_device import EdgeDevice
32
32
  # by the platform internally (the 12.1 adopt-triggers migration reads them through
33
33
  # `ApiDataManager.backend_api`, which never consults this registry). What goes is
34
34
  # the ability to schedule through the public client.
35
+
36
+ #: Entities the API paginates instead of listing.
37
+ #
38
+ # ``lists()`` fetches ``GET /<route>/``, and for these there is no such route — only
39
+ # ``POST /<route>/search``. Declaring 'lists' without this set was worse than not
40
+ # declaring it: the client advertised the operation and answered 404, and the
41
+ # documentation shipped a sample nobody could run. Listing now gathers the pages
42
+ # from the search endpoint, so the caller gets what the operation promised.
43
+ _LISTS_VIA_SEARCH = {Deployment}
44
+
35
45
  _retired = {
36
46
  "triggers": (
37
47
  Trigger,
@@ -0,0 +1 @@
1
+ __version__ = "2.1.0.dev22"
@@ -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():
@@ -361,6 +374,10 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
361
374
  :return: list of all elements with at least the id property.
362
375
  """
363
376
  dto_class = self._get_class(entity=entity, operation="lists")
377
+ from .api_config import _LISTS_VIA_SEARCH
378
+ if dto_class in _LISTS_VIA_SEARCH:
379
+ # No GET /<route>/ exists for these; the API paginates them instead.
380
+ return self._list_via_search(dto_class)
364
381
  return self._process_request(
365
382
  method="GET",
366
383
  route=dto_class.route() + "/",
@@ -368,6 +385,32 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
368
385
  result_type="list"
369
386
  )
370
387
 
388
+ def _list_via_search(self, dto_class) -> list:
389
+ """
390
+ Every record of an entity the API only paginates.
391
+
392
+ Walks the pages rather than trusting one to hold everything: a caller asking
393
+ to list is asking for all of them, and silently returning the first fifty is
394
+ the kind of wrong that looks right until an estate grows.
395
+ """
396
+ results, page = [], 1
397
+ while True:
398
+ search_query = SearchQuery()
399
+ search_query.page = page
400
+ search_query.size = 100
401
+ response = requests.post(
402
+ self.__url() + dto_class.route() + "/search",
403
+ headers=self.__header(),
404
+ data=json.dumps(search_query.to_dict())
405
+ )
406
+ if response.status_code != 200:
407
+ raise self.__raise_error(response)
408
+ paged = PagedQueryResult.from_dict(response.json(), dto_class=dto_class)
409
+ results.extend(paged.results or [])
410
+ if not paged.results or len(results) >= (paged.total or 0):
411
+ return results
412
+ page += 1
413
+
371
414
  def get(self,
372
415
  obj=None,
373
416
  id: uuid.UUID = None,
@@ -2337,6 +2380,31 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
2337
2380
  """
2338
2381
  return self._deployment_action(deployment, "retry")
2339
2382
 
2383
+ def search_deployments(self, search_query=None) -> PagedQueryResult:
2384
+ """
2385
+ Search deployments using a paged query.
2386
+
2387
+ The only way to ask what is deployed: there is no GET /deployments/, because
2388
+ a deployment is not created by posting one — it is the result of deploying a
2389
+ pipeline — and the estate is paginated rather than listed.
2390
+
2391
+ :param search_query: SearchQuery instance or dict with filters, sort, page, size.
2392
+ :return: PagedQueryResult with Deployment results.
2393
+ """
2394
+ if search_query is None:
2395
+ search_query = SearchQuery()
2396
+ elif isinstance(search_query, dict):
2397
+ search_query = SearchQuery.from_dict(search_query)
2398
+ response = requests.post(
2399
+ self.__url() + "deployments/search",
2400
+ headers=self.__header(),
2401
+ data=json.dumps(search_query.to_dict())
2402
+ )
2403
+ if response.status_code == 200:
2404
+ return PagedQueryResult.from_dict(response.json(), dto_class=Deployment)
2405
+ else:
2406
+ raise self.__raise_error(response)
2407
+
2340
2408
  def await_deployment(self,
2341
2409
  deployment,
2342
2410
  timeout: int = 900,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 2.1.0.dev20
3
+ Version: 2.1.0.dev22
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.dev20"