volcano-sdk-python 0.7.1__py3-none-any.whl → 0.7.3__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.
- volcano_sdk/_transport.py +54 -12
- volcano_sdk/auth.py +60 -32
- volcano_sdk/storage.py +129 -90
- {volcano_sdk_python-0.7.1.dist-info → volcano_sdk_python-0.7.3.dist-info}/METADATA +5 -2
- {volcano_sdk_python-0.7.1.dist-info → volcano_sdk_python-0.7.3.dist-info}/RECORD +7 -7
- {volcano_sdk_python-0.7.1.dist-info → volcano_sdk_python-0.7.3.dist-info}/WHEEL +1 -1
- {volcano_sdk_python-0.7.1.dist-info → volcano_sdk_python-0.7.3.dist-info}/licenses/LICENSE +0 -0
volcano_sdk/_transport.py
CHANGED
|
@@ -13,14 +13,10 @@ from uuid import UUID, uuid4
|
|
|
13
13
|
import httpx
|
|
14
14
|
|
|
15
15
|
from ._generated.api.authentication import (
|
|
16
|
-
auth_confirm_email_change,
|
|
17
|
-
auth_convert_anonymous,
|
|
18
|
-
auth_get_user,
|
|
19
16
|
auth_logout,
|
|
20
17
|
auth_refresh,
|
|
21
18
|
auth_signin,
|
|
22
19
|
auth_signup,
|
|
23
|
-
auth_update_user,
|
|
24
20
|
)
|
|
25
21
|
from ._generated.api.authentication.auth_cancel_email_change import (
|
|
26
22
|
_get_kwargs as cancel_email_change_kwargs,
|
|
@@ -28,6 +24,18 @@ from ._generated.api.authentication.auth_cancel_email_change import (
|
|
|
28
24
|
from ._generated.api.authentication.auth_confirm_email import (
|
|
29
25
|
_get_kwargs as confirm_email_kwargs,
|
|
30
26
|
)
|
|
27
|
+
from ._generated.api.authentication.auth_confirm_email_change import (
|
|
28
|
+
_build_response as build_auth_confirm_email_change_response,
|
|
29
|
+
)
|
|
30
|
+
from ._generated.api.authentication.auth_confirm_email_change import (
|
|
31
|
+
_get_kwargs as auth_confirm_email_change_kwargs,
|
|
32
|
+
)
|
|
33
|
+
from ._generated.api.authentication.auth_convert_anonymous import (
|
|
34
|
+
_build_response as build_auth_convert_anonymous_response,
|
|
35
|
+
)
|
|
36
|
+
from ._generated.api.authentication.auth_convert_anonymous import (
|
|
37
|
+
_get_kwargs as auth_convert_anonymous_kwargs,
|
|
38
|
+
)
|
|
31
39
|
from ._generated.api.authentication.auth_delete_all_my_sessions import (
|
|
32
40
|
_get_kwargs as delete_all_my_sessions_kwargs,
|
|
33
41
|
)
|
|
@@ -40,6 +48,12 @@ from ._generated.api.authentication.auth_forgot_password import (
|
|
|
40
48
|
from ._generated.api.authentication.auth_get_my_sessions import (
|
|
41
49
|
_get_kwargs as get_my_sessions_kwargs,
|
|
42
50
|
)
|
|
51
|
+
from ._generated.api.authentication.auth_get_user import (
|
|
52
|
+
_build_response as build_auth_get_user_response,
|
|
53
|
+
)
|
|
54
|
+
from ._generated.api.authentication.auth_get_user import (
|
|
55
|
+
_get_kwargs as auth_get_user_kwargs,
|
|
56
|
+
)
|
|
43
57
|
from ._generated.api.authentication.auth_request_email_change import (
|
|
44
58
|
_get_kwargs as request_email_change_kwargs,
|
|
45
59
|
)
|
|
@@ -52,6 +66,12 @@ from ._generated.api.authentication.auth_reset_password import (
|
|
|
52
66
|
from ._generated.api.authentication.auth_signup_anonymous import (
|
|
53
67
|
_get_kwargs as signup_anonymous_kwargs,
|
|
54
68
|
)
|
|
69
|
+
from ._generated.api.authentication.auth_update_user import (
|
|
70
|
+
_build_response as build_auth_update_user_response,
|
|
71
|
+
)
|
|
72
|
+
from ._generated.api.authentication.auth_update_user import (
|
|
73
|
+
_get_kwargs as auth_update_user_kwargs,
|
|
74
|
+
)
|
|
55
75
|
from ._generated.api.database_queries import (
|
|
56
76
|
query_database_select,
|
|
57
77
|
)
|
|
@@ -829,9 +849,13 @@ class GeneratedTransport:
|
|
|
829
849
|
)
|
|
830
850
|
try:
|
|
831
851
|
with self._client(authorization) as client:
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
852
|
+
raw_response = client.get_httpx_client().request(
|
|
853
|
+
**auth_convert_anonymous_kwargs(body=body)
|
|
854
|
+
)
|
|
855
|
+
if raw_response.status_code == HTTP_UNAUTHORIZED:
|
|
856
|
+
return self._raw_response(raw_response)
|
|
857
|
+
response = build_auth_convert_anonymous_response(
|
|
858
|
+
client=client, response=raw_response
|
|
835
859
|
)
|
|
836
860
|
except (
|
|
837
861
|
AttributeError,
|
|
@@ -928,9 +952,13 @@ class GeneratedTransport:
|
|
|
928
952
|
body = AuthConfirmEmailChangeBody(email_change_token=token)
|
|
929
953
|
try:
|
|
930
954
|
with self._client(authorization) as client:
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
955
|
+
raw_response = client.get_httpx_client().request(
|
|
956
|
+
**auth_confirm_email_change_kwargs(body=body)
|
|
957
|
+
)
|
|
958
|
+
if raw_response.status_code == HTTP_UNAUTHORIZED:
|
|
959
|
+
return self._raw_response(raw_response)
|
|
960
|
+
response = build_auth_confirm_email_change_response(
|
|
961
|
+
client=client, response=raw_response
|
|
934
962
|
)
|
|
935
963
|
except (
|
|
936
964
|
AttributeError,
|
|
@@ -1204,7 +1232,14 @@ class GeneratedTransport:
|
|
|
1204
1232
|
def auth_get_user(self, *, authorization: str) -> TransportResponse:
|
|
1205
1233
|
try:
|
|
1206
1234
|
with self._client(authorization) as client:
|
|
1207
|
-
|
|
1235
|
+
raw_response = client.get_httpx_client().request(
|
|
1236
|
+
**auth_get_user_kwargs()
|
|
1237
|
+
)
|
|
1238
|
+
if raw_response.status_code == HTTP_UNAUTHORIZED:
|
|
1239
|
+
return self._raw_response(raw_response)
|
|
1240
|
+
response = build_auth_get_user_response(
|
|
1241
|
+
client=client, response=raw_response
|
|
1242
|
+
)
|
|
1208
1243
|
except (
|
|
1209
1244
|
AttributeError,
|
|
1210
1245
|
KeyError,
|
|
@@ -1239,7 +1274,14 @@ class GeneratedTransport:
|
|
|
1239
1274
|
)
|
|
1240
1275
|
try:
|
|
1241
1276
|
with self._client(authorization) as client:
|
|
1242
|
-
|
|
1277
|
+
raw_response = client.get_httpx_client().request(
|
|
1278
|
+
**auth_update_user_kwargs(body=body)
|
|
1279
|
+
)
|
|
1280
|
+
if raw_response.status_code == HTTP_UNAUTHORIZED:
|
|
1281
|
+
return self._raw_response(raw_response)
|
|
1282
|
+
response = build_auth_update_user_response(
|
|
1283
|
+
client=client, response=raw_response
|
|
1284
|
+
)
|
|
1243
1285
|
except (
|
|
1244
1286
|
AttributeError,
|
|
1245
1287
|
KeyError,
|
volcano_sdk/auth.py
CHANGED
|
@@ -9,6 +9,7 @@ import secrets
|
|
|
9
9
|
import threading
|
|
10
10
|
from collections.abc import Mapping
|
|
11
11
|
from contextlib import suppress
|
|
12
|
+
from copy import deepcopy
|
|
12
13
|
from dataclasses import replace
|
|
13
14
|
from datetime import datetime
|
|
14
15
|
from http import HTTPStatus
|
|
@@ -574,18 +575,22 @@ class Auth:
|
|
|
574
575
|
metadata: Mapping[str, object] | None = None,
|
|
575
576
|
) -> User:
|
|
576
577
|
"""Attach email credentials to the current anonymous account."""
|
|
577
|
-
|
|
578
|
-
if
|
|
578
|
+
binding = self._client._capture_session_binding()
|
|
579
|
+
if binding[2] is None:
|
|
579
580
|
raise AuthenticationError(_NO_ACTIVE_SESSION)
|
|
580
581
|
transport = cast("AuthConvertAnonymousTransport", self._client._transport)
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
582
|
+
request_metadata = deepcopy(dict(metadata or {}))
|
|
583
|
+
response = self._session_request(
|
|
584
|
+
lambda access_token: invoke(
|
|
585
|
+
transport.auth_convert_anonymous,
|
|
586
|
+
authorization=access_token,
|
|
587
|
+
email=email,
|
|
588
|
+
password=password,
|
|
589
|
+
metadata=request_metadata,
|
|
590
|
+
),
|
|
591
|
+
binding=binding,
|
|
587
592
|
)
|
|
588
|
-
return self._update_current_user(response_payload(response, 200),
|
|
593
|
+
return self._update_current_user(response_payload(response, 200), binding)
|
|
589
594
|
|
|
590
595
|
def reset_password_for_email(self, *, email: str) -> None:
|
|
591
596
|
"""Request a reset email without revealing whether the account exists."""
|
|
@@ -629,16 +634,19 @@ class Auth:
|
|
|
629
634
|
|
|
630
635
|
def confirm_email_change(self, *, token: str) -> User:
|
|
631
636
|
"""Confirm a pending email change and return the updated user."""
|
|
632
|
-
|
|
633
|
-
if
|
|
637
|
+
binding = self._client._capture_session_binding()
|
|
638
|
+
if binding[2] is None:
|
|
634
639
|
raise AuthenticationError(_NO_ACTIVE_SESSION)
|
|
635
640
|
transport = cast("AuthConfirmEmailChangeTransport", self._client._transport)
|
|
636
|
-
response =
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
641
|
+
response = self._session_request(
|
|
642
|
+
lambda access_token: invoke(
|
|
643
|
+
transport.auth_confirm_email_change,
|
|
644
|
+
authorization=access_token,
|
|
645
|
+
token=token,
|
|
646
|
+
),
|
|
647
|
+
binding=binding,
|
|
640
648
|
)
|
|
641
|
-
return self._update_current_user(response_payload(response, 200),
|
|
649
|
+
return self._update_current_user(response_payload(response, 200), binding)
|
|
642
650
|
|
|
643
651
|
def delete_all_other_sessions(self) -> None:
|
|
644
652
|
"""Delete every other session while preserving the current session."""
|
|
@@ -944,7 +952,10 @@ class Auth:
|
|
|
944
952
|
)
|
|
945
953
|
response_payload(response, 200)
|
|
946
954
|
|
|
947
|
-
def _update_current_user(
|
|
955
|
+
def _update_current_user(
|
|
956
|
+
self, payload: object, binding: tuple[int, int, Session | None]
|
|
957
|
+
) -> User:
|
|
958
|
+
generation = self._owned_refresh_session(binding)[0]
|
|
948
959
|
user, snapshot = _user_from_payload(payload)
|
|
949
960
|
if not self._client._update_session_user_if_current(snapshot, generation):
|
|
950
961
|
raise SessionChangedError
|
|
@@ -952,12 +963,17 @@ class Auth:
|
|
|
952
963
|
|
|
953
964
|
def get_user(self) -> User:
|
|
954
965
|
"""Load a server-validated profile for the current session."""
|
|
955
|
-
|
|
956
|
-
if
|
|
966
|
+
binding = self._client._capture_session_binding()
|
|
967
|
+
if binding[2] is None:
|
|
957
968
|
raise AuthenticationError(_NO_ACTIVE_SESSION)
|
|
958
969
|
transport = cast("AuthGetUserTransport", self._client._transport)
|
|
959
|
-
response =
|
|
960
|
-
|
|
970
|
+
response = self._session_request(
|
|
971
|
+
lambda access_token: invoke(
|
|
972
|
+
transport.auth_get_user, authorization=access_token
|
|
973
|
+
),
|
|
974
|
+
binding=binding,
|
|
975
|
+
)
|
|
976
|
+
return self._update_current_user(response_payload(response, 200), binding)
|
|
961
977
|
|
|
962
978
|
def update_user(
|
|
963
979
|
self,
|
|
@@ -966,17 +982,21 @@ class Auth:
|
|
|
966
982
|
metadata: Mapping[str, object] | None = None,
|
|
967
983
|
) -> User:
|
|
968
984
|
"""Update and return the current user's server-validated profile."""
|
|
969
|
-
|
|
970
|
-
if
|
|
985
|
+
binding = self._client._capture_session_binding()
|
|
986
|
+
if binding[2] is None:
|
|
971
987
|
raise AuthenticationError(_NO_ACTIVE_SESSION)
|
|
972
988
|
transport = cast("AuthUpdateUserTransport", self._client._transport)
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
989
|
+
request_metadata = None if metadata is None else deepcopy(dict(metadata))
|
|
990
|
+
response = self._session_request(
|
|
991
|
+
lambda access_token: invoke(
|
|
992
|
+
transport.auth_update_user,
|
|
993
|
+
authorization=access_token,
|
|
994
|
+
password=password,
|
|
995
|
+
metadata=request_metadata,
|
|
996
|
+
),
|
|
997
|
+
binding=binding,
|
|
978
998
|
)
|
|
979
|
-
return self._update_current_user(response_payload(response, 200),
|
|
999
|
+
return self._update_current_user(response_payload(response, 200), binding)
|
|
980
1000
|
|
|
981
1001
|
def sign_in(self, *, email: str, password: str) -> Session:
|
|
982
1002
|
"""Sign in a user and store the returned session."""
|
|
@@ -1007,12 +1027,20 @@ class Auth:
|
|
|
1007
1027
|
)
|
|
1008
1028
|
|
|
1009
1029
|
def _session_request(
|
|
1010
|
-
self,
|
|
1030
|
+
self,
|
|
1031
|
+
operation: Callable[[str], TransportResponse],
|
|
1032
|
+
*,
|
|
1033
|
+
binding: tuple[int, int, Session | None] | None = None,
|
|
1011
1034
|
) -> TransportResponse:
|
|
1012
|
-
binding
|
|
1035
|
+
if binding is None:
|
|
1036
|
+
binding = self._client._capture_session_binding()
|
|
1013
1037
|
if binding[2] is None:
|
|
1014
1038
|
raise RuntimeError(_NO_ACTIVE_SESSION)
|
|
1015
|
-
|
|
1039
|
+
binding = self._owned_refresh_session(binding)
|
|
1040
|
+
current = binding[2]
|
|
1041
|
+
if current is None:
|
|
1042
|
+
raise SessionChangedError
|
|
1043
|
+
response = operation(current.access_token)
|
|
1016
1044
|
if response.status_code != HTTPStatus.UNAUTHORIZED:
|
|
1017
1045
|
return response
|
|
1018
1046
|
try:
|
volcano_sdk/storage.py
CHANGED
|
@@ -11,7 +11,7 @@ from dataclasses import dataclass
|
|
|
11
11
|
from datetime import datetime
|
|
12
12
|
from io import SEEK_END, BytesIO
|
|
13
13
|
from tempfile import TemporaryFile
|
|
14
|
-
from typing import Any, BinaryIO, Protocol, cast
|
|
14
|
+
from typing import TYPE_CHECKING, Any, BinaryIO, Protocol, cast
|
|
15
15
|
from urllib.parse import quote
|
|
16
16
|
|
|
17
17
|
from ._transport import (
|
|
@@ -25,6 +25,7 @@ from ._transport import (
|
|
|
25
25
|
)
|
|
26
26
|
from .models import (
|
|
27
27
|
JSONValue,
|
|
28
|
+
Session,
|
|
28
29
|
StorageObject,
|
|
29
30
|
StoragePage,
|
|
30
31
|
UploadPart,
|
|
@@ -33,6 +34,9 @@ from .models import (
|
|
|
33
34
|
UploadSessionStatus,
|
|
34
35
|
)
|
|
35
36
|
|
|
37
|
+
if TYPE_CHECKING:
|
|
38
|
+
from .auth import Auth
|
|
39
|
+
|
|
36
40
|
_INVALID_STORAGE_PAGE = "Expected a complete storage page"
|
|
37
41
|
_INVALID_CONTENT_TYPE = "content_type must be a non-blank printable ASCII string"
|
|
38
42
|
_INVALID_STORAGE_PATH = "Storage path must be a non-empty string"
|
|
@@ -280,6 +284,7 @@ class StorageContext(Protocol):
|
|
|
280
284
|
"""Client capabilities required by object storage."""
|
|
281
285
|
|
|
282
286
|
_transport: Transport
|
|
287
|
+
auth: Auth
|
|
283
288
|
|
|
284
289
|
def _anon_token(self) -> str: ...
|
|
285
290
|
|
|
@@ -287,6 +292,8 @@ class StorageContext(Protocol):
|
|
|
287
292
|
|
|
288
293
|
def _session_token(self) -> str: ...
|
|
289
294
|
|
|
295
|
+
def _capture_session_binding(self) -> tuple[int, int, Session | None]: ...
|
|
296
|
+
|
|
290
297
|
|
|
291
298
|
class StorageListTransport(Protocol):
|
|
292
299
|
"""Transport capability required to list storage objects."""
|
|
@@ -462,25 +469,33 @@ class StorageBucket:
|
|
|
462
469
|
) -> dict[str, Any]:
|
|
463
470
|
"""Upload bytes or the remaining contents of a binary stream."""
|
|
464
471
|
mime_type = _upload_content_type(content_type)
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
+
binding = self._client._capture_session_binding()
|
|
473
|
+
self._client._session_token()
|
|
474
|
+
content = _simple_upload_bytes(data)
|
|
475
|
+
response = self._client.auth._session_request(
|
|
476
|
+
lambda token: invoke(
|
|
477
|
+
self._client._transport.upload_storage_object,
|
|
478
|
+
authorization=token,
|
|
479
|
+
bucket_name=self._name,
|
|
480
|
+
path=path,
|
|
481
|
+
data=content,
|
|
482
|
+
content_type=mime_type,
|
|
483
|
+
),
|
|
484
|
+
binding=binding,
|
|
472
485
|
)
|
|
473
486
|
payload = response_payload(response, 201)
|
|
474
487
|
return dict(payload)
|
|
475
488
|
|
|
476
489
|
def download(self, path: str, *, byte_range: str | None = None) -> bytes:
|
|
477
490
|
"""Download bytes from a path in this bucket."""
|
|
478
|
-
response =
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
491
|
+
response = self._client.auth._session_request(
|
|
492
|
+
lambda token: invoke(
|
|
493
|
+
self._client._transport.download_storage_object,
|
|
494
|
+
authorization=token,
|
|
495
|
+
bucket_name=self._name,
|
|
496
|
+
path=path,
|
|
497
|
+
byte_range=byte_range,
|
|
498
|
+
)
|
|
484
499
|
)
|
|
485
500
|
expected_status = (
|
|
486
501
|
_HTTP_PARTIAL_CONTENT
|
|
@@ -500,16 +515,18 @@ class StorageBucket:
|
|
|
500
515
|
) -> UploadSession:
|
|
501
516
|
"""Create server state for a resumable upload."""
|
|
502
517
|
transport = cast("StorageUploadSessionTransport", self._client._transport)
|
|
503
|
-
response =
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
518
|
+
response = self._client.auth._session_request(
|
|
519
|
+
lambda token: invoke(
|
|
520
|
+
transport.create_upload_session,
|
|
521
|
+
authorization=token,
|
|
522
|
+
bucket_name=self._name,
|
|
523
|
+
request=StorageUploadSessionRequest(
|
|
524
|
+
path=_storage_path(path),
|
|
525
|
+
content_type=content_type,
|
|
526
|
+
total_size=total_size,
|
|
527
|
+
part_size=part_size,
|
|
528
|
+
),
|
|
529
|
+
)
|
|
513
530
|
)
|
|
514
531
|
return _upload_session(response_payload(response, 201))
|
|
515
532
|
|
|
@@ -523,16 +540,18 @@ class StorageBucket:
|
|
|
523
540
|
) -> UploadPart:
|
|
524
541
|
"""Upload one part of a resumable upload session."""
|
|
525
542
|
transport = cast("StorageUploadPartTransport", self._client._transport)
|
|
526
|
-
response =
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
543
|
+
response = self._client.auth._session_request(
|
|
544
|
+
lambda token: invoke(
|
|
545
|
+
transport.upload_part,
|
|
546
|
+
authorization=token,
|
|
547
|
+
bucket_name=self._name,
|
|
548
|
+
request=StorageUploadPartRequest(
|
|
549
|
+
path=_storage_path(path),
|
|
550
|
+
session_id=session_id,
|
|
551
|
+
part_number=part_number,
|
|
552
|
+
data=data,
|
|
553
|
+
),
|
|
554
|
+
)
|
|
536
555
|
)
|
|
537
556
|
return _upload_part(response_payload(response, 200))
|
|
538
557
|
|
|
@@ -544,14 +563,16 @@ class StorageBucket:
|
|
|
544
563
|
) -> StorageObject:
|
|
545
564
|
"""Complete a resumable upload and return the stored object."""
|
|
546
565
|
transport = cast("StorageCompleteUploadTransport", self._client._transport)
|
|
547
|
-
response =
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
566
|
+
response = self._client.auth._session_request(
|
|
567
|
+
lambda token: invoke(
|
|
568
|
+
transport.complete_upload_session,
|
|
569
|
+
authorization=token,
|
|
570
|
+
bucket_name=self._name,
|
|
571
|
+
request=StorageUploadSessionReference(
|
|
572
|
+
path=_storage_path(path),
|
|
573
|
+
session_id=session_id,
|
|
574
|
+
),
|
|
575
|
+
)
|
|
555
576
|
)
|
|
556
577
|
payload = cast("Mapping[str, object]", response_payload(response, 200))
|
|
557
578
|
return _storage_object(payload["object"])
|
|
@@ -564,14 +585,16 @@ class StorageBucket:
|
|
|
564
585
|
) -> UploadSessionStatus:
|
|
565
586
|
"""Get resumable upload progress and uploaded part metadata."""
|
|
566
587
|
transport = cast("StorageUploadStatusTransport", self._client._transport)
|
|
567
|
-
response =
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
588
|
+
response = self._client.auth._session_request(
|
|
589
|
+
lambda token: invoke(
|
|
590
|
+
transport.get_upload_session,
|
|
591
|
+
authorization=token,
|
|
592
|
+
bucket_name=self._name,
|
|
593
|
+
request=StorageUploadSessionReference(
|
|
594
|
+
path=_storage_path(path),
|
|
595
|
+
session_id=session_id,
|
|
596
|
+
),
|
|
597
|
+
)
|
|
575
598
|
)
|
|
576
599
|
return _upload_session_status(response_payload(response, 200))
|
|
577
600
|
|
|
@@ -583,14 +606,16 @@ class StorageBucket:
|
|
|
583
606
|
) -> None:
|
|
584
607
|
"""Abort a resumable upload and discard its uploaded parts."""
|
|
585
608
|
transport = cast("StorageAbortUploadTransport", self._client._transport)
|
|
586
|
-
response =
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
609
|
+
response = self._client.auth._session_request(
|
|
610
|
+
lambda token: invoke(
|
|
611
|
+
transport.abort_upload_session,
|
|
612
|
+
authorization=token,
|
|
613
|
+
bucket_name=self._name,
|
|
614
|
+
request=StorageUploadSessionReference(
|
|
615
|
+
path=_storage_path(path),
|
|
616
|
+
session_id=session_id,
|
|
617
|
+
),
|
|
618
|
+
)
|
|
594
619
|
)
|
|
595
620
|
response_payload(response, 200)
|
|
596
621
|
|
|
@@ -662,41 +687,51 @@ class StorageBucket:
|
|
|
662
687
|
) -> StoragePage:
|
|
663
688
|
"""List objects under a prefix and return the next-page cursor."""
|
|
664
689
|
transport = cast("StorageListTransport", self._client._transport)
|
|
665
|
-
response =
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
690
|
+
response = self._client.auth._session_request(
|
|
691
|
+
lambda token: invoke(
|
|
692
|
+
transport.list_storage_objects,
|
|
693
|
+
authorization=token,
|
|
694
|
+
bucket_name=self._name,
|
|
695
|
+
prefix=prefix,
|
|
696
|
+
limit=limit,
|
|
697
|
+
cursor=cursor,
|
|
698
|
+
)
|
|
672
699
|
)
|
|
673
700
|
return _storage_page(response_payload(response, 200))
|
|
674
701
|
|
|
675
702
|
def remove(self, paths: str | Sequence[str]) -> tuple[str, ...]:
|
|
676
703
|
"""Delete one or more object paths and return their immutable snapshot."""
|
|
677
704
|
path_list = _storage_paths(paths)
|
|
678
|
-
|
|
679
|
-
authorization = self._client._session_token()
|
|
705
|
+
binding = self._client._capture_session_binding()
|
|
680
706
|
for path in path_list:
|
|
681
|
-
|
|
707
|
+
self._remove_path(path, binding)
|
|
708
|
+
return path_list
|
|
709
|
+
|
|
710
|
+
def _remove_path(self, path: str, binding: tuple[int, int, Session | None]) -> None:
|
|
711
|
+
transport = cast("StorageDeleteTransport", self._client._transport)
|
|
712
|
+
response = self._client.auth._session_request(
|
|
713
|
+
lambda token: invoke(
|
|
682
714
|
transport.delete_storage_object,
|
|
683
|
-
authorization=
|
|
715
|
+
authorization=token,
|
|
684
716
|
bucket_name=self._name,
|
|
685
717
|
path=path,
|
|
686
|
-
)
|
|
687
|
-
|
|
688
|
-
|
|
718
|
+
),
|
|
719
|
+
binding=binding,
|
|
720
|
+
)
|
|
721
|
+
response_payload(response, 200)
|
|
689
722
|
|
|
690
723
|
def move(self, from_path: str, to_path: str) -> StorageObject:
|
|
691
724
|
"""Move or rename an object within this bucket."""
|
|
692
725
|
source, destination = _storage_paths((from_path, to_path))
|
|
693
726
|
transport = cast("StorageMoveTransport", self._client._transport)
|
|
694
|
-
response =
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
727
|
+
response = self._client.auth._session_request(
|
|
728
|
+
lambda token: invoke(
|
|
729
|
+
transport.move_storage_object,
|
|
730
|
+
authorization=token,
|
|
731
|
+
bucket_name=self._name,
|
|
732
|
+
from_path=source,
|
|
733
|
+
to_path=destination,
|
|
734
|
+
)
|
|
700
735
|
)
|
|
701
736
|
return _storage_object(response_payload(response, 200))
|
|
702
737
|
|
|
@@ -704,12 +739,14 @@ class StorageBucket:
|
|
|
704
739
|
"""Copy an object to another path within this bucket."""
|
|
705
740
|
source, destination = _storage_paths((from_path, to_path))
|
|
706
741
|
transport = cast("StorageCopyTransport", self._client._transport)
|
|
707
|
-
response =
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
742
|
+
response = self._client.auth._session_request(
|
|
743
|
+
lambda token: invoke(
|
|
744
|
+
transport.copy_storage_object,
|
|
745
|
+
authorization=token,
|
|
746
|
+
bucket_name=self._name,
|
|
747
|
+
from_path=source,
|
|
748
|
+
to_path=destination,
|
|
749
|
+
)
|
|
713
750
|
)
|
|
714
751
|
return _storage_object(response_payload(response, 201))
|
|
715
752
|
|
|
@@ -718,12 +755,14 @@ class StorageBucket:
|
|
|
718
755
|
object_path = _storage_paths(path)[0]
|
|
719
756
|
visibility = _storage_visibility(is_public)
|
|
720
757
|
transport = cast("StorageVisibilityTransport", self._client._transport)
|
|
721
|
-
response =
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
758
|
+
response = self._client.auth._session_request(
|
|
759
|
+
lambda token: invoke(
|
|
760
|
+
transport.update_storage_object_visibility,
|
|
761
|
+
authorization=token,
|
|
762
|
+
bucket_name=self._name,
|
|
763
|
+
path=object_path,
|
|
764
|
+
is_public=visibility,
|
|
765
|
+
)
|
|
727
766
|
)
|
|
728
767
|
return _storage_object(response_payload(response, 200))
|
|
729
768
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: volcano-sdk-python
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Summary: Official Python SDK for Volcano
|
|
5
5
|
Project-URL: Homepage, https://volcano.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/Kong/volcano-sdk-python
|
|
@@ -25,6 +25,8 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
Use the Volcano Python SDK to access authentication, databases, storage,
|
|
26
26
|
functions, locks, logs, and realtime events. Requires Python 3.11 or later.
|
|
27
27
|
|
|
28
|
+
Start with the [Python quickstart](https://github.com/Kong/volcano-sdk-python/blob/main/docs/README.md).
|
|
29
|
+
|
|
28
30
|
## Install
|
|
29
31
|
|
|
30
32
|
```shell
|
|
@@ -219,7 +221,8 @@ events. Pass `next_cursor` back as `cursor` to continue a search. `logs.activity
|
|
|
219
221
|
returns immutable time buckets using the same resource selector and query syntax.
|
|
220
222
|
Both methods require an active user session.
|
|
221
223
|
|
|
222
|
-
Database selects, inserts, updates, deletes,
|
|
224
|
+
Database selects, inserts, updates, deletes, log reads, and authenticated storage
|
|
225
|
+
requests (including upload sessions and parts) refresh the captured
|
|
223
226
|
session after an HTTP 401 and retry the same request once. Concurrent requests reuse a successful
|
|
224
227
|
refresh for that session.
|
|
225
228
|
Replacing or signing out the session before replay, or while replay is in flight,
|
|
@@ -4,8 +4,8 @@ volcano_sdk/_lock_guard.py,sha256=EZzcwOPTFTCNUrIWIQ0-nMg9tm_nPkaYkcocgeLbu94,55
|
|
|
4
4
|
volcano_sdk/_lock_renewer.py,sha256=tFo1ZeRiPKB5VSbW61uoMpNR67ZDYyMEe-dCjpAM3As,841
|
|
5
5
|
volcano_sdk/_lock_worker.py,sha256=QhSmwR0WcwgT-7ueJMlbCogLqOakQ5eRAtyWV74fgV0,3057
|
|
6
6
|
volcano_sdk/_realtime_fetch_worker.py,sha256=zQTgFF4cIUBeAL4J2OpWAlz_sIynv2BLfu588EogAdo,9269
|
|
7
|
-
volcano_sdk/_transport.py,sha256=
|
|
8
|
-
volcano_sdk/auth.py,sha256=
|
|
7
|
+
volcano_sdk/_transport.py,sha256=PzdO7uhqvgI2L-Ff0rwZCWeF7yuH_Ty-OvZx0F7dMpo,57509
|
|
8
|
+
volcano_sdk/auth.py,sha256=Z5UCrqdvmHBS6n6ZleXya04hYV94rH4SRV1GW2yimXo,43185
|
|
9
9
|
volcano_sdk/client.py,sha256=KutjBUOEJyK73OibKilrcWazpWeXKEZYUehSAH8qxUE,10366
|
|
10
10
|
volcano_sdk/connection_string.py,sha256=LlTZigsrCF4IfAqQ8SDTWJv35hnnzNu1MfeVv5JW-Kk,2331
|
|
11
11
|
volcano_sdk/database.py,sha256=p_5OaqlBjKAtIUfKQCflXM_CGqokrVmpOMsp6KHiJ8A,9493
|
|
@@ -16,7 +16,7 @@ volcano_sdk/logs.py,sha256=lxORRQBvsnJ0BdMau19MXrIeig5_mEucQSyJ4F1CZxU,4666
|
|
|
16
16
|
volcano_sdk/models.py,sha256=43zM6LQ9eJ3Hn6q9PiVSozSmOzPSr4m4OL8G8KVb-gg,8619
|
|
17
17
|
volcano_sdk/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
18
18
|
volcano_sdk/realtime.py,sha256=VkxZyrC7PlddnCSv8wBBLVg4nPWjpyuGo1FoBWhpf6M,59295
|
|
19
|
-
volcano_sdk/storage.py,sha256=
|
|
19
|
+
volcano_sdk/storage.py,sha256=1bAgzGO-dhUCVG8B-5x40jenHeh68Id2csIJF57KSGk,26126
|
|
20
20
|
volcano_sdk/_generated/__init__.py,sha256=ZlB8wMYdN6EjpUS5W_lX3jsxq9G1kOcmUr-j3Fccfn8,164
|
|
21
21
|
volcano_sdk/_generated/client.py,sha256=GDzw6T2uRmPlUb1DImpBGxwy0dNbhmBknfvvIQW0GuU,12387
|
|
22
22
|
volcano_sdk/_generated/errors.py,sha256=trp-p5qn1_JLRxGZhdHtICaNPaCrcDCe4TgIihBravk,546
|
|
@@ -773,7 +773,7 @@ volcano_sdk/_generated/models/usage_data_point.py,sha256=d4U08JbVTiIMM_l2BmRILL1
|
|
|
773
773
|
volcano_sdk/_generated/models/variable.py,sha256=tvGDOMv77gW6j5skufnfrlNAhzCzA1F7nuPCQWx79yY,5926
|
|
774
774
|
volcano_sdk/_generated/models/variable_deploy_source.py,sha256=G_aCiFHzQx8WhJFs0GvYZEFclfTrfkDvd3kT1e3vty8,463
|
|
775
775
|
volcano_sdk/_generated/models/variable_status.py,sha256=THSsKBSiAYG4kAtBzGA4TZqxjgx8hdL0Q4qCdZfOj00,391
|
|
776
|
-
volcano_sdk_python-0.7.
|
|
777
|
-
volcano_sdk_python-0.7.
|
|
778
|
-
volcano_sdk_python-0.7.
|
|
779
|
-
volcano_sdk_python-0.7.
|
|
776
|
+
volcano_sdk_python-0.7.3.dist-info/METADATA,sha256=0lDdNzghgpaKsYFFqMZZrWCn0rUt9nqdaGWSg0FhU_U,33557
|
|
777
|
+
volcano_sdk_python-0.7.3.dist-info/WHEEL,sha256=THafob7ofN-NsuMN7Mg4qZyHaQI7KkD-QlcQatYhXPo,87
|
|
778
|
+
volcano_sdk_python-0.7.3.dist-info/licenses/LICENSE,sha256=AIHJy-5MFqM8fHfuGFTTb9a8rvJGypcVgN4aZ-7XTWw,11387
|
|
779
|
+
volcano_sdk_python-0.7.3.dist-info/RECORD,,
|
|
File without changes
|