ayon-python-api 1.2.16.dev0__py3-none-any.whl → 1.2.17.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ayon_api/__init__.py +48 -0
- ayon_api/_api.py +426 -2
- ayon_api/_api_helpers/activities.py +112 -1
- ayon_api/_api_helpers/attributes.py +12 -1
- ayon_api/_api_helpers/lists.py +4 -1
- ayon_api/_api_helpers/projects.py +120 -9
- ayon_api/exceptions.py +14 -2
- ayon_api/graphql_queries.py +2 -0
- ayon_api/server_api.py +171 -1
- ayon_api/typing.py +2 -1
- ayon_api/utils.py +102 -98
- ayon_api/version.py +1 -1
- {ayon_python_api-1.2.16.dev0.dist-info → ayon_python_api-1.2.17.dev0.dist-info}/METADATA +1 -1
- {ayon_python_api-1.2.16.dev0.dist-info → ayon_python_api-1.2.17.dev0.dist-info}/RECORD +17 -17
- {ayon_python_api-1.2.16.dev0.dist-info → ayon_python_api-1.2.17.dev0.dist-info}/WHEEL +0 -0
- {ayon_python_api-1.2.16.dev0.dist-info → ayon_python_api-1.2.17.dev0.dist-info}/licenses/LICENSE +0 -0
- {ayon_python_api-1.2.16.dev0.dist-info → ayon_python_api-1.2.17.dev0.dist-info}/top_level.txt +0 -0
ayon_api/utils.py
CHANGED
|
@@ -12,9 +12,9 @@ import platform
|
|
|
12
12
|
import traceback
|
|
13
13
|
import collections
|
|
14
14
|
import itertools
|
|
15
|
-
from urllib.parse import urlparse, urlencode
|
|
15
|
+
from urllib.parse import urlparse, urlencode, ParseResult
|
|
16
16
|
import typing
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import Any, Iterable
|
|
18
18
|
from enum import IntEnum
|
|
19
19
|
|
|
20
20
|
import requests
|
|
@@ -27,6 +27,7 @@ from .constants import (
|
|
|
27
27
|
)
|
|
28
28
|
from .exceptions import (
|
|
29
29
|
UrlError,
|
|
30
|
+
UrlNotReached,
|
|
30
31
|
ServerError,
|
|
31
32
|
UnauthorizedError,
|
|
32
33
|
HTTPRequestError,
|
|
@@ -148,7 +149,7 @@ class RestApiResponse:
|
|
|
148
149
|
return self._response.content
|
|
149
150
|
|
|
150
151
|
@property
|
|
151
|
-
def content_type(self) ->
|
|
152
|
+
def content_type(self) -> str | None:
|
|
152
153
|
return self.headers.get("Content-Type")
|
|
153
154
|
|
|
154
155
|
@property
|
|
@@ -256,7 +257,7 @@ def fill_own_attribs(entity: AnyEntityDict) -> None:
|
|
|
256
257
|
own_attrib[key] = copy.deepcopy(value)
|
|
257
258
|
|
|
258
259
|
|
|
259
|
-
def
|
|
260
|
+
def _convert_filter_value(value: Any) -> list[Any] | None:
|
|
260
261
|
if value is None:
|
|
261
262
|
return None
|
|
262
263
|
|
|
@@ -272,7 +273,7 @@ def prepare_list_filters(
|
|
|
272
273
|
output: dict[str, Any], *args: tuple[str, Any], **kwargs: Any
|
|
273
274
|
) -> bool:
|
|
274
275
|
for key, value in itertools.chain(args, kwargs.items()):
|
|
275
|
-
value =
|
|
276
|
+
value = _convert_filter_value(value)
|
|
276
277
|
if value is None:
|
|
277
278
|
continue
|
|
278
279
|
if not value:
|
|
@@ -318,11 +319,11 @@ def get_machine_name() -> str:
|
|
|
318
319
|
return unidecode.unidecode(platform.node())
|
|
319
320
|
|
|
320
321
|
|
|
321
|
-
def get_default_site_id() ->
|
|
322
|
+
def get_default_site_id() -> str | None:
|
|
322
323
|
"""Site id used for server connection.
|
|
323
324
|
|
|
324
325
|
Returns:
|
|
325
|
-
|
|
326
|
+
str | None: Site id from environment variable or None.
|
|
326
327
|
|
|
327
328
|
"""
|
|
328
329
|
return os.environ.get(SITE_ID_ENV_KEY)
|
|
@@ -333,25 +334,25 @@ class ThumbnailContent:
|
|
|
333
334
|
|
|
334
335
|
Args:
|
|
335
336
|
project_name (str): Project name.
|
|
336
|
-
thumbnail_id (
|
|
337
|
-
content (
|
|
338
|
-
content_type (
|
|
337
|
+
thumbnail_id (str | None): Thumbnail id.
|
|
338
|
+
content (bytes | None): Thumbnail content.
|
|
339
|
+
content_type (str | None): Content type e.g. 'image/png'.
|
|
339
340
|
|
|
340
341
|
"""
|
|
341
342
|
def __init__(
|
|
342
343
|
self,
|
|
343
344
|
project_name: str,
|
|
344
|
-
thumbnail_id:
|
|
345
|
-
content:
|
|
346
|
-
content_type:
|
|
345
|
+
thumbnail_id: str | None,
|
|
346
|
+
content: bytes | None,
|
|
347
|
+
content_type: str | None,
|
|
347
348
|
):
|
|
348
349
|
self.project_name: str = project_name
|
|
349
|
-
self.thumbnail_id:
|
|
350
|
-
self.content_type:
|
|
350
|
+
self.thumbnail_id: str | None = thumbnail_id
|
|
351
|
+
self.content_type: str | None = content_type
|
|
351
352
|
self.content: bytes = content or b""
|
|
352
353
|
|
|
353
354
|
@property
|
|
354
|
-
def id(self) -> str:
|
|
355
|
+
def id(self) -> str | None:
|
|
355
356
|
"""Wrapper for thumbnail id."""
|
|
356
357
|
return self.thumbnail_id
|
|
357
358
|
|
|
@@ -394,14 +395,14 @@ def prepare_query_string(
|
|
|
394
395
|
|
|
395
396
|
if not key_values:
|
|
396
397
|
return ""
|
|
397
|
-
return "?{
|
|
398
|
+
return f"?{urlencode(key_values)}"
|
|
398
399
|
|
|
399
400
|
|
|
400
401
|
def create_entity_id() -> str:
|
|
401
402
|
return uuid.uuid1().hex
|
|
402
403
|
|
|
403
404
|
|
|
404
|
-
def convert_entity_id(entity_id) ->
|
|
405
|
+
def convert_entity_id(entity_id) -> str | None:
|
|
405
406
|
if not entity_id:
|
|
406
407
|
return None
|
|
407
408
|
|
|
@@ -416,7 +417,7 @@ def convert_entity_id(entity_id) -> Optional[str]:
|
|
|
416
417
|
return None
|
|
417
418
|
|
|
418
419
|
|
|
419
|
-
def convert_or_create_entity_id(entity_id:
|
|
420
|
+
def convert_or_create_entity_id(entity_id: str | None = None) -> str:
|
|
420
421
|
output = convert_entity_id(entity_id)
|
|
421
422
|
if output is None:
|
|
422
423
|
output = create_entity_id()
|
|
@@ -428,7 +429,7 @@ def entity_data_json_default(value: Any) -> Any:
|
|
|
428
429
|
return int(value.timestamp())
|
|
429
430
|
|
|
430
431
|
raise TypeError(
|
|
431
|
-
"Object of type {} is not JSON serializable"
|
|
432
|
+
f"Object of type {type(value)} is not JSON serializable"
|
|
432
433
|
)
|
|
433
434
|
|
|
434
435
|
|
|
@@ -440,7 +441,7 @@ def slugify_string(
|
|
|
440
441
|
min_length: int = 1,
|
|
441
442
|
lower: bool = False,
|
|
442
443
|
make_set: bool = False,
|
|
443
|
-
) ->
|
|
444
|
+
) -> str | set[str]:
|
|
444
445
|
"""Slugify a text string.
|
|
445
446
|
|
|
446
447
|
This function removes transliterates input string to ASCII, removes
|
|
@@ -460,8 +461,7 @@ def slugify_string(
|
|
|
460
461
|
min_length (int): Minimal length of an element (word).
|
|
461
462
|
|
|
462
463
|
Returns:
|
|
463
|
-
|
|
464
|
-
string.
|
|
464
|
+
str | set[str]: Based on 'make_set' value returns slugified string.
|
|
465
465
|
|
|
466
466
|
"""
|
|
467
467
|
tmp_string = unidecode.unidecode(input_string)
|
|
@@ -486,14 +486,14 @@ def slugify_string(
|
|
|
486
486
|
|
|
487
487
|
|
|
488
488
|
def failed_json_default(value: Any) -> str:
|
|
489
|
-
return "< Failed value {} > {}"
|
|
489
|
+
return f"< Failed value {type(value)} > {value}"
|
|
490
490
|
|
|
491
491
|
|
|
492
492
|
def prepare_attribute_changes(
|
|
493
493
|
old_entity: AnyEntityDict,
|
|
494
494
|
new_entity: AnyEntityDict,
|
|
495
495
|
replace: int = False,
|
|
496
|
-
):
|
|
496
|
+
) -> dict[str, Any]:
|
|
497
497
|
attrib_changes = {}
|
|
498
498
|
new_attrib = new_entity.get("attrib")
|
|
499
499
|
old_attrib = old_entity.get("attrib")
|
|
@@ -544,7 +544,7 @@ def prepare_entity_changes(
|
|
|
544
544
|
return changes
|
|
545
545
|
|
|
546
546
|
|
|
547
|
-
def _try_parse_url(url: str) ->
|
|
547
|
+
def _try_parse_url(url: str) -> ParseResult | None:
|
|
548
548
|
try:
|
|
549
549
|
return urlparse(url)
|
|
550
550
|
except BaseException:
|
|
@@ -553,10 +553,10 @@ def _try_parse_url(url: str) -> Optional[str]:
|
|
|
553
553
|
|
|
554
554
|
def _try_connect_to_server(
|
|
555
555
|
url: str,
|
|
556
|
-
timeout:
|
|
557
|
-
verify:
|
|
558
|
-
cert:
|
|
559
|
-
) ->
|
|
556
|
+
timeout: float | None,
|
|
557
|
+
verify: str | bool | None,
|
|
558
|
+
cert: str | None,
|
|
559
|
+
) -> str | None:
|
|
560
560
|
if timeout is None:
|
|
561
561
|
timeout = get_default_timeout()
|
|
562
562
|
|
|
@@ -570,11 +570,12 @@ def _try_connect_to_server(
|
|
|
570
570
|
# TODO add validation if the url lead to AYON server
|
|
571
571
|
# - this won't validate if the url lead to 'google.com'
|
|
572
572
|
response = requests.get(
|
|
573
|
-
url,
|
|
573
|
+
f"{url}/api/info",
|
|
574
574
|
timeout=timeout,
|
|
575
575
|
verify=verify,
|
|
576
576
|
cert=cert,
|
|
577
577
|
)
|
|
578
|
+
_ = response.json()
|
|
578
579
|
if response.history:
|
|
579
580
|
return response.history[-1].headers["location"].rstrip("/")
|
|
580
581
|
return url
|
|
@@ -590,19 +591,19 @@ def login_to_server(
|
|
|
590
591
|
url: str,
|
|
591
592
|
username: str,
|
|
592
593
|
password: str,
|
|
593
|
-
timeout:
|
|
594
|
-
) ->
|
|
594
|
+
timeout: float | None = None,
|
|
595
|
+
) -> str | None:
|
|
595
596
|
"""Use login to the server to receive token.
|
|
596
597
|
|
|
597
598
|
Args:
|
|
598
599
|
url (str): Server url.
|
|
599
600
|
username (str): User's username.
|
|
600
601
|
password (str): User's password.
|
|
601
|
-
timeout (
|
|
602
|
+
timeout (float | None): Timeout for request. Value from
|
|
602
603
|
'get_default_timeout' is used if not specified.
|
|
603
604
|
|
|
604
605
|
Returns:
|
|
605
|
-
|
|
606
|
+
str | None: User's token if login was successfull.
|
|
606
607
|
Otherwise 'None'.
|
|
607
608
|
|
|
608
609
|
"""
|
|
@@ -610,7 +611,7 @@ def login_to_server(
|
|
|
610
611
|
timeout = get_default_timeout()
|
|
611
612
|
headers = {"Content-Type": "application/json"}
|
|
612
613
|
response = requests.post(
|
|
613
|
-
"{}/api/auth/login"
|
|
614
|
+
f"{url}/api/auth/login",
|
|
614
615
|
headers=headers,
|
|
615
616
|
json={
|
|
616
617
|
"name": username,
|
|
@@ -627,13 +628,17 @@ def login_to_server(
|
|
|
627
628
|
return token
|
|
628
629
|
|
|
629
630
|
|
|
630
|
-
def logout_from_server(
|
|
631
|
+
def logout_from_server(
|
|
632
|
+
url: str,
|
|
633
|
+
token: str,
|
|
634
|
+
timeout: float | None = None,
|
|
635
|
+
) -> None:
|
|
631
636
|
"""Logout from server and throw token away.
|
|
632
637
|
|
|
633
638
|
Args:
|
|
634
639
|
url (str): Url from which should be logged out.
|
|
635
640
|
token (str): Token which should be used to log out.
|
|
636
|
-
timeout (
|
|
641
|
+
timeout (float | None): Timeout for request. Value from
|
|
637
642
|
'get_default_timeout' is used if not specified.
|
|
638
643
|
|
|
639
644
|
"""
|
|
@@ -641,10 +646,10 @@ def logout_from_server(url: str, token: str, timeout: Optional[float] = None):
|
|
|
641
646
|
timeout = get_default_timeout()
|
|
642
647
|
headers = {
|
|
643
648
|
"Content-Type": "application/json",
|
|
644
|
-
"Authorization": "Bearer {}"
|
|
649
|
+
"Authorization": f"Bearer {token}",
|
|
645
650
|
}
|
|
646
651
|
requests.post(
|
|
647
|
-
url
|
|
652
|
+
f"{url}/api/auth/logout",
|
|
648
653
|
headers=headers,
|
|
649
654
|
timeout=timeout,
|
|
650
655
|
)
|
|
@@ -653,18 +658,18 @@ def logout_from_server(url: str, token: str, timeout: Optional[float] = None):
|
|
|
653
658
|
def get_user_by_token(
|
|
654
659
|
url: str,
|
|
655
660
|
token: str,
|
|
656
|
-
timeout:
|
|
657
|
-
) ->
|
|
661
|
+
timeout: float | None = None,
|
|
662
|
+
) -> dict[str, Any] | None:
|
|
658
663
|
"""Get user information by url and token.
|
|
659
664
|
|
|
660
665
|
Args:
|
|
661
666
|
url (str): Server url.
|
|
662
667
|
token (str): User's token.
|
|
663
|
-
timeout (
|
|
668
|
+
timeout (float | None): Timeout for request. Value from
|
|
664
669
|
'get_default_timeout' is used if not specified.
|
|
665
670
|
|
|
666
671
|
Returns:
|
|
667
|
-
|
|
672
|
+
dict[str, Any] | None: User information if url and token are valid.
|
|
668
673
|
|
|
669
674
|
"""
|
|
670
675
|
if timeout is None:
|
|
@@ -674,13 +679,13 @@ def get_user_by_token(
|
|
|
674
679
|
"Content-Type": "application/json",
|
|
675
680
|
}
|
|
676
681
|
for header_value in (
|
|
677
|
-
{"Authorization": "Bearer {}"
|
|
682
|
+
{"Authorization": f"Bearer {token}"},
|
|
678
683
|
{"X-Api-Key": token},
|
|
679
684
|
):
|
|
680
685
|
headers = base_headers.copy()
|
|
681
686
|
headers.update(header_value)
|
|
682
687
|
response = requests.get(
|
|
683
|
-
"{}/api/users/me"
|
|
688
|
+
f"{url}/api/users/me",
|
|
684
689
|
headers=headers,
|
|
685
690
|
timeout=timeout,
|
|
686
691
|
)
|
|
@@ -692,7 +697,7 @@ def get_user_by_token(
|
|
|
692
697
|
def is_token_valid(
|
|
693
698
|
url: str,
|
|
694
699
|
token: str,
|
|
695
|
-
timeout:
|
|
700
|
+
timeout: float | None = None,
|
|
696
701
|
) -> bool:
|
|
697
702
|
"""Check if token is valid.
|
|
698
703
|
|
|
@@ -701,7 +706,7 @@ def is_token_valid(
|
|
|
701
706
|
Args:
|
|
702
707
|
url (str): Server url.
|
|
703
708
|
token (str): User's token.
|
|
704
|
-
timeout (
|
|
709
|
+
timeout (float | None): Timeout for request. Value from
|
|
705
710
|
'get_default_timeout' is used if not specified.
|
|
706
711
|
|
|
707
712
|
Returns:
|
|
@@ -715,9 +720,9 @@ def is_token_valid(
|
|
|
715
720
|
|
|
716
721
|
def validate_url(
|
|
717
722
|
url: str,
|
|
718
|
-
timeout:
|
|
719
|
-
verify:
|
|
720
|
-
cert:
|
|
723
|
+
timeout: int | None = None,
|
|
724
|
+
verify: str | bool | None = None,
|
|
725
|
+
cert: str | None = None,
|
|
721
726
|
) -> str:
|
|
722
727
|
"""Validate url if is valid and server is available.
|
|
723
728
|
|
|
@@ -740,7 +745,7 @@ def validate_url(
|
|
|
740
745
|
|
|
741
746
|
Args:
|
|
742
747
|
url (str): Server url.
|
|
743
|
-
timeout (
|
|
748
|
+
timeout (int | None): Timeout in seconds for connection to server.
|
|
744
749
|
|
|
745
750
|
Returns:
|
|
746
751
|
Url which was used to connect to server.
|
|
@@ -749,8 +754,8 @@ def validate_url(
|
|
|
749
754
|
UrlError: Error with short description and hints for user.
|
|
750
755
|
|
|
751
756
|
"""
|
|
752
|
-
|
|
753
|
-
if not
|
|
757
|
+
stripped_url = url.strip()
|
|
758
|
+
if not stripped_url:
|
|
754
759
|
raise UrlError(
|
|
755
760
|
"Invalid url format. Url is empty.",
|
|
756
761
|
title="Invalid url format",
|
|
@@ -758,25 +763,30 @@ def validate_url(
|
|
|
758
763
|
)
|
|
759
764
|
|
|
760
765
|
# Not sure if this is good idea?
|
|
761
|
-
modified_url =
|
|
766
|
+
modified_url = stripped_url.rstrip("/")
|
|
767
|
+
|
|
768
|
+
# Make sure url has http scheme
|
|
769
|
+
if not modified_url.lower().startswith("http"):
|
|
770
|
+
modified_url = f"http://{modified_url}"
|
|
771
|
+
|
|
762
772
|
parsed_url = _try_parse_url(modified_url)
|
|
763
773
|
universal_hints = [
|
|
764
774
|
"does the url work in browser?"
|
|
765
775
|
]
|
|
766
776
|
if parsed_url is None:
|
|
767
777
|
raise UrlError(
|
|
768
|
-
|
|
769
|
-
|
|
778
|
+
(
|
|
779
|
+
"Invalid url format. Url cannot be parsed"
|
|
780
|
+
f" as url \"{modified_url}\"."
|
|
770
781
|
),
|
|
771
782
|
title="Invalid url format",
|
|
772
783
|
hints=universal_hints
|
|
773
784
|
)
|
|
774
785
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
if not parsed_url.scheme:
|
|
786
|
+
pathless_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
|
787
|
+
if parsed_url.path:
|
|
778
788
|
new_url = _try_connect_to_server(
|
|
779
|
-
|
|
789
|
+
pathless_url,
|
|
780
790
|
timeout=timeout,
|
|
781
791
|
verify=verify,
|
|
782
792
|
cert=cert,
|
|
@@ -794,17 +804,11 @@ def validate_url(
|
|
|
794
804
|
return new_url
|
|
795
805
|
|
|
796
806
|
hints = []
|
|
797
|
-
if
|
|
798
|
-
|
|
799
|
-
if not parsed_url.scheme:
|
|
800
|
-
new_path = "https://" + new_path
|
|
801
|
-
|
|
802
|
-
hints.append(
|
|
803
|
-
"did you mean \"{}\"?".format(parsed_url.scheme + new_path)
|
|
804
|
-
)
|
|
807
|
+
if parsed_url.path:
|
|
808
|
+
hints.append(f"did you mean \"{pathless_url}\"?")
|
|
805
809
|
|
|
806
|
-
raise
|
|
807
|
-
"Couldn't connect to server on \"{}\""
|
|
810
|
+
raise UrlNotReached(
|
|
811
|
+
f"Couldn't connect to server on \"{url}\"",
|
|
808
812
|
title="Couldn't connect to server",
|
|
809
813
|
hints=hints + universal_hints
|
|
810
814
|
)
|
|
@@ -818,25 +822,25 @@ class TransferProgress:
|
|
|
818
822
|
self._started: bool = False
|
|
819
823
|
self._transfer_done: bool = False
|
|
820
824
|
self._transferred: int = 0
|
|
821
|
-
self._content_size:
|
|
825
|
+
self._content_size: int | None = None
|
|
822
826
|
|
|
823
827
|
self._failed: bool = False
|
|
824
|
-
self._fail_reason:
|
|
828
|
+
self._fail_reason: str | None = None
|
|
825
829
|
|
|
826
830
|
self._source_url: str = "N/A"
|
|
827
831
|
self._destination_url: str = "N/A"
|
|
828
832
|
|
|
829
|
-
def get_content_size(self):
|
|
833
|
+
def get_content_size(self) -> int | None:
|
|
830
834
|
"""Content size in bytes.
|
|
831
835
|
|
|
832
836
|
Returns:
|
|
833
|
-
|
|
837
|
+
int | None: Content size in bytes or None
|
|
834
838
|
if is unknown.
|
|
835
839
|
|
|
836
840
|
"""
|
|
837
841
|
return self._content_size
|
|
838
842
|
|
|
839
|
-
def set_content_size(self, content_size: int):
|
|
843
|
+
def set_content_size(self, content_size: int) -> None:
|
|
840
844
|
"""Set content size in bytes.
|
|
841
845
|
|
|
842
846
|
Args:
|
|
@@ -859,7 +863,7 @@ class TransferProgress:
|
|
|
859
863
|
"""
|
|
860
864
|
return self._started
|
|
861
865
|
|
|
862
|
-
def set_started(self):
|
|
866
|
+
def set_started(self) -> None:
|
|
863
867
|
"""Mark that transfer started.
|
|
864
868
|
|
|
865
869
|
Raises:
|
|
@@ -890,7 +894,7 @@ class TransferProgress:
|
|
|
890
894
|
"""
|
|
891
895
|
return self._transfer_done
|
|
892
896
|
|
|
893
|
-
def set_transfer_done(self):
|
|
897
|
+
def set_transfer_done(self) -> None:
|
|
894
898
|
"""Mark progress as transfer finished.
|
|
895
899
|
|
|
896
900
|
Raises:
|
|
@@ -913,17 +917,17 @@ class TransferProgress:
|
|
|
913
917
|
"""
|
|
914
918
|
return self._failed
|
|
915
919
|
|
|
916
|
-
def get_fail_reason(self) ->
|
|
920
|
+
def get_fail_reason(self) -> str | None:
|
|
917
921
|
"""Get reason why transfer failed.
|
|
918
922
|
|
|
919
923
|
Returns:
|
|
920
|
-
|
|
924
|
+
str | None: Reason why transfer
|
|
921
925
|
failed or None.
|
|
922
926
|
|
|
923
927
|
"""
|
|
924
928
|
return self._fail_reason
|
|
925
929
|
|
|
926
|
-
def set_failed(self, reason: str):
|
|
930
|
+
def set_failed(self, reason: str) -> None:
|
|
927
931
|
"""Mark progress as failed.
|
|
928
932
|
|
|
929
933
|
Args:
|
|
@@ -942,7 +946,7 @@ class TransferProgress:
|
|
|
942
946
|
"""
|
|
943
947
|
return self._transferred
|
|
944
948
|
|
|
945
|
-
def set_transferred_size(self, transferred: int):
|
|
949
|
+
def set_transferred_size(self, transferred: int) -> None:
|
|
946
950
|
"""Set already transferred size in bytes.
|
|
947
951
|
|
|
948
952
|
Args:
|
|
@@ -955,7 +959,7 @@ class TransferProgress:
|
|
|
955
959
|
"""Reset transferred size to initial value."""
|
|
956
960
|
self._transferred = 0
|
|
957
961
|
|
|
958
|
-
def add_transferred_chunk(self, chunk_size: int):
|
|
962
|
+
def add_transferred_chunk(self, chunk_size: int) -> None:
|
|
959
963
|
"""Add transferred chunk size in bytes.
|
|
960
964
|
|
|
961
965
|
Args:
|
|
@@ -978,7 +982,7 @@ class TransferProgress:
|
|
|
978
982
|
"""
|
|
979
983
|
return self._source_url
|
|
980
984
|
|
|
981
|
-
def set_source_url(self, url: str):
|
|
985
|
+
def set_source_url(self, url: str) -> None:
|
|
982
986
|
"""Set source url from where transfer happens.
|
|
983
987
|
|
|
984
988
|
Args:
|
|
@@ -1000,7 +1004,7 @@ class TransferProgress:
|
|
|
1000
1004
|
"""
|
|
1001
1005
|
return self._destination_url
|
|
1002
1006
|
|
|
1003
|
-
def set_destination_url(self, url: str):
|
|
1007
|
+
def set_destination_url(self, url: str) -> None:
|
|
1004
1008
|
"""Set destination url where transfer happens.
|
|
1005
1009
|
|
|
1006
1010
|
Args:
|
|
@@ -1026,11 +1030,11 @@ class TransferProgress:
|
|
|
1026
1030
|
return True
|
|
1027
1031
|
|
|
1028
1032
|
@property
|
|
1029
|
-
def transfer_progress(self) ->
|
|
1033
|
+
def transfer_progress(self) -> float | None:
|
|
1030
1034
|
"""Get transfer progress in percents.
|
|
1031
1035
|
|
|
1032
1036
|
Returns:
|
|
1033
|
-
|
|
1037
|
+
float | None: Transfer progress in percents or 'None'
|
|
1034
1038
|
if content size is unknown.
|
|
1035
1039
|
|
|
1036
1040
|
"""
|
|
@@ -1049,12 +1053,12 @@ class TransferProgress:
|
|
|
1049
1053
|
|
|
1050
1054
|
|
|
1051
1055
|
def create_dependency_package_basename(
|
|
1052
|
-
platform_name:
|
|
1056
|
+
platform_name: str | None = None
|
|
1053
1057
|
) -> str:
|
|
1054
1058
|
"""Create basename for dependency package file.
|
|
1055
1059
|
|
|
1056
1060
|
Args:
|
|
1057
|
-
platform_name (
|
|
1061
|
+
platform_name (str | None): Name of platform for which the
|
|
1058
1062
|
bundle is targeted. Default value is current platform.
|
|
1059
1063
|
|
|
1060
1064
|
Returns:
|
|
@@ -1066,11 +1070,11 @@ def create_dependency_package_basename(
|
|
|
1066
1070
|
|
|
1067
1071
|
now_date = datetime.datetime.now()
|
|
1068
1072
|
time_stamp = now_date.strftime("%y%m%d%H%M")
|
|
1069
|
-
return "ayon_{}_{}"
|
|
1073
|
+
return f"ayon_{time_stamp}_{platform_name}"
|
|
1070
1074
|
|
|
1071
1075
|
|
|
1072
1076
|
|
|
1073
|
-
def _get_media_mime_type_from_ftyp(content: bytes) ->
|
|
1077
|
+
def _get_media_mime_type_from_ftyp(content: bytes) -> str | None:
|
|
1074
1078
|
if content[8:10] == b"qt" or content[8:12] == b"MSNV":
|
|
1075
1079
|
return "video/quicktime"
|
|
1076
1080
|
|
|
@@ -1110,7 +1114,7 @@ def _get_media_mime_type_from_ftyp(content: bytes) -> Optional[str]:
|
|
|
1110
1114
|
return None
|
|
1111
1115
|
|
|
1112
1116
|
|
|
1113
|
-
def _get_media_mime_type_for_content_base(content: bytes) ->
|
|
1117
|
+
def _get_media_mime_type_for_content_base(content: bytes) -> str | None:
|
|
1114
1118
|
"""Determine Mime-Type of a file.
|
|
1115
1119
|
|
|
1116
1120
|
Use header of the file to determine mime type (needs 12 bytes).
|
|
@@ -1173,14 +1177,14 @@ def _get_media_mime_type_for_content_base(content: bytes) -> Optional[str]:
|
|
|
1173
1177
|
return None
|
|
1174
1178
|
|
|
1175
1179
|
|
|
1176
|
-
def _get_svg_mime_type(content: bytes) ->
|
|
1180
|
+
def _get_svg_mime_type(content: bytes) -> str | None:
|
|
1177
1181
|
# SVG
|
|
1178
1182
|
if b'xmlns="http://www.w3.org/2000/svg"' in content:
|
|
1179
1183
|
return "image/svg+xml"
|
|
1180
1184
|
return None
|
|
1181
1185
|
|
|
1182
1186
|
|
|
1183
|
-
def _get_json_mime_type(content: bytes) ->
|
|
1187
|
+
def _get_json_mime_type(content: bytes) -> str | None:
|
|
1184
1188
|
# json
|
|
1185
1189
|
try:
|
|
1186
1190
|
json.loads(content.decode("utf-8"))
|
|
@@ -1190,14 +1194,14 @@ def _get_json_mime_type(content: bytes) -> Optional[str]:
|
|
|
1190
1194
|
return None
|
|
1191
1195
|
|
|
1192
1196
|
|
|
1193
|
-
def get_media_mime_type_for_content(content: bytes) ->
|
|
1197
|
+
def get_media_mime_type_for_content(content: bytes) -> str | None:
|
|
1194
1198
|
mime_type = _get_media_mime_type_for_content_base(content)
|
|
1195
1199
|
if mime_type is not None:
|
|
1196
1200
|
return mime_type
|
|
1197
1201
|
return _get_svg_mime_type(content) or _get_json_mime_type(content)
|
|
1198
1202
|
|
|
1199
1203
|
|
|
1200
|
-
def get_media_mime_type_for_stream(stream: StreamType) ->
|
|
1204
|
+
def get_media_mime_type_for_stream(stream: StreamType) -> str | None:
|
|
1201
1205
|
# Read only 12 bytes to determine mime type
|
|
1202
1206
|
content = stream.read(12)
|
|
1203
1207
|
mime_type = _get_media_mime_type_for_content_base(content)
|
|
@@ -1208,14 +1212,14 @@ def get_media_mime_type_for_stream(stream: StreamType) -> Optional[str]:
|
|
|
1208
1212
|
return _get_svg_mime_type(content) or _get_json_mime_type(content)
|
|
1209
1213
|
|
|
1210
1214
|
|
|
1211
|
-
def get_media_mime_type(filepath: str) ->
|
|
1215
|
+
def get_media_mime_type(filepath: str) -> str | None:
|
|
1212
1216
|
"""Determine Mime-Type of a file.
|
|
1213
1217
|
|
|
1214
1218
|
Args:
|
|
1215
1219
|
filepath (str): Path to file.
|
|
1216
1220
|
|
|
1217
1221
|
Returns:
|
|
1218
|
-
|
|
1222
|
+
str | None: Mime type or None if is unknown mime type.
|
|
1219
1223
|
|
|
1220
1224
|
"""
|
|
1221
1225
|
if not filepath or not os.path.exists(filepath):
|
ayon_api/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""Package declaring Python API for AYON server."""
|
|
2
|
-
__version__ = "1.2.
|
|
2
|
+
__version__ = "1.2.17-dev"
|