accsyn-python-api 2.2.0__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-3.0.0/README.md +42 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/file.rst +23 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/release_notes.rst +7 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/setup.py +1 -1
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/source/accsyn_api/_version.py +1 -1
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/source/accsyn_api/session.py +159 -264
- accsyn-python-api-3.0.0/source/accsyn_python_api.egg-info/PKG-INFO +56 -0
- accsyn-python-api-2.2.0/PKG-INFO +0 -32
- accsyn-python-api-2.2.0/README.md +0 -17
- accsyn-python-api-2.2.0/source/accsyn_python_api.egg-info/PKG-INFO +0 -32
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/.github/workflows/github-actions-black.yml +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/.gitignore +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/.pre-commit-config.yaml +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/.readthedocs.yaml +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/_static/accsyn.css +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/api_reference/index.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/api_reference/session.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/clients.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/conf.py +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/datatypes.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/glossary.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/index.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/installing.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/introduction.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/jobs.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/misc.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/publish.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/queues.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/render.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/requirements.txt +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/shares.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/users.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/doc/using.rst +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/pyproject.toml +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/readthedocs.yaml +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/setup.cfg +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/source/accsyn_api/__init__.py +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/SOURCES.txt +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/dependency_links.txt +0 -0
- {accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/requires.txt +0 -0
- {accsyn-python-api-2.2.0 → 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
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# accsyn-python-api
|
|
2
|
+
Official accsyn fast film delivery Python API
|
|
3
|
+
|
|
4
|
+
Complete Python API reference can be found [here](https://support.accsyn.com/python-api).
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Changelog:
|
|
8
|
+
----------
|
|
9
|
+
|
|
10
|
+
See doc/release_notes.rst
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Documentation:
|
|
14
|
+
--------------
|
|
15
|
+
|
|
16
|
+
[https://accsyn-python-api.readthedocs.io/en/latest](https://accsyn-python-api.readthedocs.io/en/latest)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
Building:
|
|
20
|
+
---------
|
|
21
|
+
|
|
22
|
+
To build the documentation locally, run:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
cd doc
|
|
26
|
+
pip install -r requirements.txt
|
|
27
|
+
python -m sphinx -T -E -b html -d _build/doctrees -D language=en . ../dist/doc
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Deploying:
|
|
31
|
+
----------
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
python setup.py sdist bdist_wheel
|
|
35
|
+
twine upload --verbose --username accsyn dist/*
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Henrik Norin, HDR AB, 2023
|
|
39
|
+
accsyn(r) - secure data delivery and workflow sync
|
|
40
|
+
https://accsyn.com
|
|
41
|
+
https://support.accsyn.com
|
|
42
|
+
|
|
@@ -25,6 +25,8 @@ Optional arguments:
|
|
|
25
25
|
* ``directories_only``: Return only directories in listing, True or False. Default is False.
|
|
26
26
|
* ``files_only``: Return only files in listing, True or False. Default is False. Note: Providing recursive=True won't have any affect.
|
|
27
27
|
* ``getsize``: Calculate and return size of directories.
|
|
28
|
+
* ``include``: Filter expression (string or list) dictating what to include in result: "word" - exact match, "*word" - ends with word, "word*" - starts with word, "*word*" - contains word, "start*end" - starts & ends with word and "re('...')" - regular expression. Has precedence over *exclude*.
|
|
29
|
+
* ``exclude``:Filter expression (string or list) dictating what to exclude from result: "word" - exact match, "*word" - ends with word, "word*" - starts with word, "*word*" - contains word, "start*end" - starts & ends with word and "re('...')" - regular expression.
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
|
|
@@ -69,6 +71,27 @@ If succeeds, this will return a list of dictionaries, one for each file found, w
|
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
|
|
74
|
+
|
|
75
|
+
To search a directory, and its sub-directories, for files with a specific name, use the ``include`` argument::
|
|
76
|
+
|
|
77
|
+
session.ls("share=Documentation", include="FindMe.doc", recursive=True)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
To exclude files matching a regular expression, use the ``exclude`` argument::
|
|
81
|
+
|
|
82
|
+
session.ls("share=Documentation", exclude="re('_Draft.*')")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
To make it case insensitive::
|
|
86
|
+
|
|
87
|
+
session.ls("share=thefilm-DIT/TO_ACMEFILM", exclude="re('_draft.*', 'I')")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
.. note::
|
|
91
|
+
|
|
92
|
+
Include and exclude can be combined, include has precedence over exclude.
|
|
93
|
+
|
|
94
|
+
|
|
72
95
|
Failure scenarios
|
|
73
96
|
*****************
|
|
74
97
|
|
|
@@ -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
|
|
|
@@ -818,18 +769,15 @@ class Session(object):
|
|
|
818
769
|
:param getsize: If True - file sizes will be returned.
|
|
819
770
|
:param files_only: If True - only return files, no directories.
|
|
820
771
|
:param directories_only: If True - only return directories, no files.
|
|
821
|
-
:param include: Filter expression (string or list) dictating what to include in result: "word" - exact match,
|
|
822
|
-
"*word" - ends with word, "word*" - starts with word, "*word*" - contains word and "re('...')" - regular
|
|
823
|
-
expression. Has precedence over *exclude*.
|
|
824
|
-
:param exclude: Filter expression (string or list) dictating what to exclude from result: "word" - exact match,
|
|
825
|
-
"*word" - ends with word, "word*" - starts with word, "*word*" - contains word and "re('...')" - regular
|
|
826
|
-
expression.
|
|
772
|
+
:param include: Filter expression (string or list) dictating what to include in result: "word" - exact match, "*word" - ends with word, "word*" - starts with word, "*word*" - contains word, "start*end" - starts & ends with word and "re('...')" - regular expression. Has precedence over *exclude*.
|
|
773
|
+
:param exclude: Filter expression (string or list) dictating what to exclude from result: "word" - exact match, "*word" - ends with word, "word*" - starts with word, "*word*" - contains word, "start*end" - starts & ends with word and "re('...')" - regular expression.
|
|
827
774
|
:return: A dictionary containing result of file listing.
|
|
828
775
|
|
|
829
776
|
Include and exclude filters are case-insensitive, to make regular expression case-sensitive, use the following
|
|
830
777
|
syntax: "re('...', 'I')".
|
|
831
778
|
|
|
832
|
-
.. versionadded:: 2.6-20
|
|
779
|
+
.. versionadded:: 2.2.0 (app/daemon: 2.6-20)
|
|
780
|
+
|
|
833
781
|
"""
|
|
834
782
|
assert 0 < len(path or "") and (
|
|
835
783
|
Session._is_str(path) or isinstance(path, dict) or isinstance(path, list)
|
|
@@ -860,17 +808,14 @@ class Session(object):
|
|
|
860
808
|
Get size of a file or directory.
|
|
861
809
|
|
|
862
810
|
:param path: The accsyn path, on the form 'share=<the share>/<path>/<somewhere>'.
|
|
863
|
-
:param include: Filter expression (string or list) dictating what to include in result: "word" - exact match,
|
|
864
|
-
"*word" - ends with word, "word*" - starts with word, "*word*" - contains word and "re('...')" - regular
|
|
865
|
-
|
|
866
|
-
:param exclude: Filter expression (string or list) dictating what to exclude from result: "word" - exact match,
|
|
867
|
-
"*word" - ends with word, "word*" - starts with word, "*word*" - contains word and "re('...')" - regular
|
|
868
|
-
expression.
|
|
869
|
-
|
|
870
|
-
:return: A number representing the file size.
|
|
811
|
+
:param include: Filter expression (string or list) dictating what to include in result: "word" - exact match, "*word" - ends with word, "word*" - starts with word, "*word*" - contains word, "start*end" - starts & ends with word and "re('...')" - regular expression. Has precedence over *exclude*.
|
|
812
|
+
:param exclude: Filter expression (string or list) dictating what to exclude from result: "word" - exact match, "*word" - ends with word, "word*" - starts with word, "*word*" - contains word, "start*end" - starts & ends with word and "re('...')" - regular expression.
|
|
813
|
+
:return: A dictionary containing result of file listing.
|
|
871
814
|
|
|
872
815
|
Include and exclude filters are case-insensitive, to make regular expression case-sensitive, use the following
|
|
873
816
|
syntax: "re('...', 'I')".
|
|
817
|
+
|
|
818
|
+
.. versionadded:: 2.2.0 (app/daemon: 2.6-20)
|
|
874
819
|
"""
|
|
875
820
|
assert 0 < len(path or "") and (
|
|
876
821
|
Session._is_str(path) or isinstance(path, dict) or isinstance(path, list)
|
|
@@ -1052,19 +997,6 @@ class Session(object):
|
|
|
1052
997
|
"""Fetch API key, by default disabled in backend."""
|
|
1053
998
|
return self._event("GET", "user/api_key", {})["api_key"]
|
|
1054
999
|
|
|
1055
|
-
def get_session_key(self):
|
|
1056
|
-
"""Return the current API session key."""
|
|
1057
|
-
return self._session_key
|
|
1058
|
-
|
|
1059
|
-
def generate_session_key(self, lifetime=None):
|
|
1060
|
-
"""Generate a new API session key, with the given *lifetime*."""
|
|
1061
|
-
return self._event(
|
|
1062
|
-
"POST",
|
|
1063
|
-
"user/generate_session_key",
|
|
1064
|
-
{"lifetime": lifetime},
|
|
1065
|
-
query=self._username,
|
|
1066
|
-
)["session_key"]
|
|
1067
|
-
|
|
1068
1000
|
def gui_is_running(self):
|
|
1069
1001
|
"""
|
|
1070
1002
|
Check if a GUI is running on the same machine (hostname match) and with same username.
|
|
@@ -1174,7 +1106,7 @@ class Session(object):
|
|
|
1174
1106
|
if port is None:
|
|
1175
1107
|
port = self._port or ACCSYN_PORT
|
|
1176
1108
|
if hostname is None:
|
|
1177
|
-
hostname = "
|
|
1109
|
+
hostname = "{}.{}".format(self._domain, ACCSYN_BACKEND_DOMAIN)
|
|
1178
1110
|
# Proxy set?
|
|
1179
1111
|
proxy_type = None
|
|
1180
1112
|
proxy_hostname = None
|
|
@@ -1202,12 +1134,12 @@ class Session(object):
|
|
|
1202
1134
|
if proxy_type == "accsyn":
|
|
1203
1135
|
if proxy_port == -1:
|
|
1204
1136
|
proxy_port = 80
|
|
1205
|
-
self._verbose("Using accsyn proxy @
|
|
1137
|
+
self._verbose("Using accsyn proxy @ {}:{}".format(proxy_hostname, proxy_port))
|
|
1206
1138
|
hostname = proxy_hostname
|
|
1207
1139
|
port = proxy_port
|
|
1208
1140
|
elif proxy_type in ["socks", "socks5"]:
|
|
1209
1141
|
try:
|
|
1210
|
-
self._verbose("Using SOCKS5 proxy @
|
|
1142
|
+
self._verbose("Using SOCKS5 proxy @ {}:{}".format(proxy_hostname, proxy_port))
|
|
1211
1143
|
import socks
|
|
1212
1144
|
|
|
1213
1145
|
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, proxy_hostname, proxy_port)
|
|
@@ -1217,7 +1149,7 @@ class Session(object):
|
|
|
1217
1149
|
raise ie
|
|
1218
1150
|
elif proxy_type is not None:
|
|
1219
1151
|
raise accsynException('Unknown proxy type "{}"!'.format(proxy_type))
|
|
1220
|
-
url = "http{}://{}:{}/api/
|
|
1152
|
+
url = "http{}://{}:{}/api/v3{}".format(
|
|
1221
1153
|
"s" if ssl else "",
|
|
1222
1154
|
hostname,
|
|
1223
1155
|
port,
|
|
@@ -1230,155 +1162,118 @@ class Session(object):
|
|
|
1230
1162
|
# Wait 10s to reach machine, 2min for it to send back data
|
|
1231
1163
|
CONNECT_TO, READ_TO = (self.connect_timeout, timeout)
|
|
1232
1164
|
r = None
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
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
|
+
)
|
|
1252
1195
|
)
|
|
1253
|
-
if
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
% (
|
|
1261
|
-
method,
|
|
1262
|
-
url,
|
|
1263
|
-
data if not self._pretty_json else Session.str(data),
|
|
1264
|
-
)
|
|
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,
|
|
1265
1203
|
)
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
)
|
|
1274
|
-
elif method.lower() == "put":
|
|
1275
|
-
r = requests.put(
|
|
1276
|
-
url,
|
|
1277
|
-
Session._safe_dumps(data),
|
|
1278
|
-
timeout=(CONNECT_TO, READ_TO),
|
|
1279
|
-
verify=False,
|
|
1280
|
-
headers=headers_effective,
|
|
1281
|
-
)
|
|
1282
|
-
elif method.lower() == "post":
|
|
1283
|
-
r = requests.post(
|
|
1284
|
-
url,
|
|
1285
|
-
Session._safe_dumps(data),
|
|
1286
|
-
timeout=(CONNECT_TO, READ_TO),
|
|
1287
|
-
verify=False,
|
|
1288
|
-
headers=headers_effective,
|
|
1289
|
-
)
|
|
1290
|
-
elif method.lower() == "delete":
|
|
1291
|
-
r = requests.delete(
|
|
1292
|
-
url,
|
|
1293
|
-
params=Session._url_quote(data),
|
|
1294
|
-
timeout=(CONNECT_TO, READ_TO),
|
|
1295
|
-
verify=False,
|
|
1296
|
-
headers=headers_effective,
|
|
1297
|
-
)
|
|
1298
|
-
t_end = int(round(time.time() * 1000))
|
|
1299
|
-
# break
|
|
1300
|
-
except BaseException:
|
|
1301
|
-
# if timeout <= 0:
|
|
1302
|
-
raise accsynException(
|
|
1303
|
-
"Could not reach {}:{}! Make sure cloud server({}) can"
|
|
1304
|
-
" be reached from you location and no firewall is "
|
|
1305
|
-
"blocking outgoing TCP traffic at port {}. "
|
|
1306
|
-
"Details: {}".format(
|
|
1307
|
-
hostname,
|
|
1308
|
-
port,
|
|
1309
|
-
hostname,
|
|
1310
|
-
port,
|
|
1311
|
-
traceback.format_exc() if not quiet else "(quiet)",
|
|
1312
|
-
)
|
|
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,
|
|
1313
1211
|
)
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
method,
|
|
1340
|
-
Session._obscure_dict_string(
|
|
1341
|
-
Session._safely_printable(
|
|
1342
|
-
str(retval) if not self._pretty_json else Session.str(retval)
|
|
1343
|
-
).replace("'", '"')
|
|
1344
|
-
),
|
|
1345
|
-
t_start - t_end + 1,
|
|
1346
|
-
)
|
|
1347
|
-
)
|
|
1348
|
-
do_retry = False
|
|
1349
|
-
if not retval.get("message") is None:
|
|
1350
|
-
# Something went wrong
|
|
1351
|
-
if retval.get("session_expired") is True:
|
|
1352
|
-
if self._api_key is not None:
|
|
1353
|
-
# We should be able to get a new session and retry
|
|
1354
|
-
revive_session_key = self._session_key
|
|
1355
|
-
self._session_key = None
|
|
1356
|
-
self.login(revive_session_key=revive_session_key)
|
|
1357
|
-
self._info('Authenticated using API KEY and reused expired session...')
|
|
1358
|
-
do_retry = True
|
|
1359
|
-
if not do_retry:
|
|
1360
|
-
self._last_message = retval["message"]
|
|
1361
|
-
if not do_retry:
|
|
1362
|
-
break
|
|
1363
|
-
except BaseException:
|
|
1364
|
-
sys.stderr.write(traceback.format_exc())
|
|
1365
|
-
message = 'The {}:{}/{} REST {} {} operation failed! Details: '
|
|
1366
|
-
'{} {}'.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(
|
|
1367
1237
|
hostname,
|
|
1368
1238
|
port,
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
r.text,
|
|
1373
|
-
traceback.format_exc(),
|
|
1239
|
+
hostname,
|
|
1240
|
+
port,
|
|
1241
|
+
traceback.format_exc() if not quiet else "(quiet)",
|
|
1374
1242
|
)
|
|
1375
|
-
|
|
1376
|
-
|
|
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
|
+
)
|
|
1259
|
+
)
|
|
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
|
+
|
|
1377
1272
|
if "exception" in retval:
|
|
1378
1273
|
message = "{} caused an exception! Please contact {} admin for more"
|
|
1379
1274
|
" further support.".format(uri, self._domain)
|
|
1380
1275
|
Session._warning(message)
|
|
1381
|
-
if self.
|
|
1276
|
+
if self._role in [CLEARANCE_ADMIN, CLEARANCE_SUPPORT]:
|
|
1382
1277
|
Session._warning(retval["exception"])
|
|
1383
1278
|
raise accsynException(message)
|
|
1384
1279
|
elif "message" in retval:
|
|
@@ -1401,7 +1296,7 @@ class Session(object):
|
|
|
1401
1296
|
quiet=False,
|
|
1402
1297
|
):
|
|
1403
1298
|
"""Utility; Construct an event and send using REST to accsyn backend."""
|
|
1404
|
-
assert self.
|
|
1299
|
+
assert self._uid, "Login before posting event!"
|
|
1405
1300
|
event = {
|
|
1406
1301
|
"audience": "api",
|
|
1407
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.0/PKG-INFO
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: accsyn-python-api
|
|
3
|
-
Version: 2.2.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
|
-
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
|
-
Henrik Norin, HDR AB, 2022
|
|
22
|
-
accsyn(r) - secure data delivery and workflow sync
|
|
23
|
-
https://accsyn.com
|
|
24
|
-
https://support.accsyn.com
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Platform: UNKNOWN
|
|
28
|
-
Classifier: Programming Language :: Python :: 3
|
|
29
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
30
|
-
Classifier: Operating System :: OS Independent
|
|
31
|
-
Requires-Python: >=2.7.9, <4.0
|
|
32
|
-
Description-Content-Type: text/markdown
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# accsyn-python-api
|
|
2
|
-
Official accsyn fast film delivery Python API
|
|
3
|
-
|
|
4
|
-
Complete Python API reference can be found [here](https://support.accsyn.com/python-api).
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Changelog:
|
|
8
|
-
----------
|
|
9
|
-
|
|
10
|
-
See doc/release_notes.rst
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Henrik Norin, HDR AB, 2022
|
|
14
|
-
accsyn(r) - secure data delivery and workflow sync
|
|
15
|
-
https://accsyn.com
|
|
16
|
-
https://support.accsyn.com
|
|
17
|
-
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: accsyn-python-api
|
|
3
|
-
Version: 2.2.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
|
-
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
|
-
Henrik Norin, HDR AB, 2022
|
|
22
|
-
accsyn(r) - secure data delivery and workflow sync
|
|
23
|
-
https://accsyn.com
|
|
24
|
-
https://support.accsyn.com
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Platform: UNKNOWN
|
|
28
|
-
Classifier: Programming Language :: Python :: 3
|
|
29
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
30
|
-
Classifier: Operating System :: OS Independent
|
|
31
|
-
Requires-Python: >=2.7.9, <4.0
|
|
32
|
-
Description-Content-Type: text/markdown
|
{accsyn-python-api-2.2.0 → 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
|
{accsyn-python-api-2.2.0 → 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.0 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/requires.txt
RENAMED
|
File without changes
|
{accsyn-python-api-2.2.0 → accsyn-python-api-3.0.0}/source/accsyn_python_api.egg-info/top_level.txt
RENAMED
|
File without changes
|