accsyn-python-api 3.2.2__py3-none-any.whl → 3.3.0__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.
accsyn_api/_version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # :coding: utf-8
2
2
  # :copyright: Copyright (c) 2015-2023 accsyn/HDR AB
3
3
 
4
- __version__ = "3.2.2-0"
4
+ __version__ = "3.3.0-0"
accsyn_api/session.py CHANGED
@@ -86,7 +86,7 @@ UNIQUE_ENTITY_TYPES = [
86
86
  "engine",
87
87
  "queue",
88
88
  ]
89
- # Entity types were code is unique and can be used to find the entity by code
89
+ # Entity types were code is unique and can be used to find the entity by its API identifier (code)
90
90
 
91
91
 
92
92
  class JSONEncoder(json.JSONEncoder):
@@ -124,26 +124,27 @@ class JSONDecoder(json.JSONDecoder):
124
124
  newlist.append(recursive_decode(i))
125
125
  d[key] = newlist
126
126
  elif Session._is_str(d[key]):
127
- if re.match(
128
- "^[0-9]{2,4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:" "[0-9]{2}$",
127
+ dt = None
128
+ if d[key].startswith("ObjectId:"):
129
+ d[key] = d[key].replace("ObjectId:", "") # Just treat as string
130
+ elif re.match(
131
+ "^[0-9]{2,4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$",
129
132
  str(Session._safely_printable(d[key])),
130
133
  ):
131
134
  if len(d[key].split("-")[0]) == 4:
132
135
  dt = datetime.datetime.strptime(d[key], "%Y-%m-%dT%H:%M:%S")
133
136
  else:
134
137
  dt = datetime.datetime.strptime(d[key], "%y-%m-%dT%H:%M:%S")
135
- # Backend sends UTC, convert to local timezone
136
- dt = dt.replace(tzinfo=datetime.timezone.utc)
137
- d[key] = dt.astimezone()
138
138
  # With millis
139
139
  elif re.match(
140
- "^[0-9]{2,4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:" "[0-9]{2}:[0-9]{2}.[0-9]{3}$",
140
+ "^[0-9]{2,4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}$",
141
141
  str(Session._safely_printable(d[key])),
142
142
  ):
143
143
  if len(d[key].split("-")[0]) == 4:
144
144
  dt = datetime.datetime.strptime(d[key], "%Y-%m-%dT%H:%M:%S.%f")
145
145
  else:
146
146
  dt = datetime.datetime.strptime(d[key], "%y-%m-%dT%H:%M:%S.%f")
147
+ if dt is not None:
147
148
  # Backend sends UTC, convert to local timezone
148
149
  dt = dt.replace(tzinfo=datetime.timezone.utc)
149
150
  d[key] = dt.astimezone()
@@ -468,6 +469,7 @@ class Session(object):
468
469
  skip: Optional[int] = None,
469
470
  create: bool = False,
470
471
  update: bool = False,
472
+ single_entity_query: bool = False,
471
473
  ) -> Optional[List[Dict[str, Any]]]:
472
474
  """
473
475
  Return (GET) a list of entities/entitytypes/attributes based on *query*.
@@ -483,6 +485,7 @@ class Session(object):
483
485
  :param skip: The amount of entities to skip.
484
486
  :param create: (attributes) Return create (POST) attributes.
485
487
  :param update: (attributes) Return update (PUT) attributes.
488
+ :param single_entity_query: It is a single entity query, tell backend to be more relaxed regarding status scope.
486
489
  :return: List of dictionaries.
487
490
  """
488
491
  assert 0 < len(query or "") and Session._is_str(query), "Invalid query type supplied, must be of string type!"
@@ -555,14 +558,24 @@ class Session(object):
555
558
  data["skip"] = skip
556
559
  if attributes:
557
560
  data["attributes"] = attributes
561
+ if single_entity_query:
562
+ data["single_entity_query"] = single_entity_query
558
563
  response = self._event("GET", f"{d['entitytype']}/find", data, query=d.get("expression"))
