accsyn-python-api 3.2.2__tar.gz → 3.3.0__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.
- {accsyn_python_api-3.2.2 → accsyn_python_api-3.3.0}/PKG-INFO +2 -2
- {accsyn_python_api-3.2.2 → accsyn_python_api-3.3.0}/README.md +1 -1
- {accsyn_python_api-3.2.2 → accsyn_python_api-3.3.0}/pyproject.toml +1 -1
- {accsyn_python_api-3.2.2 → accsyn_python_api-3.3.0}/source/accsyn_api/_version.py +1 -1
- {accsyn_python_api-3.2.2 → accsyn_python_api-3.3.0}/source/accsyn_api/session.py +122 -37
- {accsyn_python_api-3.2.2 → accsyn_python_api-3.3.0}/source/accsyn_api/__init__.py +0 -0
- {accsyn_python_api-3.2.2 → accsyn_python_api-3.3.0}/source/accsyn_api/_devtools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: accsyn-python-api
|
|
3
|
-
Version: 3.
|
|
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/
|
|
34
|
+
Python API support can be found [here](https://support.accsyn.com/developer/python-api).
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
Changelog:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# accsyn-python-api
|
|
2
2
|
Official accsyn fast and secure file delivery Python API
|
|
3
3
|
|
|
4
|
-
Python API support can be found [here](https://support.accsyn.com/
|
|
4
|
+
Python API support can be found [here](https://support.accsyn.com/developer/python-api).
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Changelog:
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "accsyn-python-api"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.3.0"
|
|
8
8
|
description = "A Python API for accsyn programmable fast and secure data delivery software"
|
|
9
9
|
authors = ["Henrik Norin <support@accsyn.com>"]
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -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
|
-
|
|
128
|
-
|
|
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}:
|
|
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
|
-
|
|
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
|
-
|
|
1528
|
-
|
|
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
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
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:
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
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:
|
|
File without changes
|
|
File without changes
|