volcano-sdk-python 0.9.2__py3-none-any.whl → 0.9.4__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.
@@ -12,8 +12,12 @@ from __future__ import annotations
12
12
  import threading
13
13
  import time
14
14
  from dataclasses import dataclass
15
+ from typing import TYPE_CHECKING
15
16
  from urllib.parse import urlsplit
16
17
 
18
+ if TYPE_CHECKING:
19
+ from .errors import NotFoundError
20
+
17
21
  MAX_ENTRIES = 1024
18
22
  NEGATIVE_TTL_SECONDS = 30.0
19
23
 
@@ -41,6 +45,9 @@ class CachedOutcome:
41
45
  """A cached resolve result: a resolution, or a remembered miss when None."""
42
46
 
43
47
  resolution: FunctionResolution | None
48
+ message: str = "Function was not found"
49
+ code: str | None = None
50
+ retry_after: int | None = None
44
51
 
45
52
 
46
53
  @dataclass(frozen=True, slots=True)
@@ -122,13 +129,19 @@ def store(
122
129
  _store((api_url, authorization, name), CachedOutcome(resolution), ttl_seconds)
123
130
 
124
131
 
125
- def store_missing(api_url: str, authorization: str, name: str) -> None:
132
+ def store_missing(
133
+ api_url: str, authorization: str, name: str, error: NotFoundError
134
+ ) -> None:
126
135
  """Remember briefly that a name does not resolve.
127
136
 
128
137
  A caller retrying an unknown name in a loop would otherwise re-ask the
129
138
  server on every attempt.
130
139
  """
131
- _store((api_url, authorization, name), CachedOutcome(None), NEGATIVE_TTL_SECONDS)
140
+ _store(
141
+ (api_url, authorization, name),
142
+ CachedOutcome(None, str(error), error.code, error.retry_after),
143
+ NEGATIVE_TTL_SECONDS,
144
+ )
132
145
 
133
146
 
134
147
  def _store(
volcano_sdk/_transport.py CHANGED
@@ -99,10 +99,12 @@ from ._generated.api.database_queries.query_database_update import (
99
99
  from ._generated.api.database_queries.query_database_update import (
100
100
  _get_kwargs as database_update_kwargs,
101
101
  )
102
- from ._generated.api.functions import resolve_function_for_invocation
103
102
  from ._generated.api.functions.invoke_function import (
104
103
  _get_kwargs as invoke_function_kwargs,
105
104
  )
105
+ from ._generated.api.functions.resolve_function_for_invocation import (
106
+ _get_kwargs as resolve_function_kwargs,
107
+ )
106
108
  from ._generated.api.locks import (
107
109
  force_release_project_lock,
108
110
  get_project_lock,
@@ -1643,11 +1645,10 @@ class GeneratedTransport:
1643
1645
  name: str,
1644
1646
  ) -> TransportResponse:
1645
1647
  with self._client(authorization) as client:
1646
- response = resolve_function_for_invocation.sync_detailed(
1647
- client=client,
1648
- name=name,
1648
+ response = client.get_httpx_client().request(
1649
+ **resolve_function_kwargs(name=name)
1649
1650
  )
1650
- return self._response(response)
1651
+ return self._raw_response(response)
1651
1652
 
1652
1653
  def invoke_function(
1653
1654
  self,
volcano_sdk/functions.py CHANGED
@@ -4,14 +4,19 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
  import re
7
- from collections.abc import Mapping
8
- from typing import TYPE_CHECKING, Protocol, cast
7
+ from collections.abc import Callable, Mapping
8
+ from typing import TYPE_CHECKING, Protocol, TypeVar, cast
9
9
 
10
10
  from . import _function_resolution
11
11
  from ._function_resolution import FunctionResolution
12
12
  from ._transport import TransportResponse, invoke, response_payload
13
- from .errors import NotFoundError
14
- from .models import FunctionResponse, JSONValue
13
+ from .errors import (
14
+ AuthenticationError,
15
+ NotFoundError,
16
+ SessionChangedError,
17
+ VolcanoError,
18
+ )
19
+ from .models import FunctionResponse, JSONValue, _freeze_json
15
20
 
16
21
  if TYPE_CHECKING:
17
22
  from .client import VolcanoClient
@@ -23,14 +28,60 @@ _INVALID_FUNCTION_NAME = (
23
28
  )
24
29
  _INVALID_FUNCTION_RESPONSE = "Expected a complete function response"
25
30
  _INVALID_FUNCTION_PAYLOAD = "Function payload must be a mapping"
26
- _UNKNOWN_FUNCTION = "Function was not found"
27
31
  _HTTP_SUCCESS_MIN = 200
28
32
  _HTTP_SUCCESS_MAX = 300
29
33
  _HTTP_NOT_FOUND = 404
34
+ _HTTP_UNAUTHORIZED = 401
30
35
  # Present only once the platform has dispatched to the function.
31
36
  _FUNCTION_INVOKED_HEADER = "X-Volcano-Function-Invoked"
32
37
 
33
38
 
39
+ _Result = TypeVar("_Result")
40
+
41
+
42
+ class _FunctionAuth:
43
+ def __init__(self, client: VolcanoClient) -> None:
44
+ self._client = client
45
+ self._binding = client._capture_session_binding()
46
+ self._fallback_token = client._function_token()
47
+
48
+ def run(self, operation: Callable[[str], _Result]) -> _Result:
49
+ if self._binding[2] is not None:
50
+ self._binding = self._client.auth._owned_refresh_session(self._binding)
51
+ try:
52
+ return self._run(operation)
53
+ finally:
54
+ if self._binding[2] is not None:
55
+ self._client.auth._validate_read_failure(self._binding)
56
+ elif self._client._capture_session_binding()[1] != self._binding[1]:
57
+ raise SessionChangedError
58
+
59
+ def _run(self, operation: Callable[[str], _Result]) -> _Result:
60
+ try:
61
+ return operation(self._token())
62
+ except AuthenticationError as original:
63
+ if self._binding[2] is None or original.status != _HTTP_UNAUTHORIZED:
64
+ raise
65
+ try:
66
+ # Resolve has released its cache lock before refresh callbacks run.
67
+ self._client.auth._refresh_session_for_binding(self._binding)
68
+ except SessionChangedError:
69
+ raise
70
+ except VolcanoError:
71
+ raise original from None
72
+ return operation(self._token())
73
+
74
+ def _token(self) -> str:
75
+ if self._binding[2] is None:
76
+ if self._client._capture_session_binding()[1] != self._binding[1]:
77
+ raise SessionChangedError
78
+ return self._fallback_token
79
+ session = self._client.auth._owned_refresh_session(self._binding)[2]
80
+ if session is None:
81
+ raise SessionChangedError
82
+ return session.access_token
83
+
84
+
34
85
  class FunctionsTransport(Protocol):
35
86
  """Transport operations required by the functions facade."""
36
87
 
@@ -77,13 +128,17 @@ class Functions:
77
128
  payload: Mapping[str, JSONValue] | None = None,
78
129
  ) -> FunctionResponse:
79
130
  """Resolve and invoke a function with an optional JSON object payload."""
131
+ auth = _FunctionAuth(self._client)
80
132
  name = _function_name(name)
81
133
  request_payload = _function_payload(payload)
82
- authorization = self._client._function_token()
83
134
  transport = cast("FunctionsTransport", self._client._transport)
84
- resolution = self._resolve(transport, authorization, name)
85
- response = self._invoke_resolved(
86
- transport, authorization, resolution, request_payload
135
+ authorization, resolution = auth.run(
136
+ lambda token: (token, self._resolve(transport, token, name))
137
+ )
138
+ response = auth.run(
139
+ lambda token: self._invoke_resolved(
140
+ transport, token, resolution, request_payload
141
+ )
87
142
  )
88
143
  if _stale_mapping(response):
89
144
  # The function was deleted and recreated, so the cached identity no
@@ -91,9 +146,13 @@ class Functions:
91
146
  _function_resolution.forget(
92
147
  self._client._api_base_url(), authorization, name
93
148
  )
94
- resolution = self._resolve(transport, authorization, name)
95
- response = self._invoke_resolved(
96
- transport, authorization, resolution, request_payload
149
+ _, resolution = auth.run(
150
+ lambda token: (token, self._resolve(transport, token, name))
151
+ )
152
+ response = auth.run(
153
+ lambda token: self._invoke_resolved(
154
+ transport, token, resolution, request_payload
155
+ )
97
156
  )
98
157
  return self._response(response)
99
158
 
@@ -118,7 +177,13 @@ class Functions:
118
177
  invoke_url=resolution.invoke_url,
119
178
  payload=payload,
120
179
  )
121
- return cast("TransportResponse", response)
180
+ response = cast("TransportResponse", response)
181
+ if (
182
+ response.status_code == _HTTP_UNAUTHORIZED
183
+ and _header(response.headers, _FUNCTION_INVOKED_HEADER) is None
184
+ ):
185
+ response_payload(response, _HTTP_SUCCESS_MIN)
186
+ return response
122
187
 
123
188
  def _resolve(
124
189
  self,
@@ -148,7 +213,12 @@ class Functions:
148
213
  if cached is None:
149
214
  return None
150
215
  if cached.resolution is None:
151
- raise NotFoundError(_UNKNOWN_FUNCTION, status=_HTTP_NOT_FOUND)
216
+ raise NotFoundError(
217
+ cached.message,
218
+ status=_HTTP_NOT_FOUND,
219
+ code=cached.code,
220
+ retry_after=cached.retry_after,
221
+ )
152
222
  return cached.resolution
153
223
 
154
224
  def _resolve_uncached(
@@ -163,9 +233,11 @@ class Functions:
163
233
  authorization=authorization,
164
234
  name=name,
165
235
  )
166
- if int(resolved.status_code) == _HTTP_NOT_FOUND:
167
- _function_resolution.store_missing(api_url, authorization, name)
168
- payload = response_payload(resolved, _HTTP_SUCCESS_MIN)
236
+ try:
237
+ payload = response_payload(resolved, _HTTP_SUCCESS_MIN)
238
+ except NotFoundError as error:
239
+ _function_resolution.store_missing(api_url, authorization, name, error)
240
+ raise
169
241
  resolution = self._resolution(payload, api_url)
170
242
  _function_resolution.store(
171
243
  api_url, authorization, name, resolution, self._cache_ttl(payload)
@@ -269,9 +341,9 @@ def _function_name(value: object) -> str:
269
341
  return value
270
342
 
271
343
 
272
- def _function_payload(value: object) -> dict[str, JSONValue]:
344
+ def _function_payload(value: object) -> Mapping[str, JSONValue]:
273
345
  if value is None:
274
346
  return {}
275
347
  if not isinstance(value, Mapping):
276
348
  raise TypeError(_INVALID_FUNCTION_PAYLOAD)
277
- return dict(cast("Mapping[str, JSONValue]", value))
349
+ return cast("Mapping[str, JSONValue]", _freeze_json(cast("JSONValue", value)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: volcano-sdk-python
3
- Version: 0.9.2
3
+ Version: 0.9.4
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
@@ -26,6 +26,9 @@ 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
28
  Start with the [Python quickstart](https://github.com/Kong/volcano-sdk-python/blob/main/docs/README.md).
29
+ See the [functions guide](https://github.com/Kong/volcano-sdk-python/blob/main/docs/functions.md) for invocation identity and response handling.
30
+
31
+ See [Authentication](https://github.com/Kong/volcano-sdk-python/blob/main/docs/authentication.md) for account, session, email, and OAuth workflows.
29
32
 
30
33
  ## Install
31
34
 
@@ -54,13 +57,15 @@ client = VolcanoClient(
54
57
 
55
58
  sign_up = client.auth.sign_up(
56
59
  email="new-user@example.com",
57
- password="secret",
60
+ password="correct-horse-battery-staple",
58
61
  metadata={"display_name": "New User"},
59
62
  )
60
63
  if sign_up.confirmation_required:
61
64
  print(sign_up.message)
62
65
 
63
- session = client.auth.sign_in(email="user@example.com", password="secret")
66
+ session = client.auth.sign_in(
67
+ email="user@example.com", password="correct-horse-battery-staple"
68
+ )
64
69
  current_session = client.auth.get_session()
65
70
  assert current_session == session
66
71
 
@@ -68,7 +73,7 @@ user = client.auth.get_user()
68
73
  assert user.id == session.user_id
69
74
 
70
75
  updated_user = client.auth.update_user(
71
- password="new-secret",
76
+ password="new-correct-horse-battery-staple",
72
77
  metadata={"display_name": "Grace", "avatar": None},
73
78
  )
74
79
  assert updated_user.id == session.user_id
@@ -218,14 +223,21 @@ The request goes to the function's own domain rather than to `api_url`, so an
218
223
  egress rule that allows only the API host will block it; the resolved endpoint
219
224
  is cached for the lifetime the platform gives it. Deployments with no public
220
225
  function domain invoke through the API host instead.
221
- It uses the active user session when present, then a configured service key,
226
+ It uses the current session token, including a supplied `access_token`, then a configured service key,
222
227
  then the anonymous key. An anonymous key can invoke a public function without a
223
228
  user session; the function receives no user identity. The immutable result
224
229
  includes the response body, status, headers, and `X-Volcano-Version`. The body
225
230
  can be a JSON object, array, scalar, or text; an empty body returns `None`.
226
231
  JSON arrays become immutable tuples. Invalid JSON is returned as text. A
227
- function's own non-2xx response is returned when the version header proves it
228
- ran; platform failures raise typed SDK errors.
232
+ function's own non-2xx response is returned when Volcano confirms it ran;
233
+ non-success platform HTTP responses raise typed SDK errors.
234
+
235
+ Function resolution and invocation recover from a platform HTTP 401 before dispatch:
236
+ the SDK refreshes the captured session and retries the rejected request once.
237
+ Concurrent calls share successful recovery. Replacing or signing out that session
238
+ prevents replay under another identity. The call preserves its original payload values.
239
+ A function's own response, HTTP 403, or a network failure never triggers this retry.
240
+ Anonymous and service keys do not refresh.
229
241
 
230
242
  `logs.search()` returns an immutable page of retained runtime or deployment log
231
243
  events. Pass `next_cursor` back as `cursor` to continue a search. `logs.activity()`
@@ -318,7 +330,9 @@ The signup acknowledgement is identical for new and existing email addresses. Pa
318
330
 
319
331
  ```python
320
332
  result = client.auth.sign_up(
321
- email="new-user@example.com", password="secret", sign_in_when_allowed=True
333
+ email="new-user@example.com",
334
+ password="correct-horse-battery-staple",
335
+ sign_in_when_allowed=True,
322
336
  )
323
337
  session = result.session # None when no follow-up sign-in ran.
324
338
  ```
@@ -334,21 +348,23 @@ request. It is cached data, not proof of authentication; use `auth.get_user()`
334
348
  to fetch the server-validated profile. Existing three-field `Session` construction
335
349
  still works, with `user=None`. An adopted snapshot must have the same user ID.
336
350
  Successful `get_user()`, `update_user()`, `convert_anonymous()`, and
337
- `confirm_email_change()` calls update that local snapshot without changing tokens
338
- or emitting an auth-state event. Previously returned sessions remain immutable.
351
+ `confirm_email_change()` calls update that local snapshot. Automatic HTTP 401 recovery
352
+ can rotate credentials and emit `TOKEN_REFRESHED`; the profile update itself does not. Previously returned sessions remain immutable.
339
353
  Profile identity checks compare UUID values; the session retains its original
340
354
  user ID spelling, including in the cached snapshot.
341
355
 
342
356
  `get_user()` sends the active access token to Volcano and returns an immutable, server-validated
343
357
  profile with the complete public AuthUser fields. Profile timestamps are timezone-aware `datetime`
344
358
  values, and nested user and application metadata are immutable. The request updates the cached
345
- profile without changing credentials. If another authentication operation replaces the session
359
+ profile without changing credentials unless HTTP 401 recovery requires a refresh.
360
+ Successful recovery rotates credentials and emits `TOKEN_REFRESHED`. If another authentication operation replaces the session
346
361
  while the request is in flight, `get_user()` raises `SessionChangedError` instead of returning a
347
362
  profile for stale credentials.
348
363
 
349
364
  `update_user()` updates the current user's password, metadata, or both. Metadata is a shallow patch:
350
365
  omitted keys remain unchanged, and setting a key to `None` removes it. The method returns the same
351
- immutable profile type as `get_user()` and updates the cached profile without changing credentials.
366
+ immutable profile type as `get_user()` and updates the cached profile without changing credentials unless HTTP 401 recovery requires a refresh.
367
+ Successful recovery rotates credentials and emits `TOKEN_REFRESHED`.
352
368
  It also rejects a response if another authentication operation replaces the session while the
353
369
  update is in flight.
354
370
 
@@ -436,7 +452,9 @@ hosted_url = client.auth.get_hosted_auth_url(
436
452
  ```
437
453
 
438
454
  Store `hosted_state` in the user's signed server-side session before redirecting to `hosted_url`.
439
- After parsing the returned fragment into a `Session`, validate and adopt it atomically:
455
+ In the callback, atomically fetch and delete the stored state before validation,
456
+ even if validation or adoption fails. Reject a missing or already-consumed state.
457
+ After parsing the returned fragment into a `Session`, validate and adopt it:
440
458
 
441
459
  ```python
442
460
  session = client.auth.adopt_hosted_auth_session(
@@ -465,8 +483,9 @@ authorization_url = client.auth.sign_in_with_oauth(
465
483
  ```
466
484
 
467
485
  Store `oauth_state` in the user's signed server-side session, then redirect the user to the returned
468
- URL. In the callback, pass the returned and stored states to the SDK so it rejects login CSRF before
469
- exchanging the one-time code:
486
+ URL. In the callback, atomically fetch and delete the stored nonce as `stored_oauth_state`;
487
+ reject a missing or already-consumed nonce. Pass the returned and consumed states to
488
+ the SDK so it rejects login CSRF before exchanging the one-time code:
470
489
 
471
490
  ```python
472
491
  session = client.auth.exchange_oauth_code(
@@ -560,9 +579,11 @@ Revoke one session by ID:
560
579
  client.auth.delete_session(session_id="00000000-0000-4000-8000-000000000099")
561
580
  ```
562
581
 
563
- The request uses the current access token. Deleting that token's own session clears local
564
- credentials, including when the request outcome is uncertain; deleting another session preserves
565
- them. If another authentication operation replaces the session before deletion finishes, the method
582
+ The request uses the current access token. When its JWT contains a readable UUID `session_id`,
583
+ deleting that session clears local credentials even if the request outcome is uncertain.
584
+ Without that identifier, the SDK cannot recognize self-deletion. Deleting another session does not
585
+ itself clear local state. HTTP 401 recovery can rotate credentials and emit `TOKEN_REFRESHED`;
586
+ a server-rejected refresh clears the captured session before the operation raises. If another authentication operation replaces the session before deletion finishes, the method
566
587
  raises `SessionChangedError` instead of clearing the replacement or acknowledging a stale result.
567
588
 
568
589
  Create an anonymous account and make its tokens the current session:
@@ -574,12 +595,12 @@ session = client.auth.sign_in_anonymously(metadata={"device": "mobile"})
574
595
  Anonymous sign-ins must be enabled for the project. Convert the account before signing out if the
575
596
  user needs to recover it later.
576
597
 
577
- Attach email credentials without changing the anonymous user's ID or current session:
598
+ Attach email credentials while preserving the anonymous user's ID:
578
599
 
579
600
  ```python
580
601
  user = client.auth.convert_anonymous(
581
602
  email="user@example.com",
582
- password="secure-password",
603
+ password="a-long-example-password-2026",
583
604
  metadata={"display_name": "Ada"},
584
605
  )
585
606
  ```
@@ -591,7 +612,7 @@ Set a new password with the recovery token from that email:
591
612
  ```python
592
613
  client.auth.reset_password(
593
614
  token="recovery-token",
594
- new_password="new-secret",
615
+ new_password="new-correct-horse-battery-staple",
595
616
  )
596
617
  ```
597
618
 
@@ -602,10 +623,13 @@ when the reset flow completes.
602
623
  To start with only a supplied user access token, pass `access_token` to
603
624
  `VolcanoClient`. Construction makes no request and leaves `refresh_token`,
604
625
  `user_id`, and `user` as `None` until supplied or validated by the server.
605
- `get_user()` validates and caches the profile without changing credentials.
626
+ `get_user()` validates and caches the profile without changing credentials unless HTTP 401 recovery requires a refresh.
627
+ Successful recovery rotates credentials and emits `TOKEN_REFRESHED`.
606
628
  Without a refresh token, `refresh_session()` raises `AuthenticationError` and
607
- `sign_out()` revokes the server session using the access token and clears local state.
608
- Supply `refresh_token` with `access_token` to enable refresh. See the [token bootstrap example](https://github.com/Kong/volcano-sdk-python/blob/main/docs/README.md#use-a-supplied-access-token).
629
+ `sign_out()` clears local state and revokes the server session when the access JWT
630
+ contains a readable UUID `session_id`.
631
+ Supplied credentials require both a refresh token and an access JWT with a readable UUID
632
+ `session_id` to enable refresh. See the [token bootstrap example](https://github.com/Kong/volcano-sdk-python/blob/main/docs/README.md#use-a-supplied-access-token).
609
633
 
610
634
  Copy a complete native session into another client's memory:
611
635
 
@@ -630,7 +654,8 @@ assert client.auth.get_session() is refreshed
630
654
  ```
631
655
 
632
656
  On success, `refresh_session()` replaces the in-memory session and returns the immutable new
633
- snapshot. An authentication failure clears the session that initiated the request. Server and
657
+ snapshot. An authentication rejection from the refresh endpoint clears the captured session.
658
+ Missing refresh credentials, failed session-continuity checks, server errors, and
634
659
  transport failures preserve it, and a late response never replaces a newer session. The SDK does
635
660
  not persist sessions.
636
661
 
@@ -652,8 +677,8 @@ subscription.unsubscribe()
652
677
  Registration queues `INITIAL_SESSION`. It normally arrives before registration returns, but an
653
678
  existing notification dispatch may deliver it afterward. Successful session creation, refresh, and
654
679
  local clearing emit `SIGNED_IN`, `TOKEN_REFRESHED`, and `SIGNED_OUT`. Callbacks are delivered locally
655
- in transition order after the state lock is released, and callback failures cannot interrupt auth
656
- operations. Unsubscribing prevents queued and future delivery; a callback already selected for
680
+ in transition order after the state lock is released. Ordinary callback `Exception` failures are
681
+ isolated; exceptions such as `KeyboardInterrupt` propagate after the session transition has committed. Unsubscribing prevents queued and future delivery; a callback already selected for
657
682
  delivery may finish after `unsubscribe()` returns. The SDK does not broadcast between processes or
658
683
  persist sessions.
659
684
 
@@ -665,8 +690,10 @@ assert client.auth.get_session() is None
665
690
  ```
666
691
 
667
692
  Sign-out uses the refresh token directly when the SDK received both credentials together from
668
- sign-in or a validated refresh. Supplied credentials use the access-token session; on HTTP 401,
669
- the SDK can refresh once and revoke that same session without adopting the renewed credentials.
693
+ sign-in or a validated refresh. Supplied credentials use the access-token session when its JWT
694
+ contains a readable UUID `session_id`; on HTTP 401, the SDK can refresh once and revoke that
695
+ same session without adopting the renewed credentials. Without that identifier, sign-out uses
696
+ the supplied refresh token, or only clears local state if no refresh token is available.
670
697
  Calling `sign_out()` without a session succeeds without a request. A revocation failure is raised
671
698
  after the captured local session is cleared. Sign-out waits for an already-running refresh and uses its validated credentials.
672
699
  Later refresh attempts raise `SessionChangedError` without a request. Concurrent sign-out calls
@@ -1,18 +1,18 @@
1
1
  volcano_sdk/__init__.py,sha256=rPSFMLjFbxeQvSRkL1Ee8MsNWArIhs8fgNFgtDuMNzI,1954
2
- volcano_sdk/_function_resolution.py,sha256=_gC3LY6x71NtJc_o9d9eq3N27Z-T_Un3p2-XRu2-Cqs,5088
2
+ volcano_sdk/_function_resolution.py,sha256=g04npZTP6h2ePEAnpJryP889l5erCfFkcLloBV84eTs,5387
3
3
  volcano_sdk/_lock_guard.py,sha256=VhHTgBc4e5EDj8j15vVIhdBOTp6fvD628x3hVBeF39o,5794
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
7
  volcano_sdk/_session.py,sha256=LYCv2NCDlL5Slh2YLEG8VQ8z-kDaKDYWW4vGdMvUf1U,2474
8
8
  volcano_sdk/_session_operations.py,sha256=1vI9gtwjxG2eUGT-nIYnMEgRldJqgIj2lRLukBbG64E,5518
9
- volcano_sdk/_transport.py,sha256=AFd47C3X1WAHwq3f9V2ux0WNzwGIn4NBxrwgaIN-xl0,58296
9
+ volcano_sdk/_transport.py,sha256=ox_wKKEW42gm2307uK9vIiQFB5l8pzb0ifWXxkzPiHQ,58331
10
10
  volcano_sdk/auth.py,sha256=iKq8o0K8geVKXrnLzhvOjAQoX_Nd0yQDJqDH4bemWaM,47366
11
11
  volcano_sdk/client.py,sha256=CJJnf_iTcXnyY2Y57LXJVAn39mTUsepblUg9op-Thzo,12283
12
12
  volcano_sdk/connection_string.py,sha256=LlTZigsrCF4IfAqQ8SDTWJv35hnnzNu1MfeVv5JW-Kk,2331
13
13
  volcano_sdk/database.py,sha256=p_5OaqlBjKAtIUfKQCflXM_CGqokrVmpOMsp6KHiJ8A,9493
14
14
  volcano_sdk/errors.py,sha256=ffs66FIN_jhyh5SMj7KdXb-zVV3DSgVK6xJEPNA5h9Y,1613
15
- volcano_sdk/functions.py,sha256=zDeAKyCieNnI6wzb9iZMlg9_cbjaYWXYbXHb7jzCle4,10126
15
+ volcano_sdk/functions.py,sha256=31OWRkzBAFjvgynErRFfgjhvzA_sIfv73gz7gYX3G-0,12645
16
16
  volcano_sdk/locks.py,sha256=eSkidfHQ_wml5-1LT2hBtHxeALP6E1cGYK0FzHjbrNk,9241
17
17
  volcano_sdk/logs.py,sha256=lxORRQBvsnJ0BdMau19MXrIeig5_mEucQSyJ4F1CZxU,4666
18
18
  volcano_sdk/models.py,sha256=n5EdzkWzmOstXsuFlvfGOILRemQAqG2P4VCLMelW8SA,8690
@@ -775,7 +775,7 @@ volcano_sdk/_generated/models/usage_data_point.py,sha256=d4U08JbVTiIMM_l2BmRILL1
775
775
  volcano_sdk/_generated/models/variable.py,sha256=tvGDOMv77gW6j5skufnfrlNAhzCzA1F7nuPCQWx79yY,5926
776
776
  volcano_sdk/_generated/models/variable_deploy_source.py,sha256=G_aCiFHzQx8WhJFs0GvYZEFclfTrfkDvd3kT1e3vty8,463
777
777
  volcano_sdk/_generated/models/variable_status.py,sha256=THSsKBSiAYG4kAtBzGA4TZqxjgx8hdL0Q4qCdZfOj00,391
778
- volcano_sdk_python-0.9.2.dist-info/METADATA,sha256=rJFF7ZXI76Kjkc_CyNAl6Dg5ryRKy2VjiOV4HBtIGLQ,35536
779
- volcano_sdk_python-0.9.2.dist-info/WHEEL,sha256=THafob7ofN-NsuMN7Mg4qZyHaQI7KkD-QlcQatYhXPo,87
780
- volcano_sdk_python-0.9.2.dist-info/licenses/LICENSE,sha256=AIHJy-5MFqM8fHfuGFTTb9a8rvJGypcVgN4aZ-7XTWw,11387
781
- volcano_sdk_python-0.9.2.dist-info/RECORD,,
778
+ volcano_sdk_python-0.9.4.dist-info/METADATA,sha256=RxgSj08eiYMbgWjVj-CXOia39awfCLKsyjRmytGlwmY,37824
779
+ volcano_sdk_python-0.9.4.dist-info/WHEEL,sha256=THafob7ofN-NsuMN7Mg4qZyHaQI7KkD-QlcQatYhXPo,87
780
+ volcano_sdk_python-0.9.4.dist-info/licenses/LICENSE,sha256=AIHJy-5MFqM8fHfuGFTTb9a8rvJGypcVgN4aZ-7XTWw,11387
781
+ volcano_sdk_python-0.9.4.dist-info/RECORD,,