559
564
  if response:
560
565
  retval = response["result"]
566
+ if single_entity_query:
567
+ if retval and 0 < len(retval):
568
+ if 1 < len(retval):
569
+ Session._warning(f"Multiple entities retreived({len(retval)}), returning first one.")
570
+ single_retval = retval[0]
571
+ return single_retval
572
+ return None
561
573
  return retval
562
574
 
563
575
  def find_one(
564
576
  self,
565
577
  query: str,
578
+ entityid: Optional[str] = None,
566
579
  attributes: Optional[List[str]] = None,
567
580
  finished: Optional[bool] = None,
568
581
  inactive: Optional[bool] = None,
@@ -573,6 +586,7 @@ class Session(object):
573
586
  Return a single entity.
574
587
 
575
588
  :param query: The query, a string on accsyn query format.
589
+ :param entityid: The parent entity ID, required for sub entities "task" and "file".
576
590
  :param attributes: The attributes to return, default is to return all attributes with access.
577
591
  :param finished: (job) Search among finished/aborted jobs.
578
592
  :param inactive: (user,share) Search among inactive entities.
@@ -583,19 +597,15 @@ class Session(object):
583
597
  assert 0 < len(query or "") and (
584
598
  Session._is_str(query)
585
599
  ), "Invalid query type supplied, must be of string type!"
586
- result = self.find(
600
+ return self.find(
587
601
  query,
602
+ entityid=entityid,
588
603
  attributes=attributes,
589
604
  finished=finished,
590
605
  inactive=inactive or offline,
591
606
  archived=archived,
607
+ single_entity_query=True,
592
608
  )
593
- if result and 0 < len(result):
594
- retval = result[0]
595
- if 1 < len(result):
596
- Session._warning(f"Multiple entities retreived({len(result)}), returning first one.")
597
- return retval
598
- return None
599
609
 
600
610
  def get_entity(self, entitytype: str, entityid: str) -> Optional[Dict[str, Any]]:
601
611
  """
@@ -1524,41 +1534,116 @@ class Session(object):
1524
1534
  def get_setting(
1525
1535
  self,
1526
1536
  name: Optional[str] = None,
1527
- scope: str = 'workspace',
1528
- entity_id: Optional[str] = None,
1537
+ entitytype: str = 'workspace',
1538
+ entityid: Optional[str] = None,
1529
1539
  integration: Optional[str] = None,
1530
1540
  data: Optional[Dict[str, Any]] = None,
1531
1541
  ) -> Optional[Any]:
1532
- '''Retrive *name* setting for the given *scope* (workspace, job, share..), for optional *entity_id* or *integration* (ftrack,..)'''
1533
- evt_data = dict(scope=scope, name=name)
1534
- if entity_id:
1535
- evt_data['ident'] = entity_id
1542
+ """
1543
+ Retrive *name* setting value for the given *entitytype* (workspace, job, volume, user, queue, ...) and
1544
+ *entityid* or *integration* (ftrack,..).
1545
+
1546
+ :param name: Setting name.
1547
+ :param entitytype: Entity type (workspace, job, volume, user, queue, ...).
1548
+ :param entityid: Entity ID (None for workspace entity type).
1549
+ :param integration: Integration name (ftrack, ..).
1550
+ :param data: Additional data to include in the request.
1551
+ :return: Setting value.
1552
+ """
1553
+ evt_data = dict(entitytype=entitytype, name=name)
1536
1554
  if integration:
1537
1555
  evt_data['integration'] = integration
1538
1556
  if evt_data:
1539
1557
  evt_data['data'] = data
1540
- response = self._event("GET", "setting", evt_data)
1558
+ response = self._event("GET", "setting", evt_data, entityid=entityid)
1541
1559
  return response.get("result")
1542
1560
 
1561
+ def get_settings(
1562
+ self,
1563
+ entitytype: Optional[str] = None,
1564
+ entityid: Optional[str] = None,
1565
+ recursive: bool = False,
1566
+ upstream: bool = False,
1567
+ omit_defaults: bool = True,
1568
+ share: Optional[str] = None,
1569
+ ) -> Dict[str, Any]:
1570
+ """
1571
+ Return settings JSON for an entity.
1572
+
1573
+ :param entitytype: Optional entity type (workspace, job, volume, user, queue, ...), defaults to 'workspace'.
1574
+ :param entityid: Optional entity ID, defaults to None.
1575
+ :param recursive: Include recursive settings lookup (for share trees, etc).
1576
+ :param upstream: Include inherited/upstream/default settings.
1577
+ :param omit_defaults: Omit unchanged defaults from response.
1578
+ :param share: Optional share ID/code used by some settings lookups.
1579
+ :return: Settings as a JSON-compatible dictionary.
1580
+ """
1581
+ if entitytype:
1582
+ entitytype = entitytype.lower().strip()
1583
+ payload: Dict[str, Any] = dict(
1584
+ entitytype=entitytype,
1585
+ recursive=recursive,
1586
+ upstream=upstream,
1587
+ omit_defaults=omit_defaults,
1588
+ )
1589
+ if share:
1590
+ payload["share"] = share
1591
+ response = self._event("GET", "setting", payload, entityid=entityid)
1592
+ return cast(Dict[str, Any], response.get("result") or {})
1593
+
1543
1594
  def set_setting(
1544
1595
  self,
1596
+ entitytype: str,
1545
1597
  name: str,
1546
- value: Any,
1547
- scope: str = 'workspace',
1548
- entity_id: Optional[str] = None,
1549
- integration: Optional[str] = None,
1550
- data: Optional[Dict[str, Any]] = None,
1551
- ) -> Optional[Any]:
1552
- '''Set the setting identified by *name* to *value* for *entity_id* within *scope*.'''
1553
- evt_data = dict(scope=scope, name=name, value=value)
1554
- if entity_id:
1555
- evt_data['ident'] = entity_id
1556
- if integration:
1557
- evt_data['integration'] = integration
1558
- if evt_data:
1559
- evt_data['data'] = data
1560
- response = self._event("PUT", "setting", evt_data)
1561
- return response.get("result")
1598
+ value: any,
1599
+ entityid: Optional[str] = None,
1600
+ ) -> bool:
1601
+ """
1602
+ Set a setting for an entity.
1603
+
1604
+ .. versionchanged:: 3.2
1605
+ Simplified to a single signature: ``set_setting(entitytype, entityid, name, value)``.
1606
+ Legacy compatibility argument patterns were removed.
1607
+
1608
+ :param entitytype: Entity type (workspace, job, volume, user, queue, ...)
1609
+ :param name: Setting name.
1610
+ :param value: Setting value, must be of string type. Dictionaries are supported, but must be converted to JSON string first. Serialise dates to ISO 8601 strings.
1611
+ :param entityid: Optional entity ID (None for workspace entity type, otherwise required).
1612
+ :return: True if setting was updated.
1613
+ """
1614
+ assert 0 < len(entitytype or "") and Session._is_str(
1615
+ entitytype
1616
+ ), "Invalid entity type supplied, must be of string type!"
1617
+ assert 0 < len(name or "") and Session._is_str(name), "Invalid name supplied, must be of string type!"
1618
+ assert value is not None and isinstance(value, str), "Invalid value supplied, must be of string type!"
1619
+ entitytype = entitytype.lower().strip()
1620
+ payload: Dict[str, Any] = dict(entitytype=entitytype, name=name, value=value)
1621
+ response = self._event("PUT", "setting", payload, entityid=entityid)
1622
+ return bool(response.get("result"))
1623
+
1624
+ def delete_setting(
1625
+ self,
1626
+ entitytype: str,
1627
+ name: str,
1628
+ entityid: Optional[str] = None,
1629
+ ) -> bool:
1630
+ """
1631
+ Delete a setting for an entity.
1632
+
1633
+ :param entitytype: Entity type (workspace, job, volume, user, queue, ...)
1634
+ :param name: Setting name.
1635
+ :param entityid: Optional entity ID (None for workspace entity type, otherwise required).
1636
+ :return: True if setting was deleted.
1637
+ """
1638
+ assert 0 < len(entitytype or "") and Session._is_str(
1639
+ entitytype
1640
+ ), "Invalid entity type supplied, must be of string type!"
1641
+ assert 0 < len(name or "") and Session._is_str(name), "Invalid name supplied, must be of string type!"
1642
+ entitytype = entitytype.lower().strip()
1643
+ payload: Dict[str, Any] = dict(entitytype=entitytype, name=name)
1644
+ response = self._event("DELETE", "setting", payload, entityid=entityid)
1645
+ return bool(response.get("result"))
1646
+
1562
1647
 
1563
1648
  # Misc
1564
1649
  def get_api_key(self) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: accsyn-python-api
3
- Version: 3.2.2
3
+ Version: 3.3.0
4
4
  Summary: A Python API for accsyn programmable fast and secure data delivery software
5
5
  Home-page: https://accsyn.com
6
6
  License: Apache-2.0
@@ -31,7 +31,7 @@ Description-Content-Type: text/markdown
31
31
  # accsyn-python-api
32
32
  Official accsyn fast and secure file delivery Python API
33
33
 
34
- Python API support can be found [here](https://support.accsyn.com/workflows/python-api).
34
+ Python API support can be found [here](https://support.accsyn.com/developer/python-api).
35
35
 
36
36
 
37
37
  Changelog:
@@ -0,0 +1,8 @@
1
+ accsyn_api/__init__.py,sha256=vSGlQJ7mqd5eE2vElmJ_hnvRy61FkMqFpUXyhhVapTY,121
2
+ accsyn_api/_devtools.py,sha256=nDhD_LKrgGvJXaXxP0RRPMugOLJKMxQkjr8K4gXyOKg,848
3
+ accsyn_api/_version.py,sha256=oF8V-dlyYy_uLbVNCbI3llxc1eMfvjBBvPc0ARG757E,94
4
+ accsyn_api/session.py,sha256=4h4NN5WLuslFbu9vbpb55CKC5gJCLT_mS0xo2Th9wfA,86881
5
+ accsyn_python_api-3.3.0.dist-info/METADATA,sha256=7Gkh7aY2zVtwVD9uopTcSZvOR5tS-BDrYADTUTMqoVw,4685
6
+ accsyn_python_api-3.3.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
7
+ accsyn_python_api-3.3.0.dist-info/entry_points.txt,sha256=i6jv25cTq1_QzeTlRV6MYIzsyfikRe1Bk4ETWkyXVqU,50
8
+ accsyn_python_api-3.3.0.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- accsyn_api/__init__.py,sha256=vSGlQJ7mqd5eE2vElmJ_hnvRy61FkMqFpUXyhhVapTY,121
2
- accsyn_api/_devtools.py,sha256=nDhD_LKrgGvJXaXxP0RRPMugOLJKMxQkjr8K4gXyOKg,848
3
- accsyn_api/_version.py,sha256=FAPvGtWlZPZwplaOxmuuURDf0qS9gD7HPSQ-hXF3amA,94
4
- accsyn_api/session.py,sha256=7ehUQUhCLKFw6Eon_oMVOXAKoKBf4TSdgrZzlk_odPI,82859
5
- accsyn_python_api-3.2.2.dist-info/METADATA,sha256=IvCOb508MNGeQWOO9cFXJj4nCvZrRi9zHQzMP3Z_48I,4685
6
- accsyn_python_api-3.2.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
7
- accsyn_python_api-3.2.2.dist-info/entry_points.txt,sha256=i6jv25cTq1_QzeTlRV6MYIzsyfikRe1Bk4ETWkyXVqU,50
8
- accsyn_python_api-3.2.2.dist-info/RECORD,,