accsyn-python-api 2.2.1__tar.gz → 3.0.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.0.0/PKG-INFO +56 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/README.md +7 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/release_notes.rst +7 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/setup.py +1 -1
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_api/session.py +150 -249
- accsyn-python-api-3.0.0/source/accsyn_python_api.egg-info/PKG-INFO +56 -0
- accsyn-python-api-2.2.1/PKG-INFO +0 -50
- accsyn-python-api-2.2.1/source/accsyn_python_api.egg-info/PKG-INFO +0 -50
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/.github/workflows/github-actions-black.yml +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/.gitignore +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/.pre-commit-config.yaml +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/.readthedocs.yaml +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/_static/accsyn.css +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/api_reference/index.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/api_reference/session.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/clients.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/conf.py +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/datatypes.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/file.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/glossary.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/index.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/installing.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/introduction.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/jobs.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/misc.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/publish.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/queues.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/render.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/requirements.txt +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/shares.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/users.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/doc/using.rst +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/pyproject.toml +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/readthedocs.yaml +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/setup.cfg +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_api/__init__.py +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_api/_version.py +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/SOURCES.txt +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/dependency_links.txt +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/requires.txt +0 -0
- {accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: accsyn-python-api
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: A Python API for accsyn programmable fast and secure data delivery software
|
|
5
|
+
Home-page: https://github.com/accsyn/accsyn-python-api.git
|
|
6
|
+
Author: Henrik Norin
|
|
7
|
+
Author-email: henrik.norin@accsyn.com
|
|
8
|
+
License: Apache License (2.0)
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=2.7.9, <4.0
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# accsyn-python-api
|
|
16
|
+
Official accsyn fast film delivery Python API
|
|
17
|
+
|
|
18
|
+
Complete Python API reference can be found [here](https://support.accsyn.com/python-api).
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Changelog:
|
|
22
|
+
----------
|
|
23
|
+
|
|
24
|
+
See doc/release_notes.rst
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Documentation:
|
|
28
|
+
--------------
|
|
29
|
+
|
|
30
|
+
[https://accsyn-python-api.readthedocs.io/en/latest](https://accsyn-python-api.readthedocs.io/en/latest)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Building:
|
|
34
|
+
---------
|
|
35
|
+
|
|
36
|
+
To build the documentation locally, run:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
cd doc
|
|
40
|
+
pip install -r requirements.txt
|
|
41
|
+
python -m sphinx -T -E -b html -d _build/doctrees -D language=en . ../dist/doc
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Deploying:
|
|
45
|
+
----------
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
python setup.py sdist bdist_wheel
|
|
49
|
+
twine upload --verbose --username accsyn dist/*
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Henrik Norin, HDR AB, 2023
|
|
53
|
+
accsyn(r) - secure data delivery and workflow sync
|
|
54
|
+
https://accsyn.com
|
|
55
|
+
https://support.accsyn.com
|
|
56
|
+
|
|
@@ -27,6 +27,13 @@ To build the documentation locally, run:
|
|
|
27
27
|
python -m sphinx -T -E -b html -d _build/doctrees -D language=en . ../dist/doc
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
Deploying:
|
|
31
|
+
----------
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
python setup.py sdist bdist_wheel
|
|
35
|
+
twine upload --verbose --username accsyn dist/*
|
|
36
|
+
```
|
|
30
37
|
|
|
31
38
|
Henrik Norin, HDR AB, 2023
|
|
32
39
|
accsyn(r) - secure data delivery and workflow sync
|
|
@@ -13,6 +13,13 @@ Release Notes
|
|
|
13
13
|
|
|
14
14
|
`https://support.accsyn.com <https://support.accsyn.com>`_.
|
|
15
15
|
|
|
16
|
+
.. release:: 3.0.0
|
|
17
|
+
:date: 2024-11-17
|
|
18
|
+
|
|
19
|
+
.. change:: feat
|
|
20
|
+
|
|
21
|
+
* Compliance with new accsyn v3 workspaces.
|
|
22
|
+
* Removed pwd and session key authentication, accsyn v3 only support API key basic auth.
|
|
16
23
|
|
|
17
24
|
.. release:: 2.2.0
|
|
18
25
|
:date: 2023-11-09
|
|
@@ -43,15 +43,16 @@ logging.basicConfig(
|
|
|
43
43
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
44
44
|
)
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
ACCSYN_BACKEND_DOMAIN = "accsyn.com"
|
|
47
|
+
ACCSYN_BACKEND_MASTER_HOSTNAME = "master.{}".format(ACCSYN_BACKEND_DOMAIN)
|
|
48
48
|
ACCSYN_PORT = 443
|
|
49
49
|
DEFAULT_EVENT_PAYLOAD_COMPRESS_SIZE_TRESHOLD = 100 * 1024 # Compress event data payloads above 100k
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
CLEARANCE_SUPPORT = "support"
|
|
52
52
|
CLEARANCE_ADMIN = "admin"
|
|
53
53
|
CLEARANCE_EMPLOYEE = "employee"
|
|
54
|
-
|
|
54
|
+
CLEARANCE_STANDARD = "standard"
|
|
55
|
+
CLEARANCE_CLIENT = CLEARANCE_STANDARD # BWCOMP
|
|
55
56
|
CLEARANCE_NONE = "none"
|
|
56
57
|
|
|
57
58
|
|
|
@@ -65,7 +66,7 @@ class JSONEncoder(json.JSONEncoder):
|
|
|
65
66
|
|
|
66
67
|
|
|
67
68
|
class JSONDecoder(json.JSONDecoder):
|
|
68
|
-
"""JSON
|
|
69
|
+
"""JSON deserialize."""
|
|
69
70
|
|
|
70
71
|
def decode(self, json_string):
|
|
71
72
|
json_data = json.loads(json_string)
|
|
@@ -116,6 +117,8 @@ class Session(object):
|
|
|
116
117
|
DEFAULT_CONNECT_TIMEOUT = 10 # Wait 10 seconds for connection
|
|
117
118
|
DEFAULT_TIMEOUT = 2 * 60 # Wait 2 minutes for response
|
|
118
119
|
|
|
120
|
+
_p_logfile = None
|
|
121
|
+
|
|
119
122
|
@property
|
|
120
123
|
def username(self):
|
|
121
124
|
return self._username
|
|
@@ -133,8 +136,6 @@ class Session(object):
|
|
|
133
136
|
domain=None,
|
|
134
137
|
username=None,
|
|
135
138
|
api_key=None,
|
|
136
|
-
pwd=None,
|
|
137
|
-
session_key=None,
|
|
138
139
|
hostname=None,
|
|
139
140
|
port=None,
|
|
140
141
|
proxy=None,
|
|
@@ -151,8 +152,6 @@ class Session(object):
|
|
|
151
152
|
:param domain: The accsyn domain (or read from ACCSYN_DOMAIN environment variable)
|
|
152
153
|
:param username: The accsyn username (or read from ACCSYN_API_USER environment variable)
|
|
153
154
|
:param api_key: The secret API key for authentication (or read from ACCSYN_API_KEY environment variable)
|
|
154
|
-
:param pwd: (No API key supplied) The secret password for authentication
|
|
155
|
-
:param session_key: (No API key or password supplied) The secret session key to use for authentication.
|
|
156
155
|
:param hostname: Override hostname/IP to connect to.
|
|
157
156
|
:param port: Override default port 443.
|
|
158
157
|
:param proxy: The proxy settings (or read from ACCSYN_PROXY environment variable).
|
|
@@ -165,16 +164,14 @@ class Session(object):
|
|
|
165
164
|
"""
|
|
166
165
|
# Generate a session ID
|
|
167
166
|
self.__version__ = __version__
|
|
168
|
-
self._pwd = None
|
|
169
167
|
self._session_id = str(uuid.uuid4())
|
|
170
|
-
self.
|
|
171
|
-
self._session_key_provided = None
|
|
168
|
+
self._uid = None
|
|
172
169
|
self._be_verbose = verbose
|
|
173
170
|
self._pretty_json = pretty_json
|
|
174
171
|
self._proxy = proxy
|
|
175
172
|
self._dev = dev is True or os.environ.get('ACCSYN_DEV', 'false') in ['true', '1']
|
|
176
173
|
Session._p_logfile = path_logfile
|
|
177
|
-
self.
|
|
174
|
+
self._role = CLEARANCE_NONE
|
|
178
175
|
self._verbose("Creating accsyn Python API session (v{})".format(__version__))
|
|
179
176
|
for key in os.environ:
|
|
180
177
|
if key.startswith("FILMHUB_"):
|
|
@@ -183,8 +180,6 @@ class Session(object):
|
|
|
183
180
|
if not (
|
|
184
181
|
"ACCSYN_DOMAIN" in os.environ
|
|
185
182
|
or "ACCSYN_ORG" in os.environ
|
|
186
|
-
or "FILMHUB_DOMAIN" in os.environ
|
|
187
|
-
or "FILMHUB_ORG" in os.environ
|
|
188
183
|
):
|
|
189
184
|
raise accsynException(
|
|
190
185
|
"Please supply your accsyn domain/organization or set " "ACCSYN_DOMAIN environment!"
|
|
@@ -194,52 +189,42 @@ class Session(object):
|
|
|
194
189
|
if "ACCSYN_DOMAIN" in os.environ
|
|
195
190
|
else os.environ.get(
|
|
196
191
|
"ACCSYN_ORG",
|
|
197
|
-
os.environ.get("FILMHUB_DOMAIN", os.environ.get("FILMHUB_ORG")),
|
|
198
192
|
)
|
|
199
193
|
)
|
|
200
194
|
if username is None:
|
|
201
|
-
if not ("ACCSYN_API_USER" in os.environ
|
|
195
|
+
if not ("ACCSYN_API_USER" in os.environ):
|
|
202
196
|
raise accsynException(
|
|
203
197
|
"Please supply your accsyn user name (E-mail) or set " "ACCSYN_API_USER environment!"
|
|
204
198
|
)
|
|
205
|
-
self._username = username or os.environ.get("ACCSYN_API_USER")
|
|
199
|
+
self._username = username or os.environ.get("ACCSYN_API_USER")
|
|
206
200
|
if api_key:
|
|
207
201
|
self._api_key = api_key
|
|
208
202
|
else:
|
|
209
|
-
self._api_key = os.environ.get("ACCSYN_API_KEY")
|
|
210
|
-
if
|
|
211
|
-
|
|
212
|
-
if 0 < len(session_key or ""):
|
|
213
|
-
# User has a session key for us to use, validate at login, store it
|
|
214
|
-
# temporarily
|
|
215
|
-
self._session_key_provided = session_key
|
|
216
|
-
elif len(self._api_key or "") == 0:
|
|
217
|
-
if 0 < len(pwd or ""):
|
|
218
|
-
# Store it temporarily
|
|
219
|
-
self._pwd = pwd
|
|
220
|
-
else:
|
|
221
|
-
raise accsynException("Please supply your accsyn API KEY or set ACCSYN_API_KEY " "environment!")
|
|
203
|
+
self._api_key = os.environ.get("ACCSYN_API_KEY")
|
|
204
|
+
if not self._api_key:
|
|
205
|
+
raise accsynException("Please supply your accsyn API KEY or set ACCSYN_API_KEY environment!")
|
|
222
206
|
self._hostname = hostname
|
|
223
|
-
self._port = port
|
|
207
|
+
self._port = port
|
|
224
208
|
self._timeout = timeout or Session.DEFAULT_TIMEOUT
|
|
225
209
|
self._connect_timeout = connect_timeout or Session.DEFAULT_CONNECT_TIMEOUT
|
|
226
210
|
if self._hostname is None:
|
|
227
211
|
if self._dev:
|
|
228
|
-
self._hostname = "
|
|
212
|
+
self._hostname = "127.0.0.1"
|
|
229
213
|
else:
|
|
230
214
|
# Get domain
|
|
231
215
|
result = self._rest(
|
|
232
216
|
"PUT",
|
|
233
|
-
|
|
234
|
-
"
|
|
235
|
-
{"
|
|
217
|
+
ACCSYN_BACKEND_MASTER_HOSTNAME,
|
|
218
|
+
"workspace/J3PKTtDvolDMBtTy6AFGA",
|
|
219
|
+
{"ident": self._domain},
|
|
236
220
|
)
|
|
237
221
|
# Store hostname
|
|
238
|
-
assert "
|
|
239
|
-
self._hostname = "
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
222
|
+
assert "hostname" in result, "No API endpoint hostname were provided for us!"
|
|
223
|
+
self._hostname = result["hostname"]
|
|
224
|
+
if self._port is None:
|
|
225
|
+
self._port = result["port"]
|
|
226
|
+
if self._port is None:
|
|
227
|
+
self._port = ACCSYN_PORT if not self._dev else 8181
|
|
243
228
|
self._last_message = None
|
|
244
229
|
self.login()
|
|
245
230
|
|
|
@@ -286,66 +271,32 @@ class Session(object):
|
|
|
286
271
|
"""Retreive error message from last API call."""
|
|
287
272
|
return self._last_message
|
|
288
273
|
|
|
289
|
-
def login(self
|
|
274
|
+
def login(self):
|
|
290
275
|
"""Attempt to login to accsyn and get a session."""
|
|
291
276
|
# TODO: Load session key from safe disk storage/key chain?
|
|
292
|
-
assert self.
|
|
293
|
-
|
|
294
|
-
|
|
277
|
+
assert self._uid is None, "Already logged in!"
|
|
278
|
+
payload = dict(
|
|
279
|
+
session_id=self._session_id,
|
|
280
|
+
)
|
|
281
|
+
headers = {
|
|
282
|
+
"Authorization": "basic {}:{}".format(
|
|
283
|
+
Session._base64_encode(self._username),
|
|
284
|
+
Session._base64_encode(self._api_key),
|
|
285
|
+
),
|
|
286
|
+
"X-Accsyn-Workspace": self._domain,
|
|
295
287
|
}
|
|
296
|
-
|
|
297
|
-
d["session_key_reuse"] = revive_session_key
|
|
298
|
-
if self._api_key:
|
|
299
|
-
headers = {
|
|
300
|
-
"Authorization": "ASCredentials {}".format(
|
|
301
|
-
Session._base64_encode(
|
|
302
|
-
'{"domain":"%s","username":"%s","api_key":"%s"}'
|
|
303
|
-
% (self._domain, self._username, self._api_key)
|
|
304
|
-
)
|
|
305
|
-
)
|
|
306
|
-
}
|
|
307
|
-
elif self._pwd:
|
|
308
|
-
headers = {
|
|
309
|
-
"Authorization": "ASCredentials {}".format(
|
|
310
|
-
Session._base64_encode(
|
|
311
|
-
'{"domain":"%s","username":"%s","pwd":"%s"}'
|
|
312
|
-
% (
|
|
313
|
-
self._domain,
|
|
314
|
-
self._username,
|
|
315
|
-
Session._base64_encode(self._pwd),
|
|
316
|
-
)
|
|
317
|
-
)
|
|
318
|
-
)
|
|
319
|
-
}
|
|
320
|
-
self._pwd = None # Forget this now
|
|
321
|
-
elif self._session_key_provided:
|
|
322
|
-
headers = {
|
|
323
|
-
"Authorization": "ASSession {}".format(
|
|
324
|
-
Session._base64_encode(
|
|
325
|
-
'{"domain":"%s","username":"%s","session_key":"%s"}'
|
|
326
|
-
% (
|
|
327
|
-
self._domain,
|
|
328
|
-
self._username,
|
|
329
|
-
self._session_key_provided,
|
|
330
|
-
)
|
|
331
|
-
)
|
|
332
|
-
)
|
|
333
|
-
}
|
|
334
|
-
self._session_key_provided = None # Forget this now
|
|
335
|
-
else:
|
|
336
|
-
raise Exception("No means of authentication available!")
|
|
337
|
-
result = self._rest(
|
|
288
|
+
response = self._rest(
|
|
338
289
|
"PUT",
|
|
339
290
|
self._hostname,
|
|
340
|
-
"/
|
|
341
|
-
|
|
291
|
+
"/api/login",
|
|
292
|
+
payload,
|
|
342
293
|
headers=headers,
|
|
343
294
|
port=self._port,
|
|
344
295
|
)
|
|
345
296
|
# Store session key
|
|
346
|
-
assert "
|
|
347
|
-
|
|
348
|
-
self.
|
|
297
|
+
assert "result" in response, "No result were provided!"
|
|
298
|
+
result = response["result"]
|
|
299
|
+
self._role = result["role"]
|
|
349
300
|
self._uid = result["id"]
|
|
350
301
|
return True
|
|
351
302
|
|
|
@@ -1046,19 +997,6 @@ class Session(object):
|
|
|
1046
997
|
"""Fetch API key, by default disabled in backend."""
|
|
1047
998
|
return self._event("GET", "user/api_key", {})["api_key"]
|
|
1048
999
|
|
|
1049
|
-
def get_session_key(self):
|
|
1050
|
-
"""Return the current API session key."""
|
|
1051
|
-
return self._session_key
|
|
1052
|
-
|
|
1053
|
-
def generate_session_key(self, lifetime=None):
|
|
1054
|
-
"""Generate a new API session key, with the given *lifetime*."""
|
|
1055
|
-
return self._event(
|
|
1056
|
-
"POST",
|
|
1057
|
-
"user/generate_session_key",
|
|
1058
|
-
{"lifetime": lifetime},
|
|
1059
|
-
query=self._username,
|
|
1060
|
-
)["session_key"]
|
|
1061
|
-
|
|
1062
1000
|
def gui_is_running(self):
|
|
1063
1001
|
"""
|
|
1064
1002
|
Check if a GUI is running on the same machine (hostname match) and with same username.
|
|
@@ -1168,7 +1106,7 @@ class Session(object):
|
|
|
1168
1106
|
if port is None:
|
|
1169
1107
|
port = self._port or ACCSYN_PORT
|
|
1170
1108
|
if hostname is None:
|
|
1171
|
-
hostname = "
|
|
1109
|
+
hostname = "{}.{}".format(self._domain, ACCSYN_BACKEND_DOMAIN)
|
|
1172
1110
|
# Proxy set?
|
|
1173
1111
|
proxy_type = None
|
|
1174
1112
|
proxy_hostname = None
|
|
@@ -1196,12 +1134,12 @@ class Session(object):
|
|
|
1196
1134
|
if proxy_type == "accsyn":
|
|
1197
1135
|
if proxy_port == -1:
|
|
1198
1136
|
proxy_port = 80
|
|
1199
|
-
self._verbose("Using accsyn proxy @
|
|
1137
|
+
self._verbose("Using accsyn proxy @ {}:{}".format(proxy_hostname, proxy_port))
|
|
1200
1138
|
hostname = proxy_hostname
|
|
1201
1139
|
port = proxy_port
|
|
1202
1140
|
elif proxy_type in ["socks", "socks5"]:
|
|
1203
1141
|
try:
|
|
1204
|
-
self._verbose("Using SOCKS5 proxy @
|
|
1142
|
+
self._verbose("Using SOCKS5 proxy @ {}:{}".format(proxy_hostname, proxy_port))
|
|
1205
1143
|
import socks
|
|
1206
1144
|
|
|
1207
1145
|
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, proxy_hostname, proxy_port)
|
|
@@ -1211,7 +1149,7 @@ class Session(object):
|
|
|
1211
1149
|
raise ie
|
|
1212
1150
|
elif proxy_type is not None:
|
|
1213
1151
|
raise accsynException('Unknown proxy type "{}"!'.format(proxy_type))
|
|
1214
|
-
url = "http{}://{}:{}/api/
|
|
1152
|
+
url = "http{}://{}:{}/api/v3{}".format(
|
|
1215
1153
|
"s" if ssl else "",
|
|
1216
1154
|
hostname,
|
|
1217
1155
|
port,
|
|
@@ -1224,155 +1162,118 @@ class Session(object):
|
|
|
1224
1162
|
# Wait 10s to reach machine, 2min for it to send back data
|
|
1225
1163
|
CONNECT_TO, READ_TO = (self.connect_timeout, timeout)
|
|
1226
1164
|
r = None
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1165
|
+
retval = None
|
|
1166
|
+
|
|
1167
|
+
if headers:
|
|
1168
|
+
headers_effective = copy.deepcopy(headers)
|
|
1169
|
+
else:
|
|
1170
|
+
headers_effective = {
|
|
1171
|
+
"Authorization": "basic {}:{}".format(
|
|
1172
|
+
Session._base64_encode(self._username),
|
|
1173
|
+
Session._base64_encode(self._api_key)
|
|
1174
|
+
),
|
|
1175
|
+
"X-Accsyn-Workspace": self._domain,
|
|
1176
|
+
}
|
|
1177
|
+
headers_effective["X-Accsyn-Device"] = "PythonAPI v%s @ %s %s(%s)" % (
|
|
1178
|
+
__version__,
|
|
1179
|
+
sys.platform,
|
|
1180
|
+
Session.get_hostname(),
|
|
1181
|
+
os.name,
|
|
1182
|
+
)
|
|
1183
|
+
if 3 <= sys.version_info.major:
|
|
1184
|
+
t_start = int(round(time.time() * 1000))
|
|
1185
|
+
else:
|
|
1186
|
+
t_start = long(round(time.time() * 1000))
|
|
1187
|
+
try:
|
|
1188
|
+
self._verbose(
|
|
1189
|
+
"REST %s %s, data: %s"
|
|
1190
|
+
% (
|
|
1191
|
+
method,
|
|
1192
|
+
url,
|
|
1193
|
+
data if not self._pretty_json else Session.str(data),
|
|
1194
|
+
)
|
|
1246
1195
|
)
|
|
1247
|
-
if
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
% (
|
|
1255
|
-
method,
|
|
1256
|
-
url,
|
|
1257
|
-
data if not self._pretty_json else Session.str(data),
|
|
1258
|
-
)
|
|
1196
|
+
if method.lower() == "get":
|
|
1197
|
+
r = requests.get(
|
|
1198
|
+
url,
|
|
1199
|
+
params=Session._url_quote(data),
|
|
1200
|
+
timeout=(CONNECT_TO, READ_TO),
|
|
1201
|
+
verify=False,
|
|
1202
|
+
headers=headers_effective,
|
|
1259
1203
|
)
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
)
|
|
1268
|
-
elif method.lower() == "put":
|
|
1269
|
-
r = requests.put(
|
|
1270
|
-
url,
|
|
1271
|
-
Session._safe_dumps(data),
|
|
1272
|
-
timeout=(CONNECT_TO, READ_TO),
|
|
1273
|
-
verify=False,
|
|
1274
|
-
headers=headers_effective,
|
|
1275
|
-
)
|
|
1276
|
-
elif method.lower() == "post":
|
|
1277
|
-
r = requests.post(
|
|
1278
|
-
url,
|
|
1279
|
-
Session._safe_dumps(data),
|
|
1280
|
-
timeout=(CONNECT_TO, READ_TO),
|
|
1281
|
-
verify=False,
|
|
1282
|
-
headers=headers_effective,
|
|
1283
|
-
)
|
|
1284
|
-
elif method.lower() == "delete":
|
|
1285
|
-
r = requests.delete(
|
|
1286
|
-
url,
|
|
1287
|
-
params=Session._url_quote(data),
|
|
1288
|
-
timeout=(CONNECT_TO, READ_TO),
|
|
1289
|
-
verify=False,
|
|
1290
|
-
headers=headers_effective,
|
|
1291
|
-
)
|
|
1292
|
-
t_end = int(round(time.time() * 1000))
|
|
1293
|
-
# break
|
|
1294
|
-
except BaseException:
|
|
1295
|
-
# if timeout <= 0:
|
|
1296
|
-
raise accsynException(
|
|
1297
|
-
"Could not reach {}:{}! Make sure cloud server({}) can"
|
|
1298
|
-
" be reached from you location and no firewall is "
|
|
1299
|
-
"blocking outgoing TCP traffic at port {}. "
|
|
1300
|
-
"Details: {}".format(
|
|
1301
|
-
hostname,
|
|
1302
|
-
port,
|
|
1303
|
-
hostname,
|
|
1304
|
-
port,
|
|
1305
|
-
traceback.format_exc() if not quiet else "(quiet)",
|
|
1306
|
-
)
|
|
1204
|
+
elif method.lower() == "put":
|
|
1205
|
+
r = requests.put(
|
|
1206
|
+
url,
|
|
1207
|
+
Session._safe_dumps(data),
|
|
1208
|
+
timeout=(CONNECT_TO, READ_TO),
|
|
1209
|
+
verify=False,
|
|
1210
|
+
headers=headers_effective,
|
|
1307
1211
|
)
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
method,
|
|
1334
|
-
Session._obscure_dict_string(
|
|
1335
|
-
Session._safely_printable(
|
|
1336
|
-
str(retval) if not self._pretty_json else Session.str(retval)
|
|
1337
|
-
).replace("'", '"')
|
|
1338
|
-
),
|
|
1339
|
-
t_start - t_end + 1,
|
|
1340
|
-
)
|
|
1341
|
-
)
|
|
1342
|
-
do_retry = False
|
|
1343
|
-
if not retval.get("message") is None:
|
|
1344
|
-
# Something went wrong
|
|
1345
|
-
if retval.get("session_expired") is True:
|
|
1346
|
-
if self._api_key is not None:
|
|
1347
|
-
# We should be able to get a new session and retry
|
|
1348
|
-
revive_session_key = self._session_key
|
|
1349
|
-
self._session_key = None
|
|
1350
|
-
self.login(revive_session_key=revive_session_key)
|
|
1351
|
-
self._info('Authenticated using API KEY and reused expired session...')
|
|
1352
|
-
do_retry = True
|
|
1353
|
-
if not do_retry:
|
|
1354
|
-
self._last_message = retval["message"]
|
|
1355
|
-
if not do_retry:
|
|
1356
|
-
break
|
|
1357
|
-
except BaseException:
|
|
1358
|
-
sys.stderr.write(traceback.format_exc())
|
|
1359
|
-
message = 'The {}:{}/{} REST {} {} operation failed! Details: '
|
|
1360
|
-
'{} {}'.format(
|
|
1212
|
+
elif method.lower() == "post":
|
|
1213
|
+
r = requests.post(
|
|
1214
|
+
url,
|
|
1215
|
+
Session._safe_dumps(data),
|
|
1216
|
+
timeout=(CONNECT_TO, READ_TO),
|
|
1217
|
+
verify=False,
|
|
1218
|
+
headers=headers_effective,
|
|
1219
|
+
)
|
|
1220
|
+
elif method.lower() == "delete":
|
|
1221
|
+
r = requests.delete(
|
|
1222
|
+
url,
|
|
1223
|
+
params=Session._url_quote(data),
|
|
1224
|
+
timeout=(CONNECT_TO, READ_TO),
|
|
1225
|
+
verify=False,
|
|
1226
|
+
headers=headers_effective,
|
|
1227
|
+
)
|
|
1228
|
+
t_end = int(round(time.time() * 1000))
|
|
1229
|
+
# break
|
|
1230
|
+
except BaseException:
|
|
1231
|
+
# if timeout <= 0:
|
|
1232
|
+
raise accsynException(
|
|
1233
|
+
"Could not reach {}:{}! Make sure backend({}) can"
|
|
1234
|
+
" be reached from you location and no firewall is "
|
|
1235
|
+
"blocking outgoing TCP traffic at port {}. "
|
|
1236
|
+
"Details: {}".format(
|
|
1361
1237
|
hostname,
|
|
1362
1238
|
port,
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1239
|
+
hostname,
|
|
1240
|
+
port,
|
|
1241
|
+
traceback.format_exc() if not quiet else "(quiet)",
|
|
1242
|
+
)
|
|
1243
|
+
)
|
|
1244
|
+
try:
|
|
1245
|
+
retval = json.loads(r.text, cls=JSONDecoder)
|
|
1246
|
+
if not quiet:
|
|
1247
|
+
self._verbose(
|
|
1248
|
+
"{}/{} REST {} result: {} (~{}ms)".format(
|
|
1249
|
+
hostname,
|
|
1250
|
+
uri,
|
|
1251
|
+
method,
|
|
1252
|
+
Session._obscure_dict_string(
|
|
1253
|
+
Session._safely_printable(
|
|
1254
|
+
str(retval) if not self._pretty_json else Session.str(retval)
|
|
1255
|
+
).replace("'", '"')
|
|
1256
|
+
),
|
|
1257
|
+
t_start - t_end + 1,
|
|
1258
|
+
)
|
|
1368
1259
|
)
|
|
1369
|
-
|
|
1370
|
-
|
|
1260
|
+
except BaseException:
|
|
1261
|
+
sys.stderr.write(traceback.format_exc())
|
|
1262
|
+
message = 'The {} REST {} {} operation failed! Details: {} {}'.format(
|
|
1263
|
+
url,
|
|
1264
|
+
method,
|
|
1265
|
+
Session._obscure_dict_string(Session._safely_printable(str(data)).replace("'", '"')),
|
|
1266
|
+
r.text,
|
|
1267
|
+
traceback.format_exc(),
|
|
1268
|
+
)
|
|
1269
|
+
Session._warning(message)
|
|
1270
|
+
raise accsynException(message)
|
|
1271
|
+
|
|
1371
1272
|
if "exception" in retval:
|
|
1372
1273
|
message = "{} caused an exception! Please contact {} admin for more"
|
|
1373
1274
|
" further support.".format(uri, self._domain)
|
|
1374
1275
|
Session._warning(message)
|
|
1375
|
-
if self.
|
|
1276
|
+
if self._role in [CLEARANCE_ADMIN, CLEARANCE_SUPPORT]:
|
|
1376
1277
|
Session._warning(retval["exception"])
|
|
1377
1278
|
raise accsynException(message)
|
|
1378
1279
|
elif "message" in retval:
|
|
@@ -1395,7 +1296,7 @@ class Session(object):
|
|
|
1395
1296
|
quiet=False,
|
|
1396
1297
|
):
|
|
1397
1298
|
"""Utility; Construct an event and send using REST to accsyn backend."""
|
|
1398
|
-
assert self.
|
|
1299
|
+
assert self._uid, "Login before posting event!"
|
|
1399
1300
|
event = {
|
|
1400
1301
|
"audience": "api",
|
|
1401
1302
|
"domain": self._domain,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: accsyn-python-api
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: A Python API for accsyn programmable fast and secure data delivery software
|
|
5
|
+
Home-page: https://github.com/accsyn/accsyn-python-api.git
|
|
6
|
+
Author: Henrik Norin
|
|
7
|
+
Author-email: henrik.norin@accsyn.com
|
|
8
|
+
License: Apache License (2.0)
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=2.7.9, <4.0
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# accsyn-python-api
|
|
16
|
+
Official accsyn fast film delivery Python API
|
|
17
|
+
|
|
18
|
+
Complete Python API reference can be found [here](https://support.accsyn.com/python-api).
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Changelog:
|
|
22
|
+
----------
|
|
23
|
+
|
|
24
|
+
See doc/release_notes.rst
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Documentation:
|
|
28
|
+
--------------
|
|
29
|
+
|
|
30
|
+
[https://accsyn-python-api.readthedocs.io/en/latest](https://accsyn-python-api.readthedocs.io/en/latest)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Building:
|
|
34
|
+
---------
|
|
35
|
+
|
|
36
|
+
To build the documentation locally, run:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
cd doc
|
|
40
|
+
pip install -r requirements.txt
|
|
41
|
+
python -m sphinx -T -E -b html -d _build/doctrees -D language=en . ../dist/doc
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Deploying:
|
|
45
|
+
----------
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
python setup.py sdist bdist_wheel
|
|
49
|
+
twine upload --verbose --username accsyn dist/*
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Henrik Norin, HDR AB, 2023
|
|
53
|
+
accsyn(r) - secure data delivery and workflow sync
|
|
54
|
+
https://accsyn.com
|
|
55
|
+
https://support.accsyn.com
|
|
56
|
+
|
accsyn-python-api-2.2.1/PKG-INFO
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: accsyn-python-api
|
|
3
|
-
Version: 2.2.1
|
|
4
|
-
Summary: A Python API for accsyn programmable fast and secure data delivery software
|
|
5
|
-
Home-page: https://github.com/accsyn/accsyn-python-api.git
|
|
6
|
-
Author: Henrik Norin
|
|
7
|
-
Author-email: henrik.norin@accsyn.com
|
|
8
|
-
License: Apache License (2.0)
|
|
9
|
-
Description: # accsyn-python-api
|
|
10
|
-
Official accsyn fast film delivery Python API
|
|
11
|
-
|
|
12
|
-
Complete Python API reference can be found [here](https://support.accsyn.com/python-api).
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Changelog:
|
|
16
|
-
----------
|
|
17
|
-
|
|
18
|
-
See doc/release_notes.rst
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Documentation:
|
|
22
|
-
--------------
|
|
23
|
-
|
|
24
|
-
[https://accsyn-python-api.readthedocs.io/en/latest](https://accsyn-python-api.readthedocs.io/en/latest)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Building:
|
|
28
|
-
---------
|
|
29
|
-
|
|
30
|
-
To build the documentation locally, run:
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
cd doc
|
|
34
|
-
pip install -r requirements.txt
|
|
35
|
-
python -m sphinx -T -E -b html -d _build/doctrees -D language=en . ../dist/doc
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Henrik Norin, HDR AB, 2023
|
|
40
|
-
accsyn(r) - secure data delivery and workflow sync
|
|
41
|
-
https://accsyn.com
|
|
42
|
-
https://support.accsyn.com
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Platform: UNKNOWN
|
|
46
|
-
Classifier: Programming Language :: Python :: 3
|
|
47
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
48
|
-
Classifier: Operating System :: OS Independent
|
|
49
|
-
Requires-Python: >=2.7.9, <4.0
|
|
50
|
-
Description-Content-Type: text/markdown
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: accsyn-python-api
|
|
3
|
-
Version: 2.2.1
|
|
4
|
-
Summary: A Python API for accsyn programmable fast and secure data delivery software
|
|
5
|
-
Home-page: https://github.com/accsyn/accsyn-python-api.git
|
|
6
|
-
Author: Henrik Norin
|
|
7
|
-
Author-email: henrik.norin@accsyn.com
|
|
8
|
-
License: Apache License (2.0)
|
|
9
|
-
Description: # accsyn-python-api
|
|
10
|
-
Official accsyn fast film delivery Python API
|
|
11
|
-
|
|
12
|
-
Complete Python API reference can be found [here](https://support.accsyn.com/python-api).
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Changelog:
|
|
16
|
-
----------
|
|
17
|
-
|
|
18
|
-
See doc/release_notes.rst
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Documentation:
|
|
22
|
-
--------------
|
|
23
|
-
|
|
24
|
-
[https://accsyn-python-api.readthedocs.io/en/latest](https://accsyn-python-api.readthedocs.io/en/latest)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Building:
|
|
28
|
-
---------
|
|
29
|
-
|
|
30
|
-
To build the documentation locally, run:
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
cd doc
|
|
34
|
-
pip install -r requirements.txt
|
|
35
|
-
python -m sphinx -T -E -b html -d _build/doctrees -D language=en . ../dist/doc
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Henrik Norin, HDR AB, 2023
|
|
40
|
-
accsyn(r) - secure data delivery and workflow sync
|
|
41
|
-
https://accsyn.com
|
|
42
|
-
https://support.accsyn.com
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Platform: UNKNOWN
|
|
46
|
-
Classifier: Programming Language :: Python :: 3
|
|
47
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
48
|
-
Classifier: Operating System :: OS Independent
|
|
49
|
-
Requires-Python: >=2.7.9, <4.0
|
|
50
|
-
Description-Content-Type: text/markdown
|
{accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/.github/workflows/github-actions-black.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/requires.txt
RENAMED
|
File without changes
|
{accsyn-python-api-2.2.1 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/top_level.txt
RENAMED
|
File without changes
|