wizata-dsapi 2.2.0.dev10__tar.gz → 2.2.0.dev12__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 (71) hide show
  1. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/PKG-INFO +1 -1
  2. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/__init__.py +2 -1
  3. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/inventory.py +107 -0
  4. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/request.py +3 -1
  5. wizata_dsapi-2.2.0.dev12/wizata_dsapi/version.py +1 -0
  6. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/wizata_dsapi_client.py +28 -1
  7. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi.egg-info/PKG-INFO +1 -1
  8. wizata_dsapi-2.2.0.dev10/wizata_dsapi/version.py +0 -1
  9. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/LICENSE.txt +0 -0
  10. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/README.rst +0 -0
  11. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/setup.cfg +0 -0
  12. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/setup.py +0 -0
  13. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/api_config.py +0 -0
  14. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/api_dto.py +0 -0
  15. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/api_interface.py +0 -0
  16. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/bucket.py +0 -0
  17. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/business_label.py +0 -0
  18. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/connection.py +0 -0
  19. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/connection_types.py +0 -0
  20. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/context.py +0 -0
  21. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/dashboard.py +0 -0
  22. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/dataframe_toolkit.py +0 -0
  23. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/datapoint.py +0 -0
  24. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/datastore.py +0 -0
  25. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/deployment.py +0 -0
  26. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/ds_dataframe.py +0 -0
  27. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/dsapi_json_encoder.py +0 -0
  28. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/edge_config.py +0 -0
  29. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/edge_device.py +0 -0
  30. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/edge_module.py +0 -0
  31. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/evaluation.py +0 -0
  32. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/execution.py +0 -0
  33. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/execution_log.py +0 -0
  34. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/experiment.py +0 -0
  35. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/graylog_log.py +0 -0
  36. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/group_system.py +0 -0
  37. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/ilogger.py +0 -0
  38. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/insight.py +0 -0
  39. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/mlmodel.py +0 -0
  40. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/mobile_asset.py +0 -0
  41. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/model_toolkit.py +0 -0
  42. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/models/__init__.py +0 -0
  43. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/models/common.py +0 -0
  44. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/notification.py +0 -0
  45. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/paged_query_result.py +0 -0
  46. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/pipeline.py +0 -0
  47. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/pipeline_image.py +0 -0
  48. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/plot.py +0 -0
  49. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/plots/__init__.py +0 -0
  50. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/plots/common.py +0 -0
  51. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/plots/theme.py +0 -0
  52. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/product.py +0 -0
  53. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/script.py +0 -0
  54. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/scripts/__init__.py +0 -0
  55. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/scripts/common.py +0 -0
  56. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/search.py +0 -0
  57. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/solution_component.py +0 -0
  58. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/streamlit_utils.py +0 -0
  59. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/template.py +0 -0
  60. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/template_config.py +0 -0
  61. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/trigger.py +0 -0
  62. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/twin.py +0 -0
  63. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/twinregistration.py +0 -0
  64. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/user.py +0 -0
  65. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/wizard_function.py +0 -0
  66. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/wizard_request.py +0 -0
  67. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi/words.py +0 -0
  68. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi.egg-info/SOURCES.txt +0 -0
  69. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
  70. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/wizata_dsapi.egg-info/requires.txt +0 -0
  71. {wizata_dsapi-2.2.0.dev10 → wizata_dsapi-2.2.0.dev12}/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.2.0.dev10
3
+ Version: 2.2.0.dev12
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -66,7 +66,8 @@ from .connection import Connection, ConnectionMapping, ConnectionDirection, Tran
66
66
  from .connection_types import ConnectionType, CONNECTION_TYPES, TRANSFORM_SCHEMAS, get_connection_type, \
67
67
  list_connection_types
68
68
  from .product import ProductKind, Product, ProductComponent, BUILTIN_PRODUCT_KINDS, is_valid_product_key
