accsyn-python-api 3.2.0__tar.gz → 3.2.2__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.0 → accsyn_python_api-3.2.2}/PKG-INFO +1 -1
- {accsyn_python_api-3.2.0 → accsyn_python_api-3.2.2}/pyproject.toml +1 -1
- {accsyn_python_api-3.2.0 → accsyn_python_api-3.2.2}/source/accsyn_api/_devtools.py +0 -1
- {accsyn_python_api-3.2.0 → accsyn_python_api-3.2.2}/source/accsyn_api/_version.py +1 -1
- {accsyn_python_api-3.2.0 → accsyn_python_api-3.2.2}/source/accsyn_api/session.py +125 -108
- {accsyn_python_api-3.2.0 → accsyn_python_api-3.2.2}/README.md +0 -0
- {accsyn_python_api-3.2.0 → accsyn_python_api-3.2.2}/source/accsyn_api/__init__.py +0 -0
|
@@ -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.2.
|
|
7
|
+
version = "3.2.2"
|
|
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"
|
|
@@ -63,14 +63,29 @@ CLIENT_STATE_OFFLINE = "offline"
|
|
|
63
63
|
CLIENT_STATE_DISABLED = "disabled"
|
|
64
64
|
CLIENT_STATE_DISABLED_OFFLINE = "disabled-offline"
|
|
65
65
|
|
|
66
|
-
JOB_TYPE_TRANSFER = 1
|
|
66
|
+
JOB_TYPE_TRANSFER = 1 # p2p transfer job, either standalone or beneath a delivery/request
|
|
67
67
|
JOB_TYPE_QUEUE = 2 # A job contai
|
|
68
|
-
JOB_TYPE_COMPUTE = 3
|
|
69
|
-
JOB_TYPE_DELIVERY =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
JOB_TYPE_COMPUTE = 3 # A compute/render job
|
|
69
|
+
JOB_TYPE_DELIVERY = (
|
|
70
|
+
7 # An outgoing delivery job, hold one or more upload jobs for managers and one download job per recipient
|
|
71
|
+
)
|
|
72
|
+
JOB_TYPE_REQUEST = (
|
|
73
|
+
8 # An inbound upload request, holds one upload job per recipient and then one or more download job for managers
|
|
74
|
+
)
|
|
75
|
+
JOB_TYPE_STREAM = 10 # An accsyn streaming delivery, same as delivery but containing one or more streamable media
|
|
76
|
+
|
|
77
|
+
UNIQUE_ENTITY_TYPES = [
|
|
78
|
+
"user",
|
|
79
|
+
"workspace",
|
|
80
|
+
"share",
|
|
81
|
+
"volume",
|
|
82
|
+
"folder",
|
|
83
|
+
"home",
|
|
84
|
+
"collection",
|
|
85
|
+
"site",
|
|
86
|
+
"engine",
|
|
87
|
+
"queue",
|
|
88
|
+
]
|
|
74
89
|
# Entity types were code is unique and can be used to find the entity by code
|
|
75
90
|
|
|
76
91
|
|
|
@@ -140,13 +155,13 @@ class JSONDecoder(json.JSONDecoder):
|
|
|
140
155
|
def _load_env_file(path: str, override: bool = False) -> None:
|
|
141
156
|
"""
|
|
142
157
|
Load environment variables from a .env file.
|
|
143
|
-
|
|
158
|
+
|
|
144
159
|
:param path: Path to the .env file
|
|
145
160
|
:param override: If True, override existing environment variables. If False, only set if not already set.
|
|
146
161
|
"""
|
|
147
162
|
if not os.path.exists(path):
|
|
148
163
|
return
|
|
149
|
-
|
|
164
|
+
|
|
150
165
|
try:
|
|
151
166
|
with open(path, "r", encoding="utf-8") as f:
|
|
152
167
|
for line in f:
|
|
@@ -154,24 +169,24 @@ def _load_env_file(path: str, override: bool = False) -> None:
|
|
|
154
169
|
line = line.strip()
|
|
155
170
|
if not line:
|
|
156
171
|
continue
|
|
157
|
-
|
|
172
|
+
|
|
158
173
|
# Skip comments (lines starting with #)
|
|
159
174
|
if line.startswith("#"):
|
|
160
175
|
continue
|
|
161
|
-
|
|
176
|
+
|
|
162
177
|
# Parse KEY=VALUE
|
|
163
178
|
if "=" in line:
|
|
164
179
|
key, value = line.split("=", 1)
|
|
165
180
|
key = key.strip()
|
|
166
181
|
value = value.strip()
|
|
167
|
-
|
|
182
|
+
|
|
168
183
|
# Remove quotes if present
|
|
169
184
|
if len(value) >= 2:
|
|
170
185
|
if (value.startswith('"') and value.endswith('"')) or (
|
|
171
186
|
value.startswith("'") and value.endswith("'")
|
|
172
187
|
):
|
|
173
188
|
value = value[1:-1]
|
|
174
|
-
|
|
189
|
+
|
|
175
190
|
# Only set if not already set (unless override=True)
|
|
176
191
|
if override or key not in os.environ:
|
|
177
192
|
os.environ[key] = value
|
|
@@ -408,12 +423,20 @@ class Session(object):
|
|
|
408
423
|
if isinstance(data, list):
|
|
409
424
|
data = dict(tasks=data)
|
|
410
425
|
assert data is not None and 0 < len(data), "Empty create data submitted!"
|
|
411
|
-
uri="create"
|
|
426
|
+
uri = "create"
|
|
412
427
|
if entitytype == "task" and "tasks" not in data:
|
|
413
428
|
data = dict(tasks=data)
|
|
414
429
|
if entitytype == "file":
|
|
415
|
-
uri="add"
|
|
416
|
-
if allow_duplicates is not None and entitytype in [
|
|
430
|
+
uri = "add"
|
|
431
|
+
if allow_duplicates is not None and entitytype in [
|
|
432
|
+
"transfer",
|
|
433
|
+
"compute",
|
|
434
|
+
"delivery",
|
|
435
|
+
"request",
|
|
436
|
+
"stream",
|
|
437
|
+
"job",
|
|
438
|
+
"task",
|
|
439
|
+
]:
|
|
417
440
|
data["allow_duplicates"] = allow_duplicates
|
|
418
441
|
d = self._event(
|
|
419
442
|
"POST",
|
|
@@ -439,7 +462,7 @@ class Session(object):
|
|
|
439
462
|
attributes: Optional[List[str]] = None,
|
|
440
463
|
finished: Optional[bool] = None,
|
|
441
464
|
inactive: Optional[bool] = None,
|
|
442
|
-
offline: Optional[bool] = None,
|
|
465
|
+
offline: Optional[bool] = None, # Deprecated, use inactive instead
|
|
443
466
|
archived: Optional[bool] = None,
|
|
444
467
|
limit: Optional[int] = None,
|
|
445
468
|
skip: Optional[int] = None,
|
|
@@ -569,7 +592,7 @@ class Session(object):
|
|
|
569
592
|
)
|
|
570
593
|
if result and 0 < len(result):
|
|
571
594
|
retval = result[0]
|
|
572
|
-
if 1<len(result):
|
|
595
|
+
if 1 < len(result):
|
|
573
596
|
Session._warning(f"Multiple entities retreived({len(result)}), returning first one.")
|
|
574
597
|
return retval
|
|
575
598
|
return None
|
|
@@ -596,7 +619,7 @@ class Session(object):
|
|
|
596
619
|
if not result:
|
|
597
620
|
return None
|
|
598
621
|
retval = result[0]
|
|
599
|
-
if 1<len(result):
|
|
622
|
+
if 1 < len(result):
|
|
600
623
|
Session._warning(f"Multiple entities retreived({len(result)}), returning first one.")
|
|
601
624
|
return retval
|
|
602
625
|
return None
|
|
@@ -637,12 +660,7 @@ class Session(object):
|
|
|
637
660
|
|
|
638
661
|
# Update an entity
|
|
639
662
|
|
|
640
|
-
def update(
|
|
641
|
-
self,
|
|
642
|
-
entitytype: str,
|
|
643
|
-
entityid: str,
|
|
644
|
-
data: Dict[str, Any]
|
|
645
|
-
) -> Optional[Dict[str, Any]]:
|
|
663
|
+
def update(self, entitytype: str, entityid: str, data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
646
664
|
"""
|
|
647
665
|
Update/modify an entity.
|
|
648
666
|
|
|
@@ -660,7 +678,9 @@ class Session(object):
|
|
|
660
678
|
assert 0 < len(entityid or "") and Session._is_str(
|
|
661
679
|
entityid
|
|
662
680
|
), "Invalid entity ID supplied, must be of string type!"
|
|
663
|
-
assert 0 < len(data or dict()) and isinstance(
|
|
681
|
+
assert 0 < len(data or dict()) and isinstance(
|
|
682
|
+
data, dict
|
|
683
|
+
), "Invalid data supplied, must be dict and have content!"
|
|
664
684
|
response = self._event(
|
|
665
685
|
"PUT",
|
|
666
686
|
f"{entitytype}/edit",
|
|
@@ -670,12 +690,7 @@ class Session(object):
|
|
|
670
690
|
if response:
|
|
671
691
|
return response["result"][0]
|
|
672
692
|
|
|
673
|
-
def update_one(
|
|
674
|
-
self,
|
|
675
|
-
entitytype: str,
|
|
676
|
-
entityid: str,
|
|
677
|
-
data: Dict[str, Any]
|
|
678
|
-
) -> Optional[Dict[str, Any]]:
|
|
693
|
+
def update_one(self, entitytype: str, entityid: str, data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
679
694
|
'''
|
|
680
695
|
Update/modify an entity.
|
|
681
696
|
|
|
@@ -692,10 +707,10 @@ class Session(object):
|
|
|
692
707
|
return self.update(entitytype, entityid, data)
|
|
693
708
|
|
|
694
709
|
def update_many(
|
|
695
|
-
self,
|
|
696
|
-
entitytype: str,
|
|
710
|
+
self,
|
|
711
|
+
entitytype: str,
|
|
697
712
|
entityid: str,
|
|
698
|
-
data: List[Dict[str, Any]],
|
|
713
|
+
data: List[Dict[str, Any]],
|
|
699
714
|
) -> Optional[List[Dict[str, Any]]]:
|
|
700
715
|
"""
|
|
701
716
|
Update/modify multiple entities - tasks beneath a job.
|
|
@@ -764,9 +779,13 @@ class Session(object):
|
|
|
764
779
|
if entitytype_parent in ["volume", "share"] and entitytype in ["server", "client"]:
|
|
765
780
|
# Assign a server to a share, expect share and client supplied
|
|
766
781
|
share_id = data.get("volume", data.get("share"))
|
|
767
|
-
assert re.match(
|
|
782
|
+
assert re.match(
|
|
783
|
+
"^[a-z0-9]{24}$", (share_id or "")
|
|
784
|
+
), "Please supply parent entity ID as 'volume' with assignment data!"
|
|
768
785
|
client_id = data.get("server", data.get("client"))
|
|
769
|
-
assert re.match(
|
|
786
|
+
assert re.match(
|
|
787
|
+
"^[a-z0-9]{24}$", (client_id or "")
|
|
788
|
+
), "Please supply entity ID as 'server' with assignment data!"
|
|
770
789
|
response = self._event(
|
|
771
790
|
"PUT",
|
|
772
791
|
f"share/server",
|
|
@@ -778,34 +797,38 @@ class Session(object):
|
|
|
778
797
|
elif entitytype_parent in ["delivery"] and entitytype in ["user"]:
|
|
779
798
|
# Assign a user to a delivery, expect delivery and user supplied
|
|
780
799
|
delivery_id = data.get("delivery")
|
|
781
|
-
assert re.match(
|
|
800
|
+
assert re.match(
|
|
801
|
+
"^[a-z0-9]{24}$", (delivery_id or "")
|
|
802
|
+
), "Please supply parent entity ID as 'delivery' with assignment data!"
|
|
782
803
|
user_id = data.get("user")
|
|
783
|
-
assert re.match(
|
|
804
|
+
assert re.match(
|
|
805
|
+
"^[a-z0-9]{24}$", (user_id or "")
|
|
806
|
+
), "Please supply entity ID as 'user' with assignment data!"
|
|
784
807
|
response = self._event(
|
|
785
808
|
"PUT",
|
|
786
809
|
f"job/recipient/add",
|
|
787
810
|
dict(recipient=user_id),
|
|
788
811
|
entityid=delivery_id,
|
|
789
812
|
)
|
|
790
|
-
elif entitytype_parent in ["volume","folder","home","collection"] and entitytype in ["user"]:
|
|
813
|
+
elif entitytype_parent in ["volume", "folder", "home", "collection"] and entitytype in ["user"]:
|
|
791
814
|
# Assign an employee user to a volume
|
|
792
815
|
volume_id = data.get("volume")
|
|
793
|
-
assert re.match(
|
|
816
|
+
assert re.match(
|
|
817
|
+
"^[a-z0-9]{24}$", (volume_id or "")
|
|
818
|
+
), "Please supply parent entity ID as 'volume' with assignment data!"
|
|
794
819
|
user_id = data.get("user")
|
|
795
|
-
assert re.match(
|
|
820
|
+
assert re.match(
|
|
821
|
+
"^[a-z0-9]{24}$", (user_id or "")
|
|
822
|
+
), "Please supply entity ID as 'user' with assignment data!"
|
|
796
823
|
payload = dict(
|
|
797
824
|
entity=f"user:{user_id}",
|
|
798
825
|
target=f"share:{volume_id}",
|
|
799
826
|
read=data.get("read", True),
|
|
800
827
|
write=data.get("write", True),
|
|
801
828
|
notify=data.get("notify", True),
|
|
802
|
-
message=data.get("message", "")
|
|
803
|
-
)
|
|
804
|
-
response = self._event(
|
|
805
|
-
"POST",
|
|
806
|
-
f"acl/create",
|
|
807
|
-
payload
|
|
829
|
+
message=data.get("message", ""),
|
|
808
830
|
)
|
|
831
|
+
response = self._event("POST", f"acl/create", payload)
|
|
809
832
|
if response is not None:
|
|
810
833
|
return response["result"]
|
|
811
834
|
else:
|
|
@@ -825,7 +848,7 @@ class Session(object):
|
|
|
825
848
|
assert 0 < len(entitytype or "") and Session._is_str(
|
|
826
849
|
entitytype
|
|
827
850
|
), "Invalid parent entity type supplied, must be of string type!"
|
|
828
|
-
if entitytype.lower() in ["volume", "share"]:
|
|
851
|
+
if entitytype.lower() in ["volume", "share"]: # share is deprecated since 3.2
|
|
829
852
|
# List servers assigned to a volume
|
|
830
853
|
response = self._event(
|
|
831
854
|
"GET",
|
|
@@ -868,9 +891,13 @@ class Session(object):
|
|
|
868
891
|
if entitytype_parent in ["volume", "share"] and entitytype == "server":
|
|
869
892
|
# Assign a server to a share, expect share and client supplied
|
|
870
893
|
share_id = data.get("volume", data.get("share"))
|
|
871
|
-
assert re.match(
|
|
894
|
+
assert re.match(
|
|
895
|
+
"^[a-z0-9]{24}$", (share_id or "")
|
|
896
|
+
), "Please supply parent entity ID as 'volume' with de-assignment data!"
|
|
872
897
|
client_id = data.get("server", data.get("client"))
|
|
873
|
-
assert re.match(
|
|
898
|
+
assert re.match(
|
|
899
|
+
"^[a-z0-9]{24}$", (client_id or "")
|
|
900
|
+
), "Please supply entity ID as 'server' with de-assignment data!"
|
|
874
901
|
response = self._event(
|
|
875
902
|
"DELETE",
|
|
876
903
|
f"{entitytype_parent}/server",
|
|
@@ -882,7 +909,7 @@ class Session(object):
|
|
|
882
909
|
else:
|
|
883
910
|
raise AccsynException("Unsupported assignment operation!")
|
|
884
911
|
|
|
885
|
-
|
|
912
|
+
# Entity access grant / revocation
|
|
886
913
|
|
|
887
914
|
def grant(
|
|
888
915
|
self,
|
|
@@ -921,13 +948,15 @@ class Session(object):
|
|
|
921
948
|
f"{entitytype}/find",
|
|
922
949
|
query=f"code='{entityid}'",
|
|
923
950
|
)
|
|
924
|
-
if 0<len(response.get("result", [])):
|
|
951
|
+
if 0 < len(response.get("result", [])):
|
|
925
952
|
# Use the correct ID
|
|
926
953
|
entityid = response["result"][0]["id"]
|
|
927
954
|
else:
|
|
928
955
|
# Allow this - user will be invited
|
|
929
956
|
if (data or dict()).get("invite", True) is False:
|
|
930
|
-
raise AccsynException(
|
|
957
|
+
raise AccsynException(
|
|
958
|
+
f"No {entitytype} found with code '{entityid}', and invite is not allowed!"
|
|
959
|
+
)
|
|
931
960
|
else:
|
|
932
961
|
Session._warning(f"No {entitytype} found with code '{entityid}', will be invited!")
|
|
933
962
|
else:
|
|
@@ -955,7 +984,7 @@ class Session(object):
|
|
|
955
984
|
raise AccsynException(f"Please supply a valid {targettype} ID!")
|
|
956
985
|
result = None
|
|
957
986
|
if entitytype == "user":
|
|
958
|
-
if targettype in ["delivery","request","stream"]:
|
|
987
|
+
if targettype in ["delivery", "request", "stream"]:
|
|
959
988
|
# Assign a user to a delivery, expect delivery and user supplied
|
|
960
989
|
user_id = entityid
|
|
961
990
|
delivery_id = targetid
|
|
@@ -970,7 +999,7 @@ class Session(object):
|
|
|
970
999
|
entityid=delivery_id,
|
|
971
1000
|
)
|
|
972
1001
|
result = response["result"]
|
|
973
|
-
elif targettype in ["volume","folder","home","collection"]:
|
|
1002
|
+
elif targettype in ["volume", "folder", "home", "collection"]:
|
|
974
1003
|
# Assign an employee user to a volume
|
|
975
1004
|
assert (
|
|
976
1005
|
data is not None and isinstance(data, dict) and (0 < len(data or dict()))
|
|
@@ -988,11 +1017,7 @@ class Session(object):
|
|
|
988
1017
|
)
|
|
989
1018
|
if (data or dict()).get("invite", True) is False:
|
|
990
1019
|
payload["invite"] = False
|
|
991
|
-
response = self._event(
|
|
992
|
-
"POST",
|
|
993
|
-
f"acl/create",
|
|
994
|
-
payload
|
|
995
|
-
)
|
|
1020
|
+
response = self._event("POST", f"acl/create", payload)
|
|
996
1021
|
result = response["result"][0]
|
|
997
1022
|
if result is not None:
|
|
998
1023
|
return result
|
|
@@ -1031,7 +1056,7 @@ class Session(object):
|
|
|
1031
1056
|
entityid=targetid,
|
|
1032
1057
|
)
|
|
1033
1058
|
return response["result"]
|
|
1034
|
-
elif targettype.lower() in ["volume", "folder", "home","collection"]:
|
|
1059
|
+
elif targettype.lower() in ["volume", "folder", "home", "collection"]:
|
|
1035
1060
|
# List users with access to a share
|
|
1036
1061
|
response = self._event(
|
|
1037
1062
|
"GET",
|
|
@@ -1041,27 +1066,23 @@ class Session(object):
|
|
|
1041
1066
|
)
|
|
1042
1067
|
result = []
|
|
1043
1068
|
for acl in response["result"]:
|
|
1044
|
-
result.append(
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1069
|
+
result.append(
|
|
1070
|
+
dict(
|
|
1071
|
+
user=acl["entity"].split(":")[1],
|
|
1072
|
+
user_hr=acl.get("entity_hr", ""),
|
|
1073
|
+
share=acl["target"].split(":")[1],
|
|
1074
|
+
share_hr=acl.get("target_hr", ""),
|
|
1075
|
+
read=acl["read"],
|
|
1076
|
+
write=acl["write"],
|
|
1077
|
+
acknowledged=acl.get("acknowledged", False),
|
|
1078
|
+
path=acl.get("path", "/"),
|
|
1079
|
+
)
|
|
1080
|
+
)
|
|
1054
1081
|
return result
|
|
1055
1082
|
else:
|
|
1056
1083
|
raise AccsynException("Unsupported access operation!")
|
|
1057
1084
|
|
|
1058
|
-
def revoke(
|
|
1059
|
-
self,
|
|
1060
|
-
entitytype: str,
|
|
1061
|
-
entityid: str,
|
|
1062
|
-
targettype: str,
|
|
1063
|
-
targetid: str
|
|
1064
|
-
) -> bool:
|
|
1085
|
+
def revoke(self, entitytype: str, entityid: str, targettype: str, targetid: str) -> bool:
|
|
1065
1086
|
"""
|
|
1066
1087
|
Revoke access to an entity.
|
|
1067
1088
|
|
|
@@ -1090,7 +1111,7 @@ class Session(object):
|
|
|
1090
1111
|
f"{entitytype}/find",
|
|
1091
1112
|
query=f"code='{entityid}'",
|
|
1092
1113
|
)
|
|
1093
|
-
if 0<len(response.get("result", [])):
|
|
1114
|
+
if 0 < len(response.get("result", [])):
|
|
1094
1115
|
# Use the correct ID
|
|
1095
1116
|
entityid = response["result"][0]["id"]
|
|
1096
1117
|
else:
|
|
@@ -1118,12 +1139,14 @@ class Session(object):
|
|
|
1118
1139
|
dict(recipient=user_id),
|
|
1119
1140
|
entityid=delivery_id,
|
|
1120
1141
|
)
|
|
1121
|
-
elif targettype in ["volume","folder","home","collection"] and entitytype == "user":
|
|
1142
|
+
elif targettype in ["volume", "folder", "home", "collection"] and entitytype == "user":
|
|
1122
1143
|
# Revoke user access from a share
|
|
1123
1144
|
share_id = targetid
|
|
1124
1145
|
user_id = entityid
|
|
1125
1146
|
# First, located the ACL
|
|
1126
|
-
response = self._event(
|
|
1147
|
+
response = self._event(
|
|
1148
|
+
"GET", f"acl/find", dict(), query=f"acl WHERE entity=user:{user_id} AND target=share:{share_id}"
|
|
1149
|
+
)
|
|
1127
1150
|
acls = response["result"]
|
|
1128
1151
|
if len(acls) == 0:
|
|
1129
1152
|
raise AccsynException(f"No ACL found for user {user_id} and share {share_id}")
|
|
@@ -1138,7 +1161,6 @@ class Session(object):
|
|
|
1138
1161
|
else:
|
|
1139
1162
|
raise AccsynException("Unsupported revoke access operation!")
|
|
1140
1163
|
|
|
1141
|
-
|
|
1142
1164
|
# Deactivate/Delete an entity
|
|
1143
1165
|
|
|
1144
1166
|
def offline_one(self, entitytype: str, entityid: str) -> Any:
|
|
@@ -1224,7 +1246,9 @@ class Session(object):
|
|
|
1224
1246
|
), "Invalid entity ID supplied, must be of string type!"
|
|
1225
1247
|
if not re.match("^[a-z0-9]{24}$", (entityid or "")):
|
|
1226
1248
|
raise AccsynException("Invalid parent entity ID supplied!")
|
|
1227
|
-
assert 0 < len(data or dict()) and isinstance(
|
|
1249
|
+
assert 0 < len(data or dict()) and isinstance(
|
|
1250
|
+
data, dict
|
|
1251
|
+
), "Invalid data supplied, must be dict and have content!"
|
|
1228
1252
|
if entitytype == "collection":
|
|
1229
1253
|
uri = "file/remove"
|
|
1230
1254
|
else:
|
|
@@ -1258,7 +1282,7 @@ class Session(object):
|
|
|
1258
1282
|
f"{entitytype}/activate",
|
|
1259
1283
|
dict(),
|
|
1260
1284
|
entityid=entityident if re.match("^[a-z0-9]{24}$", (entityident or "")) else None,
|
|
1261
|
-
query=entityident if not re.match("^[a-z0-9]{24}$", (entityident or "")) else None
|
|
1285
|
+
query=entityident if not re.match("^[a-z0-9]{24}$", (entityident or "")) else None,
|
|
1262
1286
|
)
|
|
1263
1287
|
if response:
|
|
1264
1288
|
return response["result"]
|
|
@@ -1298,13 +1322,7 @@ class Session(object):
|
|
|
1298
1322
|
assert 0 < len(path or "") and (
|
|
1299
1323
|
Session._is_str(path) or isinstance(path, dict) or isinstance(path, list)
|
|
1300
1324
|
), "No path supplied, or not a string/list/dict!"
|
|
1301
|
-
data = dict(
|
|
1302
|
-
op="ls",
|
|
1303
|
-
path=path,
|
|
1304
|
-
download=True,
|
|
1305
|
-
recursive=recursive,
|
|
1306
|
-
getsize=getsize
|
|
1307
|
-
)
|
|
1325
|
+
data = dict(op="ls", path=path, download=True, recursive=recursive, getsize=getsize)
|
|
1308
1326
|
if maxdepth:
|
|
1309
1327
|
data["maxdepth"] = maxdepth
|
|
1310
1328
|
if directories_only:
|
|
@@ -1353,9 +1371,7 @@ class Session(object):
|
|
|
1353
1371
|
if response:
|
|
1354
1372
|
return response["result"]
|
|
1355
1373
|
|
|
1356
|
-
def exists(
|
|
1357
|
-
self, path: Union[str, Dict[str, Any], List[str]]
|
|
1358
|
-
) -> Optional[bool]:
|
|
1374
|
+
def exists(self, path: Union[str, Dict[str, Any], List[str]]) -> Optional[bool]:
|
|
1359
1375
|
"""
|
|
1360
1376
|
Check if a file or directory exists.
|
|
1361
1377
|
|
|
@@ -1373,9 +1389,7 @@ class Session(object):
|
|
|
1373
1389
|
if response:
|
|
1374
1390
|
return response["result"]
|
|
1375
1391
|
|
|
1376
|
-
def mkdir(
|
|
1377
|
-
self, path: Union[str, Dict[str, Any], List[str]]
|
|
1378
|
-
) -> Optional[Any]:
|
|
1392
|
+
def mkdir(self, path: Union[str, Dict[str, Any], List[str]]) -> Optional[Any]:
|
|
1379
1393
|
"""
|
|
1380
1394
|
Create a directory on a share.
|
|
1381
1395
|
|
|
@@ -1454,7 +1468,8 @@ class Session(object):
|
|
|
1454
1468
|
return response["result"]
|
|
1455
1469
|
|
|
1456
1470
|
def delete(
|
|
1457
|
-
self,
|
|
1471
|
+
self,
|
|
1472
|
+
path: Union[str, Dict[str, Any], List[str]],
|
|
1458
1473
|
force: bool = False,
|
|
1459
1474
|
) -> Optional[Any]:
|
|
1460
1475
|
"""
|
|
@@ -1602,9 +1617,7 @@ class Session(object):
|
|
|
1602
1617
|
break
|
|
1603
1618
|
return retval
|
|
1604
1619
|
|
|
1605
|
-
def integration(
|
|
1606
|
-
self, name: str, operation: str, data: Dict[str, Any]
|
|
1607
|
-
) -> Any:
|
|
1620
|
+
def integration(self, name: str, operation: str, data: Dict[str, Any]) -> Any:
|
|
1608
1621
|
'''Make an integration utility call for integration pointed out by *name* and providing the *operation* as string and *data* as a dictionary'''
|
|
1609
1622
|
assert len(name) > 0, 'No name provided'
|
|
1610
1623
|
assert len(operation) > 0, 'No operation provided'
|
|
@@ -1620,15 +1633,17 @@ class Session(object):
|
|
|
1620
1633
|
# Help
|
|
1621
1634
|
def help(self) -> None:
|
|
1622
1635
|
documentation_url = "https://accsyn-python-api.readthedocs.io/en/latest/"
|
|
1623
|
-
print(
|
|
1624
|
-
|
|
1636
|
+
print(
|
|
1637
|
+
f"Please have a look at the Python API reference: {documentation_url}, attempting to open in default browser..."
|
|
1638
|
+
)
|
|
1639
|
+
# Open the documentation url in the browser
|
|
1625
1640
|
webbrowser.open(documentation_url)
|
|
1626
|
-
|
|
1641
|
+
|
|
1627
1642
|
@staticmethod
|
|
1628
1643
|
def str(d: Optional[Dict[str, Any]], indent: int = 4) -> str:
|
|
1629
1644
|
"""
|
|
1630
1645
|
Return a string representation of an dictionary.
|
|
1631
|
-
|
|
1646
|
+
|
|
1632
1647
|
.. deprecated:: 3.2.0
|
|
1633
1648
|
Use the :func:`dump` function instead
|
|
1634
1649
|
"""
|
|
@@ -1639,7 +1654,7 @@ class Session(object):
|
|
|
1639
1654
|
def dump(d: Optional[Dict[str, Any]], indent: int = 4) -> str:
|
|
1640
1655
|
"""
|
|
1641
1656
|
Return a string representation of an dictionary.
|
|
1642
|
-
|
|
1657
|
+
|
|
1643
1658
|
.. versionchanged:: 3.2.0
|
|
1644
1659
|
Was 'str' function.
|
|
1645
1660
|
|
|
@@ -1738,7 +1753,9 @@ class Session(object):
|
|
|
1738
1753
|
try:
|
|
1739
1754
|
import socks
|
|
1740
1755
|
except ImportError as ie:
|
|
1741
|
-
logging.error(
|
|
1756
|
+
logging.error(
|
|
1757
|
+
"Socks module is not installed, please install it with 'pip install socks' or add it to your PYTHONPATH"
|
|
1758
|
+
)
|
|
1742
1759
|
raise ie
|
|
1743
1760
|
|
|
1744
1761
|
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, proxy_hostname, proxy_port)
|
|
File without changes
|
|
File without changes
|