volcano-sdk-python 0.9.0__py3-none-any.whl → 0.9.2__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/auth.py CHANGED
@@ -590,33 +590,37 @@ class Auth:
590
590
 
591
591
  def request_email_change(self, *, new_email: str) -> EmailChangeResult:
592
592
  """Request a confirmation email without changing the current session."""
593
- generation, current = self._client._capture_session()
594
- if current is None:
593
+ binding = self._client._capture_session_binding()
594
+ if binding[2] is None:
595
595
  raise AuthenticationError(_NO_ACTIVE_SESSION)
596
596
  transport = cast("AuthRequestEmailChangeTransport", self._client._transport)
597
- response = invoke(
598
- transport.auth_request_email_change,
599
- authorization=current.access_token,
600
- new_email=new_email,
597
+ response = self._session_request(
598
+ lambda access_token: invoke(
599
+ transport.auth_request_email_change,
600
+ authorization=access_token,
601
+ new_email=new_email,
602
+ ),
603
+ binding=binding,
601
604
  )
602
605
  result = _email_change_result_from_payload(response_payload(response, 200))
603
- if self._client._capture_session()[0] != generation:
604
- raise SessionChangedError
606
+ self._owned_refresh_session(binding)
605
607
  return result
606
608
 
607
609
  def cancel_email_change(self) -> None:
608
610
  """Cancel a pending email change without changing the current session."""
609
- generation, current = self._client._capture_session()
610
- if current is None:
611
+ binding = self._client._capture_session_binding()
612
+ if binding[2] is None:
611
613
  raise AuthenticationError(_NO_ACTIVE_SESSION)
612
614
  transport = cast("AuthCancelEmailChangeTransport", self._client._transport)
613
- response = invoke(
614
- transport.auth_cancel_email_change,
615
- authorization=current.access_token,
615
+ response = self._session_request(
616
+ lambda access_token: invoke(
617
+ transport.auth_cancel_email_change,
618
+ authorization=access_token,
619
+ ),
620
+ binding=binding,
616
621
  )
617
622
  response_payload(response, 200)
618
- if self._client._capture_session()[0] != generation:
619
- raise SessionChangedError
623
+ self._owned_refresh_session(binding)
620
624
 
621
625
  def confirm_email_change(self, *, token: str) -> User:
622
626
  """Confirm a pending email change and return the updated user."""
@@ -636,48 +640,54 @@ class Auth:
636
640
 
637
641
  def delete_all_other_sessions(self) -> None:
638
642
  """Delete every other session while preserving the current session."""
639
- generation, current = self._client._capture_session()
640
- if current is None:
643
+ binding = self._client._capture_session_binding()
644
+ if binding[2] is None:
641
645
  raise AuthenticationError(_NO_ACTIVE_SESSION)
642
646
  transport = cast("AuthDeleteAllMySessionsTransport", self._client._transport)
643
- response = invoke(
644
- transport.auth_delete_all_my_sessions,
645
- authorization=current.access_token,
647
+ response = self._session_request(
648
+ lambda access_token: invoke(
649
+ transport.auth_delete_all_my_sessions,
650
+ authorization=access_token,
651
+ ),
652
+ binding=binding,
646
653
  )
647
654
  response_payload(response, 204)
648
- if self._client._capture_session()[0] != generation:
649
- raise SessionChangedError
655
+ self._owned_refresh_session(binding)
650
656
 
651
657
  def list_sessions(self, *, page: int = 1, limit: int = 20) -> SessionPage:
652
658
  """List sessions in the stable offset-paginated activity order."""
653
- generation, current = self._client._capture_session()
654
- if current is None:
659
+ binding = self._client._capture_session_binding()
660
+ if binding[2] is None:
655
661
  raise AuthenticationError(_NO_ACTIVE_SESSION)
656
662
  transport = cast("AuthGetMySessionsTransport", self._client._transport)
657
- response = invoke(
658
- transport.auth_get_my_sessions,
659
- authorization=current.access_token,
660
- page=page,
661
- limit=limit,
663
+ response = self._session_request(
664
+ lambda access_token: invoke(
665
+ transport.auth_get_my_sessions,
666
+ authorization=access_token,
667
+ page=page,
668
+ limit=limit,
669
+ ),
670
+ binding=binding,
662
671
  )
663
672
  result = _session_page_from_payload(response_payload(response, 200))
664
- if self._client._capture_session()[0] != generation:
665
- raise SessionChangedError
673
+ self._owned_refresh_session(binding)
666
674
  return result
667
675
 
668
676
  def list_linked_oauth_providers(self) -> tuple[LinkedOAuthProvider, ...]:
669
677
  """List OAuth providers linked to the current account."""
670
- generation, current = self._client._capture_session()
671
- if current is None:
678
+ binding = self._client._capture_session_binding()
679
+ if binding[2] is None:
672
680
  raise AuthenticationError(_NO_ACTIVE_SESSION)
673
681
  transport = cast("AuthListOAuthProvidersTransport", self._client._transport)
674
- response = invoke(
675
- transport.auth_list_oauth_providers,
676
- authorization=current.access_token,
682
+ response = self._session_request(
683
+ lambda access_token: invoke(
684
+ transport.auth_list_oauth_providers,
685
+ authorization=access_token,
686
+ ),
687
+ binding=binding,
677
688
  )
678
689
  result = _linked_oauth_providers_from_payload(response_payload(response, 200))
679
- if self._client._capture_session()[0] != generation:
680
- raise SessionChangedError
690
+ self._owned_refresh_session(binding)
681
691
  return result
682
692
 
683
693
  def get_hosted_auth_url(
@@ -763,38 +773,42 @@ class Auth:
763
773
  def link_oauth_provider(self, *, provider: OAuthProviderName) -> str:
764
774
  """Return the authorization URL for linking an OAuth provider."""
765
775
  provider_name = _oauth_provider_name(provider)
766
- generation, current = self._client._capture_session()
767
- if current is None:
776
+ binding = self._client._capture_session_binding()
777
+ if binding[2] is None:
768
778
  raise AuthenticationError(_NO_ACTIVE_SESSION)
769
779
  transport = cast("AuthLinkOAuthProviderTransport", self._client._transport)
770
- response = invoke(
771
- transport.auth_link_oauth_provider,
772
- authorization=current.access_token,
773
- provider=provider_name,
780
+ response = self._session_request(
781
+ lambda access_token: invoke(
782
+ transport.auth_link_oauth_provider,
783
+ authorization=access_token,
784
+ provider=provider_name,
785
+ ),
786
+ binding=binding,
774
787
  )
775
788
  result = _oauth_link_from_payload(response_payload(response, 200))
776
- if self._client._capture_session()[0] != generation:
777
- raise SessionChangedError
789
+ self._owned_refresh_session(binding)
778
790
  return result
779
791
 
780
792
  def unlink_oauth_provider(self, *, provider: OAuthProviderName) -> None:
781
793
  """Unlink an OAuth provider from the current account."""
782
794
  provider_name = _oauth_provider_name(provider)
783
- generation, current = self._client._capture_session()
784
- if current is None:
795
+ binding = self._client._capture_session_binding()
796
+ if binding[2] is None:
785
797
  raise AuthenticationError(_NO_ACTIVE_SESSION)
786
798
  transport = cast(
787
799
  "AuthUnlinkOAuthProviderTransport",
788
800
  self._client._transport,
789
801
  )
790
- response = invoke(
791
- transport.auth_unlink_oauth_provider,
792
- authorization=current.access_token,
793
- provider=provider_name,
802
+ response = self._session_request(
803
+ lambda access_token: invoke(
804
+ transport.auth_unlink_oauth_provider,
805
+ authorization=access_token,
806
+ provider=provider_name,
807
+ ),
808
+ binding=binding,
794
809
  )
795
810
  response_payload(response, 204)
796
- if self._client._capture_session()[0] != generation:
797
- raise SessionChangedError
811
+ self._owned_refresh_session(binding)
798
812
 
799
813
  def get_oauth_provider_token(
800
814
  self,
@@ -803,23 +817,25 @@ class Auth:
803
817
  ) -> OAuthProviderTokenStatus:
804
818
  """Return validity metadata for a server-held OAuth provider token."""
805
819
  provider_name = _oauth_provider_name(provider)
806
- generation, current = self._client._capture_session()
807
- if current is None:
820
+ binding = self._client._capture_session_binding()
821
+ if binding[2] is None:
808
822
  raise AuthenticationError(_NO_ACTIVE_SESSION)
809
823
  transport = cast(
810
824
  "AuthGetOAuthProviderTokenTransport",
811
825
  self._client._transport,
812
826
  )
813
- response = invoke(
814
- transport.auth_get_oauth_provider_token,
815
- authorization=current.access_token,
816
- provider=provider_name,
827
+ response = self._session_request(
828
+ lambda access_token: invoke(
829
+ transport.auth_get_oauth_provider_token,
830
+ authorization=access_token,
831
+ provider=provider_name,
832
+ ),
833
+ binding=binding,
817
834
  )
818
835
  result = _oauth_provider_token_status_from_payload(
819
836
  response_payload(response, 200)
820
837
  )
821
- if self._client._capture_session()[0] != generation:
822
- raise SessionChangedError
838
+ self._owned_refresh_session(binding)
823
839
  return result
824
840
 
825
841
  def refresh_oauth_provider_token(
@@ -829,23 +845,25 @@ class Auth:
829
845
  ) -> OAuthProviderTokenStatus:
830
846
  """Refresh a server-held OAuth provider token and return its status."""
831
847
  provider_name = _oauth_provider_name(provider)
832
- generation, current = self._client._capture_session()
833
- if current is None:
848
+ binding = self._client._capture_session_binding()
849
+ if binding[2] is None:
834
850
  raise AuthenticationError(_NO_ACTIVE_SESSION)
835
851
  transport = cast(
836
852
  "AuthRefreshOAuthProviderTokenTransport",
837
853
  self._client._transport,
838
854
  )
839
- response = invoke(
840
- transport.auth_refresh_oauth_provider_token,
841
- authorization=current.access_token,
842
- provider=provider_name,
855
+ response = self._session_request(
856
+ lambda access_token: invoke(
857
+ transport.auth_refresh_oauth_provider_token,
858
+ authorization=access_token,
859
+ provider=provider_name,
860
+ ),
861
+ binding=binding,
843
862
  )
844
863
  result = _oauth_provider_token_status_from_payload(
845
864
  response_payload(response, 200)
846
865
  )
847
- if self._client._capture_session()[0] != generation:
848
- raise SessionChangedError
866
+ self._owned_refresh_session(binding)
849
867
  return result
850
868
 
851
869
  def call_oauth_api(
@@ -859,26 +877,30 @@ class Auth:
859
877
  """Call a provider API through Volcano's fixed-host server proxy."""
860
878
  provider_name = _oauth_provider_name(provider)
861
879
  request_method = _oauth_api_method(method)
862
- generation, current = self._client._capture_session()
863
- if current is None:
880
+ binding = self._client._capture_session_binding()
881
+ if binding[2] is None:
864
882
  raise AuthenticationError(_NO_ACTIVE_SESSION)
865
883
  transport = cast("AuthCallOAuthAPITransport", self._client._transport)
866
- response = invoke(
867
- transport.auth_call_oauth_api,
868
- authorization=current.access_token,
869
- provider=provider_name,
870
- endpoint=endpoint,
871
- method=request_method,
872
- body=body,
884
+ request_body = deepcopy(dict(body)) if body is not None else None
885
+ response = self._session_request(
886
+ lambda access_token: invoke(
887
+ transport.auth_call_oauth_api,
888
+ authorization=access_token,
889
+ provider=provider_name,
890
+ endpoint=endpoint,
891
+ method=request_method,
892
+ body=request_body,
893
+ ),
894
+ binding=binding,
873
895
  )
874
896
  result = _oauth_api_data_from_payload(response_payload(response, 200))
875
- if self._client._capture_session()[0] != generation:
876
- raise SessionChangedError
897
+ self._owned_refresh_session(binding)
877
898
  return result
878
899
 
879
900
  def delete_session(self, *, session_id: str) -> None:
880
901
  """Delete one session and clear local state when it is current."""
881
- generation, current = self._client._capture_session()
902
+ binding = self._client._capture_session_binding()
903
+ generation, lineage, current = binding
882
904
  if current is None:
883
905
  raise AuthenticationError(_NO_ACTIVE_SESSION)
884
906
  current_session_id = session_id_from_access_token(current.access_token)
@@ -888,24 +910,28 @@ class Auth:
888
910
  )
889
911
  transport = cast("AuthDeleteMySessionTransport", self._client._transport)
890
912
  try:
891
- response = invoke(
892
- transport.auth_delete_my_session,
893
- authorization=current.access_token,
894
- session_id=session_id,
913
+ response = self._session_request(
914
+ lambda access_token: invoke(
915
+ transport.auth_delete_my_session,
916
+ authorization=access_token,
917
+ session_id=session_id,
918
+ ),
919
+ binding=binding,
895
920
  )
896
921
  response_payload(response, 204)
897
922
  except TransportError as error:
898
923
  if deletes_current and not self._client._clear_session_if_current(
899
- generation
924
+ generation, lineage=lineage
900
925
  ):
901
926
  raise SessionChangedError from error
902
927
  raise
903
928
  if deletes_current:
904
- current_unchanged = self._client._clear_session_if_current(generation)
929
+ if not self._client._clear_session_if_current(generation, lineage=lineage):
930
+ raise SessionChangedError
905
931
  else:
906
- current_unchanged = self._client._capture_session()[0] == generation
907
- if not current_unchanged:
908
- raise SessionChangedError
932
+ _, active_lineage, active_session = self._client._capture_session_binding()
933
+ if active_lineage is not lineage or active_session is None:
934
+ raise SessionChangedError
909
935
 
910
936
  def confirm_email(self, *, token: str) -> None:
911
937
  """Confirm an email with its token without changing local state."""
volcano_sdk/realtime.py CHANGED
@@ -768,7 +768,6 @@ class Channel:
768
768
  not self._fetch_config.enabled
769
769
  or change.mode != "lightweight"
770
770
  or change.type == "DELETE"
771
- or change.schema != "public"
772
771
  or change.id is None
773
772
  or database_name is None
774
773
  ):
@@ -776,7 +775,11 @@ class Channel:
776
775
  return _PostgresFetchRequest(
777
776
  database_name=database_name,
778
777
  access_token=self._realtime._connection_token(),
779
- table=change.table,
778
+ table=(
779
+ change.table
780
+ if change.schema == "public"
781
+ else f"{change.schema}.{change.table}"
782
+ ),
780
783
  row_id=change.id,
781
784
  )
782
785
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: volcano-sdk-python
3
- Version: 0.9.0
3
+ Version: 0.9.2
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
@@ -79,14 +79,18 @@ function = client.functions.invoke(
79
79
  )
80
80
  print(function.status, function.version, function.data)
81
81
 
82
- logs = client.logs.search(
82
+ # Project logs use a control-plane project token, not this end-user session.
83
+ logs_client = VolcanoClient(
84
+ anon_key="ak_your_anon_key", access_token="vpat_your_project_token"
85
+ )
86
+ logs = logs_client.logs.search(
83
87
  "00000000-0000-4000-8000-000000000001",
84
88
  {"resource": {"type": "function"}, "limit": 100},
85
89
  )
86
90
  for event in logs.data:
87
91
  print(event["timestamp"], event["body"])
88
92
 
89
- activity = client.logs.activity(
93
+ activity = logs_client.logs.activity(
90
94
  "00000000-0000-4000-8000-000000000001",
91
95
  {"resource": {"type": "function"}, "bucket_count": 24},
92
96
  )
@@ -226,7 +230,9 @@ ran; platform failures raise typed SDK errors.
226
230
  `logs.search()` returns an immutable page of retained runtime or deployment log
227
231
  events. Pass `next_cursor` back as `cursor` to continue a search. `logs.activity()`
228
232
  returns immutable time buckets using the same resource selector and query syntax.
229
- Both methods require an active user session.
233
+ Both methods require a platform user token or a project access token.
234
+ A `read_only` project token is sufficient; end-user sessions cannot read project logs.
235
+ See the [logs guide](https://github.com/Kong/volcano-sdk-python/blob/main/docs/logs.md).
230
236
 
231
237
  Database selects, inserts, updates, deletes, log reads, and authenticated storage
232
238
  requests (including upload sessions and parts) refresh the captured
@@ -784,12 +790,12 @@ stop_changes()
784
790
  ```
785
791
 
786
792
  Binding a database automatically fetches the matching row for lightweight
787
- `INSERT` and `UPDATE` notifications in the `public` schema. The fetch uses the
793
+ `INSERT` and `UPDATE` notifications in public or custom schemas. The fetch uses the
788
794
  realtime connection's RLS-scoped access token. Compatible row lookups are
789
795
  batched while callback delivery preserves publication order.
790
796
  If the row is absent or the query fails, the callback receives the lightweight
791
- notification with its `id` and `mode` intact. Non-public schemas also retain
792
- that lightweight form. Lightweight deletes never query the database; they
797
+ notification with its `id` and `mode` intact. Custom-schema row lookups preserve
798
+ the schema from the notification. Lightweight deletes never query the database; they
793
799
  preserve `old_record`, or provide `{"id": change.id}` when no old row was
794
800
  included. Tune a channel's batching with `fetch_batch_window_ms` and
795
801
  `fetch_max_batch_size`; the defaults are 20 milliseconds and 50 rows. Set
@@ -7,7 +7,7 @@ volcano_sdk/_realtime_fetch_worker.py,sha256=zQTgFF4cIUBeAL4J2OpWAlz_sIynv2BLfu5
7
7
  volcano_sdk/_session.py,sha256=LYCv2NCDlL5Slh2YLEG8VQ8z-kDaKDYWW4vGdMvUf1U,2474
8
8
  volcano_sdk/_session_operations.py,sha256=1vI9gtwjxG2eUGT-nIYnMEgRldJqgIj2lRLukBbG64E,5518
9
9
  volcano_sdk/_transport.py,sha256=AFd47C3X1WAHwq3f9V2ux0WNzwGIn4NBxrwgaIN-xl0,58296
10
- volcano_sdk/auth.py,sha256=7eCaA9DFsJYI4KHBXG6UXNM8QZLpvedNbCwXTfozgMI,46518
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
@@ -17,7 +17,7 @@ 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
19
19
  volcano_sdk/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
20
- volcano_sdk/realtime.py,sha256=3p5ueLCeveaR4_ItqlLv-exkMCODqxDQNHj1aYB_YE4,59506
20
+ volcano_sdk/realtime.py,sha256=KJbEMEpCYqlbE4YYtu6Wt5YM379LQmWtXU-wRhni1T0,59597
21
21
  volcano_sdk/storage.py,sha256=p16OV5ADI6JjMAJ7gx2gcmwk9t8--YiIZcOSLQLVlDY,26238
22
22
  volcano_sdk/_generated/__init__.py,sha256=ZlB8wMYdN6EjpUS5W_lX3jsxq9G1kOcmUr-j3Fccfn8,164
23
23
  volcano_sdk/_generated/client.py,sha256=GDzw6T2uRmPlUb1DImpBGxwy0dNbhmBknfvvIQW0GuU,12387
@@ -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.0.dist-info/METADATA,sha256=RKoQTUaTeDCZvyej7-w-j6bQIizIf2DYEN-B5dGnCt8,35125
779
- volcano_sdk_python-0.9.0.dist-info/WHEEL,sha256=THafob7ofN-NsuMN7Mg4qZyHaQI7KkD-QlcQatYhXPo,87
780
- volcano_sdk_python-0.9.0.dist-info/licenses/LICENSE,sha256=AIHJy-5MFqM8fHfuGFTTb9a8rvJGypcVgN4aZ-7XTWw,11387
781
- volcano_sdk_python-0.9.0.dist-info/RECORD,,
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,,