69
- from .inventory import (InventoryBalance, InventoryStorage, InventoryStorageDatapoint, inventory_mode, INVENTORY_OPTION, INVENTORY_MODES,
69
+ from .inventory import (InventoryBalance, InventoryStorage, InventoryStorageDatapoint, inventory_mode,
70
+ InventoryStock, InventoryStockProduct, InventoryStockLine, InventoryStockCount, INVENTORY_OPTION, INVENTORY_MODES,
70
71
  INVENTORY_MOVEMENTS, INVENTORY_BALANCES, INVENTORY_STOCK,
71
72
  PRODUCT_TAG, PRODUCT_MESSAGE_KEY)
72
73
  from .dashboard import Dashboard, DashboardType
@@ -204,3 +204,110 @@ class InventoryStorage:
204
204
 
205
205
  def __repr__(self) -> str:
206
206
  return f"InventoryStorage({self.twin_hardware_id!r}, {[d.hardware_id for d in self.datapoints]})"
207
+
208
+
209
+ class InventoryStockCount:
210
+ """The last count behind a stock line: the balance it starts from (DEV-6088)."""
211
+
212
+ def __init__(self, balance_id=None, count=None, timestamp=None, quantity: float = None, by: str = None):
213
+ self.id: Optional[str] = _uuid_str(balance_id)
214
+ self.count: Optional[str] = _uuid_str(count)
215
+ self.timestamp: Optional[datetime] = _ts_in(timestamp)
216
+ self.quantity: Optional[float] = quantity
217
+ self.by: Optional[str] = by
218
+
219
+ def to_dict(self) -> dict:
220
+ return {"id": self.id, "count": self.count,
221
+ "timestamp": _ts_out(self.timestamp) if isinstance(self.timestamp, datetime) else self.timestamp,
222
+ "quantity": self.quantity, "by": self.by}
223
+
224
+ @classmethod
225
+ def from_dict(cls, data: dict) -> "InventoryStockCount":
226
+ return cls(balance_id=data.get("id"), count=data.get("count"), timestamp=data.get("timestamp"),
227
+ quantity=data.get("quantity"), by=data.get("by"))
228
+
229
+
230
+ class InventoryStockLine:
231
+ """
232
+ One product on one storage datapoint at a moment: ``quantity`` in the datapoint's unit,
233
+ ``last_count`` (None when never counted) and ``moved_since`` it (DEV-6088).
234
+ """
235
+
236
+ def __init__(self, twin_id=None, twin_hardware_id: str = None, twin_name: str = None, datapoint: str = None,
237
+ unit=None, unit_symbol: str = None, quantity: float = None, moved_since: float = None,
238
+ last_count: InventoryStockCount = None):
239
+ self.twin_id: Optional[str] = _uuid_str(twin_id)
240
+ self.twin_hardware_id: Optional[str] = twin_hardware_id
241
+ self.twin_name: Optional[str] = twin_name
242
+ self.datapoint: Optional[str] = datapoint
243
+ self.unit: Optional[str] = _uuid_str(unit)
244
+ self.unit_symbol: Optional[str] = unit_symbol
245
+ self.quantity: Optional[float] = quantity
246
+ self.moved_since: Optional[float] = moved_since
247
+ self.last_count: Optional[InventoryStockCount] = last_count
248
+
249
+ def to_dict(self) -> dict:
250
+ return {"twin": {"id": self.twin_id, "hardwareId": self.twin_hardware_id, "name": self.twin_name},
251
+ "datapoint": self.datapoint, "unit": self.unit, "unitSymbol": self.unit_symbol,
252
+ "quantity": self.quantity, "movedSince": self.moved_since,
253
+ "lastCount": self.last_count.to_dict() if self.last_count is not None else None}
254
+
255
+ @classmethod
256
+ def from_dict(cls, data: dict) -> "InventoryStockLine":
257
+ twin = data.get("twin") or {}
258
+ last = data.get("lastCount")
259
+ return cls(twin_id=twin.get("id"), twin_hardware_id=twin.get("hardwareId"), twin_name=twin.get("name"),
260
+ datapoint=data.get("datapoint"), unit=data.get("unit"), unit_symbol=data.get("unitSymbol"),
261
+ quantity=data.get("quantity"), moved_since=data.get("movedSince"),
262
+ last_count=InventoryStockCount.from_dict(last) if last else None)
263
+
264
+
265
+ class InventoryStockProduct:
266
+ """
267
+ A product's stock at a moment: one line per storage holding it, and a ``total`` in
268
+ ``total_unit``: the product's default unit, else the unit most of its storages use
269
+ (DEV-6088). ``total`` is None when a line's unit cannot be converted.
270
+ """
271
+
272
+ def __init__(self, key: str = None, name: str = None, kind: str = None, category=None, unit=None,
273
+ unit_symbol: str = None, total: float = None, total_unit=None, total_unit_symbol: str = None,
274
+ storages: list = None):
275
+ self.key: Optional[str] = key
276
+ self.name: Optional[str] = name
277
+ self.kind: Optional[str] = kind
278
+ self.category: Optional[str] = _uuid_str(category)
279
+ self.unit: Optional[str] = _uuid_str(unit)
280
+ self.unit_symbol: Optional[str] = unit_symbol
281
+ self.total: Optional[float] = total
282
+ self.total_unit: Optional[str] = _uuid_str(total_unit)
283
+ self.total_unit_symbol: Optional[str] = total_unit_symbol
284
+ self.storages: list = list(storages or [])
285
+
286
+ def to_dict(self) -> dict:
287
+ return {"key": self.key, "name": self.name, "kind": self.kind, "category": self.category,
288
+ "unit": self.unit, "unitSymbol": self.unit_symbol, "total": self.total,
289
+ "totalUnit": self.total_unit, "totalUnitSymbol": self.total_unit_symbol,
290
+ "storages": [s.to_dict() for s in self.storages]}
291
+
292
+ @classmethod
293
+ def from_dict(cls, data: dict) -> "InventoryStockProduct":
294
+ return cls(key=data.get("key"), name=data.get("name"), kind=data.get("kind"), category=data.get("category"),
295
+ unit=data.get("unit"), unit_symbol=data.get("unitSymbol"), total=data.get("total"),
296
+ total_unit=data.get("totalUnit"), total_unit_symbol=data.get("totalUnitSymbol"),
297
+ storages=[InventoryStockLine.from_dict(s) for s in data.get("storages") or []])
298
+
299
+
300
+ class InventoryStock:
301
+ """Stock of every product × storage at ``as_of`` (``POST /dsapi/planner/inventory/stock``, DEV-6088)."""
302
+
303
+ def __init__(self, as_of=None, products: list = None):
304
+ self.as_of: Optional[datetime] = _ts_in(as_of)
305
+ self.products: list = list(products or [])
306
+
307
+ def to_dict(self) -> dict:
308
+ return {"asOf": _ts_out(self.as_of) if isinstance(self.as_of, datetime) else self.as_of,
309
+ "products": [p.to_dict() for p in self.products]}
310
+
311
+ @classmethod
312
+ def from_dict(cls, data: dict) -> "InventoryStock":
313
+ return cls(as_of=data.get("asOf"), products=[InventoryStockProduct.from_dict(p) for p in data.get("products") or []])
@@ -165,7 +165,9 @@ class Request(ApiDto):
165
165
  :ivar dict filters: filters to apply to the query pre-aggregation. nested dictionary using as first key=datapoint then value=another dictionary with key=operator (gt,lt,gte,lte,eq,neq) and value is the float value to compare too).
166
166
  :ivar dict options: dict representing query options.
167
167
  :ivar list scopes: scope filters for SCOPED datapoints.
168
- :ivar list products: product keys to keep on inventoryMovement datapoints (all when None).
168
+ :ivar list products: product keys to keep on inventoryMovement datapoints (all when None). With
169
+ no datapoints, it selects the inventoryMovement datapoints holding them (under the twin
170
+ when the request names one).
169
171
  """
170
172
 
171
173
  @classmethod
@@ -0,0 +1 @@
1
+ __version__ = "2.2.0.dev12"
@@ -55,7 +55,7 @@ from .version import __version__
55
55
  import ast
56
56
  from .deployment import Deployment, DeploymentStatus
57
57
  from .product import ProductKind, Product, ProductComponent
58
- from .inventory import InventoryBalance, InventoryStorage
58
+ from .inventory import InventoryBalance, InventoryStorage, InventoryStock
59
59
  from .api_config import _registry
60
60
 
61
61
  from .streamlit_utils import get_streamlit_token, get_streamlit_domain
@@ -872,6 +872,8 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
872
872
  :param scopes: list of scope filters for SCOPED datapoints (e.g. ["normal", {"vibration": {"gte": 0.6}}]).
873
873
  :param products: product keys to keep on inventoryMovement datapoints (all when None).
874
874
  ``options={"inventory": "movements" | "balances" | "stock"}`` chooses what they return.
875
+ With no ``datapoints``, the inventoryMovement datapoints holding those products are
876
+ selected for you: every storage, or those under ``twin`` and its children (DEV-6089).
875
877
  :return: dataframe
876
878
  """
877
879
  return self._query(request=self._build_request(
@@ -2909,6 +2911,31 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
2909
2911
  body=search_query.to_dict())
2910
2912
  return PagedQueryResult.from_dict(response.json(), dto_class=InventoryBalance)
2911
2913
 
2914
+ def get_inventory_stock(self, as_of=None, twins: list = None, products: list = None,
2915
+ kinds: list = None) -> InventoryStock:
2916
+ """
2917
+ Stock of every product × storage at a moment (DEV-6088): per storage datapoint the
2918
+ quantity in its unit, the last count and what moved since; per product a total in
2919
+ its default unit (else the unit most of its storages use).
2920
+
2921
+ :param as_of: datetime or ISO string; default now. Events at that moment count.
2922
+ :param twins: storage twins (hardware ids or ids) to keep.
2923
+ :param products: product keys to keep.
2924
+ :param kinds: product kind keys to keep.
2925
+ """
2926
+ body = {}
2927
+ if as_of is not None:
2928
+ if isinstance(as_of, datetime.datetime):
2929
+ if as_of.tzinfo is None:
2930
+ as_of = as_of.replace(tzinfo=datetime.timezone.utc)
2931
+ as_of = as_of.isoformat()
2932
+ body["asOf"] = as_of
2933
+ for name, value in (("twins", twins), ("products", products), ("kinds", kinds)):
2934
+ if value is not None:
2935
+ body[name] = list(value)
2936
+ response = self._planner_request("POST", "planner/inventory/stock", body=body)
2937
+ return InventoryStock.from_dict(response.json())
2938
+
2912
2939
  def search_inventory_storages(self, search_query=None) -> PagedQueryResult:
2913
2940
  """
2914
2941
  The storage places: Twins holding an inventoryMovement DataPoint, each with those
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 2.2.0.dev10
3
+ Version: 2.2.0.dev12
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.2.0.dev10"