volcano-sdk-python 0.13.4__py3-none-any.whl → 0.13.5__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_base.py +47 -0
- volcano_sdk/_auth_context.py +88 -0
- volcano_sdk/_auth_email.py +185 -0
- volcano_sdk/_auth_oauth.py +371 -0
- volcano_sdk/_auth_requests.py +318 -0
- volcano_sdk/_auth_values.py +478 -0
- volcano_sdk/_callbacks.py +41 -0
- volcano_sdk/_client_context.py +124 -0
- volcano_sdk/_client_session.py +63 -0
- volcano_sdk/_database_response.py +37 -0
- volcano_sdk/_durable_duration.py +148 -0
- volcano_sdk/_durable_engine.py +305 -0
- volcano_sdk/_durable_modules.py +185 -0
- volcano_sdk/_durable_options.py +85 -0
- volcano_sdk/_durable_protocols.py +136 -0
- volcano_sdk/_durable_response.py +234 -0
- volcano_sdk/_durable_results.py +136 -0
- volcano_sdk/_function_requests.py +76 -0
- volcano_sdk/_function_resolution.py +11 -11
- volcano_sdk/_function_values.py +209 -0
- volcano_sdk/_generated/api/anon_keys/create_anon_key.py +11 -11
- volcano_sdk/_generated/api/anon_keys/get_anon_key.py +16 -16
- volcano_sdk/_generated/api/anon_keys/list_anon_keys.py +11 -11
- volcano_sdk/_generated/api/anon_keys/regenerate_anon_key.py +16 -16
- volcano_sdk/_generated/api/anon_keys/revoke_anon_key.py +16 -16
- volcano_sdk/_generated/api/anon_keys/set_default_anon_key.py +16 -16
- volcano_sdk/_generated/api/auth_admin/ban_auth_user.py +16 -16
- volcano_sdk/_generated/api/auth_admin/delete_all_user_sessions.py +12 -12
- volcano_sdk/_generated/api/auth_admin/delete_auth_user.py +12 -12
- volcano_sdk/_generated/api/auth_admin/delete_user_session.py +15 -15
- volcano_sdk/_generated/api/auth_admin/get_auth_insights.py +11 -11
- volcano_sdk/_generated/api/auth_admin/get_auth_user.py +16 -16
- volcano_sdk/_generated/api/auth_admin/list_auth_users.py +11 -11
- volcano_sdk/_generated/api/auth_admin/list_user_sessions.py +16 -16
- volcano_sdk/_generated/api/auth_admin/unban_auth_user.py +16 -16
- volcano_sdk/_generated/api/auth_configuration/configure_auth_methods.py +9 -9
- volcano_sdk/_generated/api/auth_configuration/create_email_template.py +19 -19
- volcano_sdk/_generated/api/auth_configuration/delete_auth_page_layout.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/delete_auth_page_theme.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/delete_email_template.py +15 -15
- volcano_sdk/_generated/api/auth_configuration/get_auth_config.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/get_auth_hosted_page.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/get_auth_methods.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/get_auth_page_appearance.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/get_default_email_template.py +6 -6
- volcano_sdk/_generated/api/auth_configuration/get_default_email_templates.py +6 -6
- volcano_sdk/_generated/api/auth_configuration/get_email_template.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/get_hosted_login_options.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/hosted_login_check_email.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/list_email_templates.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/preview_auth_page.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/render_auth_page_preview.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/render_default_managed_auth_page.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/render_managed_auth_page.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/test_email_config.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/update_auth_config.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/update_auth_hosted_page.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/update_auth_page_layout.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/update_auth_page_theme.py +11 -11
- volcano_sdk/_generated/api/auth_configuration/update_email_template.py +23 -23
- volcano_sdk/_generated/api/authentication/auth_cancel_email_change.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_confirm_email.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_confirm_email_change.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_convert_anonymous.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_delete_all_my_sessions.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_delete_my_session.py +11 -11
- volcano_sdk/_generated/api/authentication/auth_forgot_password.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_get_my_sessions.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_get_password_policy.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_get_user.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_list_identities.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_list_methods.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_logout.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_promote_method.py +11 -11
- volcano_sdk/_generated/api/authentication/auth_refresh.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_request_email_change.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_resend_confirmation.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_reset_password.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_signin.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_signup.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_signup_anonymous.py +6 -6
- volcano_sdk/_generated/api/authentication/auth_unlink_identity.py +11 -11
- volcano_sdk/_generated/api/authentication/auth_update_user.py +6 -6
- volcano_sdk/_generated/api/database_backups/create_database_backup.py +11 -11
- volcano_sdk/_generated/api/database_backups/create_database_restore.py +11 -11
- volcano_sdk/_generated/api/database_backups/delete_database_backup.py +11 -11
- volcano_sdk/_generated/api/database_backups/get_database_backup.py +11 -11
- volcano_sdk/_generated/api/database_backups/get_database_backup_schedule.py +11 -11
- volcano_sdk/_generated/api/database_backups/get_database_restore.py +16 -16
- volcano_sdk/_generated/api/database_backups/list_database_backups.py +11 -11
- volcano_sdk/_generated/api/database_backups/list_database_restores.py +11 -11
- volcano_sdk/_generated/api/database_backups/update_database_backup_schedule.py +11 -11
- volcano_sdk/_generated/api/database_branches/create_database_branch.py +11 -11
- volcano_sdk/_generated/api/database_branches/delete_database_branch.py +11 -11
- volcano_sdk/_generated/api/database_branches/get_database_branch.py +11 -11
- volcano_sdk/_generated/api/database_branches/list_database_branches.py +11 -11
- volcano_sdk/_generated/api/database_branches/reset_database_branch.py +11 -11
- volcano_sdk/_generated/api/database_branches/reset_database_branch_password.py +11 -11
- volcano_sdk/_generated/api/database_branches/update_database_branch.py +11 -11
- volcano_sdk/_generated/api/database_queries/query_database_branch_delete.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_branch_insert.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_branch_ping.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_branch_select.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_branch_update.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_delete.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_insert.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_ping.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_select.py +6 -6
- volcano_sdk/_generated/api/database_queries/query_database_update.py +6 -6
- volcano_sdk/_generated/api/databases/create_database.py +15 -15
- volcano_sdk/_generated/api/databases/delete_database.py +11 -11
- volcano_sdk/_generated/api/databases/get_database.py +11 -11
- volcano_sdk/_generated/api/databases/get_database_stats.py +11 -11
- volcano_sdk/_generated/api/databases/get_project_database_queries.py +19 -19
- volcano_sdk/_generated/api/databases/list_database_regions.py +6 -6
- volcano_sdk/_generated/api/databases/list_databases.py +11 -11
- volcano_sdk/_generated/api/databases/list_postgres_versions.py +6 -6
- volcano_sdk/_generated/api/databases/reset_database_password.py +11 -11
- volcano_sdk/_generated/api/databases/update_database_type.py +11 -11
- volcano_sdk/_generated/api/durable_functions/create_durable_function.py +11 -11
- volcano_sdk/_generated/api/durable_functions/create_durable_function_scheduler.py +11 -11
- volcano_sdk/_generated/api/durable_functions/delete_durable_function.py +11 -11
- volcano_sdk/_generated/api/durable_functions/delete_durable_function_scheduler.py +16 -16
- volcano_sdk/_generated/api/durable_functions/get_durable_execution.py +16 -16
- volcano_sdk/_generated/api/durable_functions/get_durable_function.py +11 -11
- volcano_sdk/_generated/api/durable_functions/get_durable_function_scheduler.py +16 -16
- volcano_sdk/_generated/api/durable_functions/list_durable_executions.py +11 -11
- volcano_sdk/_generated/api/durable_functions/list_durable_function_deployments.py +11 -11
- volcano_sdk/_generated/api/durable_functions/list_durable_function_schedulers.py +11 -11
- volcano_sdk/_generated/api/durable_functions/list_durable_functions.py +11 -11
- volcano_sdk/_generated/api/durable_functions/start_durable_execution.py +11 -11
- volcano_sdk/_generated/api/durable_functions/start_durable_execution_from_application.py +6 -6
- volcano_sdk/_generated/api/durable_functions/stop_durable_execution.py +16 -16
- volcano_sdk/_generated/api/durable_functions/update_durable_function_scheduler.py +16 -16
- volcano_sdk/_generated/api/frontends/create_frontend.py +11 -11
- volcano_sdk/_generated/api/frontends/create_frontend_custom_domain.py +20 -20
- volcano_sdk/_generated/api/frontends/delete_frontend.py +16 -16
- volcano_sdk/_generated/api/frontends/delete_frontend_custom_domain.py +16 -16
- volcano_sdk/_generated/api/frontends/get_frontend.py +16 -16
- volcano_sdk/_generated/api/frontends/get_frontend_custom_domain.py +16 -16
- volcano_sdk/_generated/api/frontends/get_frontend_usage_history.py +16 -16
- volcano_sdk/_generated/api/frontends/list_frontend_deployments.py +16 -16
- volcano_sdk/_generated/api/frontends/list_frontends.py +11 -11
- volcano_sdk/_generated/api/frontends/list_project_custom_domains.py +11 -11
- volcano_sdk/_generated/api/frontends/redeploy_frontend.py +16 -16
- volcano_sdk/_generated/api/functions/create_function.py +11 -11
- volcano_sdk/_generated/api/functions/create_function_scheduler.py +16 -16
- volcano_sdk/_generated/api/functions/create_functions_batch.py +11 -11
- volcano_sdk/_generated/api/functions/delete_function.py +16 -16
- volcano_sdk/_generated/api/functions/delete_function_scheduler.py +21 -21
- volcano_sdk/_generated/api/functions/get_function.py +16 -16
- volcano_sdk/_generated/api/functions/get_function_scheduler.py +21 -21
- volcano_sdk/_generated/api/functions/invoke_function.py +11 -11
- volcano_sdk/_generated/api/functions/list_function_deployments.py +16 -16
- volcano_sdk/_generated/api/functions/list_function_regions.py +6 -6
- volcano_sdk/_generated/api/functions/list_function_runtimes.py +6 -6
- volcano_sdk/_generated/api/functions/list_function_schedulers.py +16 -16
- volcano_sdk/_generated/api/functions/list_functions.py +11 -11
- volcano_sdk/_generated/api/functions/list_project_schedulers.py +11 -11
- volcano_sdk/_generated/api/functions/resolve_function_for_invocation.py +6 -6
- volcano_sdk/_generated/api/functions/update_function.py +16 -16
- volcano_sdk/_generated/api/functions/update_function_scheduler.py +21 -21
- volcano_sdk/_generated/api/git_connections/delete_git_connection.py +11 -11
- volcano_sdk/_generated/api/git_connections/git_connect_callback.py +6 -6
- volcano_sdk/_generated/api/git_connections/list_git_connections.py +6 -6
- volcano_sdk/_generated/api/git_connections/list_git_installation_repositories.py +11 -11
- volcano_sdk/_generated/api/git_connections/list_git_installations.py +11 -11
- volcano_sdk/_generated/api/git_connections/start_git_connect.py +6 -6
- volcano_sdk/_generated/api/locks/acquire_project_lock.py +18 -18
- volcano_sdk/_generated/api/locks/force_release_project_lock.py +12 -12
- volcano_sdk/_generated/api/locks/get_project_lock.py +12 -12
- volcano_sdk/_generated/api/locks/release_project_lock.py +18 -18
- volcano_sdk/_generated/api/locks/renew_project_lock.py +18 -18
- volcano_sdk/_generated/api/logs/get_project_log_activity.py +23 -23
- volcano_sdk/_generated/api/logs/search_project_logs.py +23 -23
- volcano_sdk/_generated/api/logs/stream_project_logs.py +23 -23
- volcano_sdk/_generated/api/o_auth_authentication/auth_device_authorize.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_device_token.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_device_verify.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_link_o_auth_provider.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_list_o_auth_providers.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_o_auth_authorize.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_o_auth_callback.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_o_auth_exchange.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_platform_exchange.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/auth_unlink_o_auth_provider.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/call_o_auth_provider_api.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/get_o_auth_provider_token.py +6 -6
- volcano_sdk/_generated/api/o_auth_authentication/refresh_o_auth_provider_token.py +6 -6
- volcano_sdk/_generated/api/o_auth_configuration/create_o_auth_config.py +11 -11
- volcano_sdk/_generated/api/o_auth_configuration/delete_o_auth_config.py +9 -9
- volcano_sdk/_generated/api/o_auth_configuration/get_o_auth_config.py +11 -11
- volcano_sdk/_generated/api/o_auth_configuration/list_available_o_auth_providers.py +11 -11
- volcano_sdk/_generated/api/o_auth_configuration/list_o_auth_configs.py +11 -11
- volcano_sdk/_generated/api/o_auth_configuration/update_o_auth_config.py +11 -11
- volcano_sdk/_generated/api/project_imports/complete_import_connect.py +6 -6
- volcano_sdk/_generated/api/project_imports/delete_import_connection.py +11 -11
- volcano_sdk/_generated/api/project_imports/get_project_import_run.py +11 -11
- volcano_sdk/_generated/api/project_imports/list_import_connections.py +6 -6
- volcano_sdk/_generated/api/project_imports/list_import_sources.py +11 -11
- volcano_sdk/_generated/api/project_imports/preflight_project_import.py +6 -6
- volcano_sdk/_generated/api/project_imports/start_import_connect.py +6 -6
- volcano_sdk/_generated/api/project_imports/start_project_import.py +6 -6
- volcano_sdk/_generated/api/projects/apply_project_config.py +11 -11
- volcano_sdk/_generated/api/projects/cancel_project_source_export.py +11 -11
- volcano_sdk/_generated/api/projects/connect_project_git.py +11 -11
- volcano_sdk/_generated/api/projects/create_project.py +6 -6
- volcano_sdk/_generated/api/projects/delete_project.py +11 -11
- volcano_sdk/_generated/api/projects/delete_project_logo.py +11 -11
- volcano_sdk/_generated/api/projects/disconnect_project_git.py +11 -11
- volcano_sdk/_generated/api/projects/export_project_source.py +11 -11
- volcano_sdk/_generated/api/projects/get_project.py +11 -11
- volcano_sdk/_generated/api/projects/get_project_config.py +11 -11
- volcano_sdk/_generated/api/projects/get_project_git_connection.py +11 -11
- volcano_sdk/_generated/api/projects/get_project_git_deploy_settings.py +11 -11
- volcano_sdk/_generated/api/projects/get_project_health.py +11 -11
- volcano_sdk/_generated/api/projects/get_project_logo.py +11 -11
- volcano_sdk/_generated/api/projects/get_project_source_export.py +11 -11
- volcano_sdk/_generated/api/projects/get_project_usage.py +11 -11
- volcano_sdk/_generated/api/projects/list_deployments.py +11 -11
- volcano_sdk/_generated/api/projects/list_project_deployments.py +11 -11
- volcano_sdk/_generated/api/projects/list_projects.py +6 -6
- volcano_sdk/_generated/api/projects/query_project_metrics.py +11 -11
- volcano_sdk/_generated/api/projects/replace_shared_variables.py +11 -11
- volcano_sdk/_generated/api/projects/set_project_git_production_branch.py +11 -11
- volcano_sdk/_generated/api/projects/summarize_project_deployments.py +11 -11
- volcano_sdk/_generated/api/projects/update_project.py +11 -11
- volcano_sdk/_generated/api/projects/update_project_git_deploy_settings.py +11 -11
- volcano_sdk/_generated/api/projects/upload_project_logo.py +11 -11
- volcano_sdk/_generated/api/realtime/get_realtime_config.py +11 -11
- volcano_sdk/_generated/api/realtime/get_realtime_stats.py +11 -11
- volcano_sdk/_generated/api/realtime/update_realtime_config.py +11 -11
- volcano_sdk/_generated/api/service_keys/create_service_key.py +11 -11
- volcano_sdk/_generated/api/service_keys/delete_service_key.py +12 -12
- volcano_sdk/_generated/api/service_keys/get_service_key.py +16 -16
- volcano_sdk/_generated/api/service_keys/list_service_keys.py +11 -11
- volcano_sdk/_generated/api/service_keys/regenerate_service_key.py +16 -16
- volcano_sdk/_generated/api/storage_admin/get_storage_stats.py +11 -11
- volcano_sdk/_generated/api/storage_admin/list_storage_objects_admin.py +16 -16
- volcano_sdk/_generated/api/storage_buckets/create_storage_bucket.py +11 -11
- volcano_sdk/_generated/api/storage_buckets/delete_storage_bucket.py +9 -9
- volcano_sdk/_generated/api/storage_buckets/get_storage_bucket.py +11 -11
- volcano_sdk/_generated/api/storage_buckets/list_storage_buckets.py +11 -11
- volcano_sdk/_generated/api/storage_buckets/update_storage_bucket.py +11 -11
- volcano_sdk/_generated/api/storage_objects/copy_storage_object.py +6 -6
- volcano_sdk/_generated/api/storage_objects/delete_storage_object.py +6 -6
- volcano_sdk/_generated/api/storage_objects/download_public_file.py +11 -11
- volcano_sdk/_generated/api/storage_objects/download_storage_object.py +6 -6
- volcano_sdk/_generated/api/storage_objects/list_storage_objects.py +6 -6
- volcano_sdk/_generated/api/storage_objects/move_storage_object.py +6 -6
- volcano_sdk/_generated/api/storage_objects/update_storage_object_visibility.py +6 -6
- volcano_sdk/_generated/api/storage_objects/upload_part.py +6 -6
- volcano_sdk/_generated/api/storage_objects/upload_storage_object.py +6 -6
- volcano_sdk/_generated/api/storage_policies/create_storage_policy.py +11 -11
- volcano_sdk/_generated/api/storage_policies/delete_storage_policy.py +12 -12
- volcano_sdk/_generated/api/storage_policies/list_storage_policies.py +11 -11
- volcano_sdk/_generated/api/system/health_check.py +6 -6
- volcano_sdk/_generated/api/variables/create_variable.py +11 -11
- volcano_sdk/_generated/api/variables/delete_variable.py +11 -11
- volcano_sdk/_generated/api/variables/get_variable.py +11 -11
- volcano_sdk/_generated/api/variables/list_variables.py +11 -11
- volcano_sdk/_generated/api/variables/update_variable.py +11 -11
- volcano_sdk/_generated/models/auth_config.py +2 -2
- volcano_sdk/_generated/models/project.py +1 -1
- volcano_sdk/_generated/models/project_config_auth_email.py +1 -1
- volcano_sdk/_generated/models/project_config_auth_managed_pages.py +2 -1
- volcano_sdk/_generated/models/project_config_auth_signup.py +2 -2
- volcano_sdk/_generated/models/project_config_custom_domain.py +1 -1
- volcano_sdk/_generated/models/project_config_email_template.py +2 -2
- volcano_sdk/_generated/models/project_config_email_templates.py +1 -1
- volcano_sdk/_generated/models/project_config_frontend.py +2 -2
- volcano_sdk/_generated/models/project_config_hosted_pages.py +1 -1
- volcano_sdk/_generated/models/project_config_project.py +1 -1
- volcano_sdk/_generated/models/project_plan.py +2 -2
- volcano_sdk/_generated/models/realtime_plan_limits.py +1 -1
- volcano_sdk/_generated/models/update_auth_config_request.py +2 -2
- volcano_sdk/_json_values.py +31 -0
- volcano_sdk/_lock_guard.py +14 -4
- volcano_sdk/_lock_renewer.py +2 -2
- volcano_sdk/_lock_values.py +64 -0
- volcano_sdk/_log_response.py +5 -5
- volcano_sdk/_realtime_callbacks.py +96 -0
- volcano_sdk/_realtime_channel.py +683 -0
- volcano_sdk/_realtime_connection.py +676 -0
- volcano_sdk/_realtime_fetch_worker.py +17 -14
- volcano_sdk/_realtime_messages.py +411 -0
- volcano_sdk/_realtime_presence.py +195 -0
- volcano_sdk/_realtime_transport.py +280 -0
- volcano_sdk/_storage_values.py +428 -0
- volcano_sdk/_transport.py +109 -2070
- volcano_sdk/_transport_auth_account.py +355 -0
- volcano_sdk/_transport_auth_identity.py +376 -0
- volcano_sdk/_transport_base.py +34 -0
- volcano_sdk/_transport_database.py +141 -0
- volcano_sdk/_transport_execution.py +246 -0
- volcano_sdk/_transport_locks.py +121 -0
- volcano_sdk/_transport_response.py +239 -0
- volcano_sdk/_transport_storage.py +258 -0
- volcano_sdk/_transport_types.py +549 -0
- volcano_sdk/auth.py +55 -1261
- volcano_sdk/client.py +53 -87
- volcano_sdk/connection_string.py +13 -18
- volcano_sdk/database.py +37 -47
- volcano_sdk/durable.py +31 -217
- volcano_sdk/durable_authoring.py +90 -693
- volcano_sdk/functions.py +46 -278
- volcano_sdk/locks.py +53 -98
- volcano_sdk/logs.py +19 -12
- volcano_sdk/models.py +9 -26
- volcano_sdk/realtime.py +89 -1717
- volcano_sdk/storage.py +150 -467
- {volcano_sdk_python-0.13.4.dist-info → volcano_sdk_python-0.13.5.dist-info}/METADATA +6 -12
- {volcano_sdk_python-0.13.4.dist-info → volcano_sdk_python-0.13.5.dist-info}/RECORD +315 -279
- {volcano_sdk_python-0.13.4.dist-info → volcano_sdk_python-0.13.5.dist-info}/WHEEL +0 -0
- {volcano_sdk_python-0.13.4.dist-info → volcano_sdk_python-0.13.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Shared authentication facade capabilities."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from ._auth_context import auth_context
|
|
8
|
+
from ._auth_requests import AuthRequests
|
|
9
|
+
from ._auth_values import (
|
|
10
|
+
user_from_payload,
|
|
11
|
+
)
|
|
12
|
+
from .errors import (
|
|
13
|
+
SessionChangedError,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from ._auth_context import AuthContext, AuthContextSource
|
|
18
|
+
from ._session_operations import SessionOperations
|
|
19
|
+
from .models import (
|
|
20
|
+
Session,
|
|
21
|
+
User,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AuthBase:
|
|
26
|
+
"""Share typed client capabilities across authentication operation groups."""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
client: AuthContext | AuthContextSource,
|
|
31
|
+
*,
|
|
32
|
+
_requests: AuthRequests | None = None,
|
|
33
|
+
) -> None:
|
|
34
|
+
"""Create an authentication facade backed by a client."""
|
|
35
|
+
self._client: AuthContext = auth_context(client)
|
|
36
|
+
self._requests: AuthRequests = (
|
|
37
|
+
AuthRequests(self._client) if _requests is None else _requests
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def _update_current_user(
|
|
41
|
+
self, payload: object, binding: tuple[int, SessionOperations, Session | None]
|
|
42
|
+
) -> User:
|
|
43
|
+
generation = self._requests.owned_session(binding)[0]
|
|
44
|
+
user, snapshot = user_from_payload(payload)
|
|
45
|
+
if not self._client.update_session_user_if_current(snapshot, generation):
|
|
46
|
+
raise SessionChangedError
|
|
47
|
+
return user
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Typed client capabilities for authentication."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import TYPE_CHECKING, Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from collections.abc import Callable, Mapping
|
|
10
|
+
|
|
11
|
+
from ._session_operations import SessionOperations
|
|
12
|
+
from ._transport import (
|
|
13
|
+
Transport,
|
|
14
|
+
)
|
|
15
|
+
from .models import (
|
|
16
|
+
AuthChangeEvent,
|
|
17
|
+
AuthStateCallback,
|
|
18
|
+
AuthSubscription,
|
|
19
|
+
JSONValue,
|
|
20
|
+
Session,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SetSession(Protocol):
|
|
25
|
+
def __call__(
|
|
26
|
+
self,
|
|
27
|
+
session: Session,
|
|
28
|
+
*,
|
|
29
|
+
event: AuthChangeEvent | None,
|
|
30
|
+
) -> None: ...
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class SetSessionIfCurrent(Protocol):
|
|
34
|
+
def __call__(
|
|
35
|
+
self,
|
|
36
|
+
session: Session,
|
|
37
|
+
generation: int,
|
|
38
|
+
*,
|
|
39
|
+
event: AuthChangeEvent,
|
|
40
|
+
notifications: list[Callable[[], None]] | None = None,
|
|
41
|
+
) -> bool: ...
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ClearSessionIfCurrent(Protocol):
|
|
45
|
+
def __call__(
|
|
46
|
+
self,
|
|
47
|
+
generation: int,
|
|
48
|
+
*,
|
|
49
|
+
lineage: SessionOperations | None = None,
|
|
50
|
+
event: AuthChangeEvent,
|
|
51
|
+
notifications: list[Callable[[], None]] | None = None,
|
|
52
|
+
) -> bool: ...
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(frozen=True, slots=True)
|
|
56
|
+
class AuthContext:
|
|
57
|
+
"""Typed client operations required by the authentication facade."""
|
|
58
|
+
|
|
59
|
+
transport: Callable[[], Transport]
|
|
60
|
+
current_session: Callable[[], Session | None]
|
|
61
|
+
anon_token: Callable[[], str]
|
|
62
|
+
api_base_url: Callable[[], str]
|
|
63
|
+
set_session: SetSession
|
|
64
|
+
capture_session: Callable[[], tuple[int, Session | None]]
|
|
65
|
+
capture_session_binding: Callable[[], tuple[int, SessionOperations, Session | None]]
|
|
66
|
+
update_session_user_if_current: Callable[[Mapping[str, JSONValue], int], bool]
|
|
67
|
+
set_session_if_current: SetSessionIfCurrent
|
|
68
|
+
clear_session_if_current: ClearSessionIfCurrent
|
|
69
|
+
subscribe_auth_state_change: Callable[[AuthStateCallback], AuthSubscription]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@runtime_checkable
|
|
73
|
+
class AuthContextSource(Protocol):
|
|
74
|
+
"""The private authentication context factory retained by VolcanoClient."""
|
|
75
|
+
|
|
76
|
+
def _auth_context(self) -> AuthContext: ...
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def auth_context(client: AuthContextSource | AuthContext) -> AuthContext:
|
|
80
|
+
"""Preserve Auth(client) while keeping its internal callbacks private.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
The client's authentication capabilities or the supplied context.
|
|
84
|
+
|
|
85
|
+
"""
|
|
86
|
+
if isinstance(client, AuthContextSource):
|
|
87
|
+
return client._auth_context() # ruff: ignore[private-member-access] # pyright: ignore[reportPrivateUsage]
|
|
88
|
+
return client
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"""Email identity, confirmation, and password recovery operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from ._auth_base import AuthBase
|
|
8
|
+
from ._auth_values import (
|
|
9
|
+
INVALID_AUTH_TRANSPORT,
|
|
10
|
+
NO_ACTIVE_SESSION,
|
|
11
|
+
email_change_result_from_payload,
|
|
12
|
+
)
|
|
13
|
+
from ._transport import (
|
|
14
|
+
AuthCancelEmailChangeTransport,
|
|
15
|
+
AuthConfirmEmailChangeTransport,
|
|
16
|
+
AuthConfirmEmailTransport,
|
|
17
|
+
AuthForgotPasswordTransport,
|
|
18
|
+
AuthRequestEmailChangeTransport,
|
|
19
|
+
AuthResendConfirmationTransport,
|
|
20
|
+
AuthResetPasswordTransport,
|
|
21
|
+
invoke,
|
|
22
|
+
response_payload,
|
|
23
|
+
)
|
|
24
|
+
from .errors import (
|
|
25
|
+
AuthenticationError,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from .models import (
|
|
30
|
+
EmailChangeResult,
|
|
31
|
+
User,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class EmailAuth(AuthBase):
|
|
36
|
+
"""Email identity, confirmation, and password recovery operations."""
|
|
37
|
+
|
|
38
|
+
def reset_password_for_email(self, *, email: str) -> None:
|
|
39
|
+
"""Request a reset email without revealing whether the account exists.
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
TypeError: The transport does not support this authentication operation.
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
transport = self._client.transport()
|
|
46
|
+
if not isinstance(transport, AuthForgotPasswordTransport):
|
|
47
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
48
|
+
response = invoke(
|
|
49
|
+
transport.auth_forgot_password,
|
|
50
|
+
authorization=self._client.anon_token(),
|
|
51
|
+
email=email,
|
|
52
|
+
)
|
|
53
|
+
_ = response_payload(response, 200)
|
|
54
|
+
|
|
55
|
+
def request_email_change(self, *, new_email: str) -> EmailChangeResult:
|
|
56
|
+
"""Request a confirmation email without changing the current session.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
The server acknowledgement of the requested email change.
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
AuthenticationError: There is no active session.
|
|
63
|
+
TypeError: The transport does not support this authentication operation.
|
|
64
|
+
|
|
65
|
+
"""
|
|
66
|
+
binding = self._client.capture_session_binding()
|
|
67
|
+
if binding[2] is None:
|
|
68
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
69
|
+
transport = self._client.transport()
|
|
70
|
+
if not isinstance(transport, AuthRequestEmailChangeTransport):
|
|
71
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
72
|
+
response = self._requests.request(
|
|
73
|
+
lambda access_token: invoke(
|
|
74
|
+
transport.auth_request_email_change,
|
|
75
|
+
authorization=access_token,
|
|
76
|
+
new_email=new_email,
|
|
77
|
+
),
|
|
78
|
+
binding=binding,
|
|
79
|
+
)
|
|
80
|
+
result = email_change_result_from_payload(response_payload(response, 200))
|
|
81
|
+
_ = self._requests.owned_session(binding)
|
|
82
|
+
return result
|
|
83
|
+
|
|
84
|
+
def cancel_email_change(self) -> None:
|
|
85
|
+
"""Cancel a pending email change without changing the current session.
|
|
86
|
+
|
|
87
|
+
Raises:
|
|
88
|
+
AuthenticationError: There is no active session.
|
|
89
|
+
TypeError: The transport does not support this authentication operation.
|
|
90
|
+
|
|
91
|
+
"""
|
|
92
|
+
binding = self._client.capture_session_binding()
|
|
93
|
+
if binding[2] is None:
|
|
94
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
95
|
+
transport = self._client.transport()
|
|
96
|
+
if not isinstance(transport, AuthCancelEmailChangeTransport):
|
|
97
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
98
|
+
response = self._requests.request(
|
|
99
|
+
lambda access_token: invoke(
|
|
100
|
+
transport.auth_cancel_email_change,
|
|
101
|
+
authorization=access_token,
|
|
102
|
+
),
|
|
103
|
+
binding=binding,
|
|
104
|
+
)
|
|
105
|
+
_ = response_payload(response, 200)
|
|
106
|
+
_ = self._requests.owned_session(binding)
|
|
107
|
+
|
|
108
|
+
def confirm_email_change(self, *, token: str) -> User:
|
|
109
|
+
"""Confirm a pending email change and return the updated user.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
The updated profile after confirming the new email.
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
AuthenticationError: There is no active session.
|
|
116
|
+
TypeError: The transport does not support this authentication operation.
|
|
117
|
+
|
|
118
|
+
"""
|
|
119
|
+
binding = self._client.capture_session_binding()
|
|
120
|
+
if binding[2] is None:
|
|
121
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
122
|
+
transport = self._client.transport()
|
|
123
|
+
if not isinstance(transport, AuthConfirmEmailChangeTransport):
|
|
124
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
125
|
+
response = self._requests.request(
|
|
126
|
+
lambda access_token: invoke(
|
|
127
|
+
transport.auth_confirm_email_change,
|
|
128
|
+
authorization=access_token,
|
|
129
|
+
token=token,
|
|
130
|
+
),
|
|
131
|
+
binding=binding,
|
|
132
|
+
)
|
|
133
|
+
return self._update_current_user(response_payload(response, 200), binding)
|
|
134
|
+
|
|
135
|
+
def confirm_email(self, *, token: str) -> None:
|
|
136
|
+
"""Confirm an email with its token without changing local state.
|
|
137
|
+
|
|
138
|
+
Raises:
|
|
139
|
+
TypeError: The transport does not support this authentication operation.
|
|
140
|
+
|
|
141
|
+
"""
|
|
142
|
+
transport = self._client.transport()
|
|
143
|
+
if not isinstance(transport, AuthConfirmEmailTransport):
|
|
144
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
145
|
+
response = invoke(
|
|
146
|
+
transport.auth_confirm_email,
|
|
147
|
+
authorization=self._client.anon_token(),
|
|
148
|
+
token=token,
|
|
149
|
+
)
|
|
150
|
+
_ = response_payload(response, 200)
|
|
151
|
+
|
|
152
|
+
def resend_confirmation(self, *, email: str) -> None:
|
|
153
|
+
"""Request a generic confirmation resend without changing local state.
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
TypeError: The transport does not support this authentication operation.
|
|
157
|
+
|
|
158
|
+
"""
|
|
159
|
+
transport = self._client.transport()
|
|
160
|
+
if not isinstance(transport, AuthResendConfirmationTransport):
|
|
161
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
162
|
+
response = invoke(
|
|
163
|
+
transport.auth_resend_confirmation,
|
|
164
|
+
authorization=self._client.anon_token(),
|
|
165
|
+
email=email,
|
|
166
|
+
)
|
|
167
|
+
_ = response_payload(response, 200)
|
|
168
|
+
|
|
169
|
+
def reset_password(self, *, token: str, new_password: str) -> None:
|
|
170
|
+
"""Set a new password with a recovery token without changing local state.
|
|
171
|
+
|
|
172
|
+
Raises:
|
|
173
|
+
TypeError: The transport does not support this authentication operation.
|
|
174
|
+
|
|
175
|
+
"""
|
|
176
|
+
transport = self._client.transport()
|
|
177
|
+
if not isinstance(transport, AuthResetPasswordTransport):
|
|
178
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
179
|
+
response = invoke(
|
|
180
|
+
transport.auth_reset_password,
|
|
181
|
+
authorization=self._client.anon_token(),
|
|
182
|
+
token=token,
|
|
183
|
+
new_password=new_password,
|
|
184
|
+
)
|
|
185
|
+
_ = response_payload(response, 200)
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"""Hosted authentication and OAuth provider operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from copy import deepcopy
|
|
6
|
+
from typing import TYPE_CHECKING, Literal
|
|
7
|
+
from urllib.parse import quote, urlencode
|
|
8
|
+
|
|
9
|
+
from ._auth_base import AuthBase
|
|
10
|
+
from ._auth_values import (
|
|
11
|
+
HOSTED_AUTH_ACTIONS,
|
|
12
|
+
INVALID_AUTH_TRANSPORT,
|
|
13
|
+
NO_ACTIVE_SESSION,
|
|
14
|
+
PATH_SEGMENT_SAFE,
|
|
15
|
+
UNSUPPORTED_HOSTED_AUTH_ACTION,
|
|
16
|
+
copy_complete_session,
|
|
17
|
+
hosted_auth_parameter,
|
|
18
|
+
linked_oauth_providers_from_payload,
|
|
19
|
+
oauth_api_data_from_payload,
|
|
20
|
+
oauth_api_method,
|
|
21
|
+
oauth_link_from_payload,
|
|
22
|
+
oauth_parameter,
|
|
23
|
+
oauth_provider_name,
|
|
24
|
+
oauth_provider_token_status_from_payload,
|
|
25
|
+
oauth_state,
|
|
26
|
+
session_from_payload,
|
|
27
|
+
validate_hosted_auth_callback_state,
|
|
28
|
+
validate_oauth_callback_state,
|
|
29
|
+
)
|
|
30
|
+
from ._transport import (
|
|
31
|
+
AuthCallOAuthAPITransport,
|
|
32
|
+
AuthGetOAuthProviderTokenTransport,
|
|
33
|
+
AuthLinkOAuthProviderTransport,
|
|
34
|
+
AuthListOAuthProvidersTransport,
|
|
35
|
+
AuthOAuthAuthorizationURLTransport,
|
|
36
|
+
AuthOAuthExchangeTransport,
|
|
37
|
+
AuthRefreshOAuthProviderTokenTransport,
|
|
38
|
+
AuthUnlinkOAuthProviderTransport,
|
|
39
|
+
invoke,
|
|
40
|
+
response_payload,
|
|
41
|
+
)
|
|
42
|
+
from .errors import (
|
|
43
|
+
AuthenticationError,
|
|
44
|
+
SessionChangedError,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if TYPE_CHECKING:
|
|
48
|
+
from collections.abc import Mapping
|
|
49
|
+
|
|
50
|
+
from .models import (
|
|
51
|
+
JSONValue,
|
|
52
|
+
LinkedOAuthProvider,
|
|
53
|
+
OAuthProviderName,
|
|
54
|
+
OAuthProviderTokenStatus,
|
|
55
|
+
Session,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class OAuthAuth(AuthBase):
|
|
60
|
+
"""Hosted authentication and OAuth provider operations."""
|
|
61
|
+
|
|
62
|
+
def list_linked_oauth_providers(self) -> tuple[LinkedOAuthProvider, ...]:
|
|
63
|
+
"""List OAuth providers linked to the current account.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
An immutable tuple of linked provider records.
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
AuthenticationError: There is no active session.
|
|
70
|
+
TypeError: The transport does not support this authentication operation.
|
|
71
|
+
|
|
72
|
+
"""
|
|
73
|
+
binding = self._client.capture_session_binding()
|
|
74
|
+
if binding[2] is None:
|
|
75
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
76
|
+
transport = self._client.transport()
|
|
77
|
+
if not isinstance(transport, AuthListOAuthProvidersTransport):
|
|
78
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
79
|
+
response = self._requests.request(
|
|
80
|
+
lambda access_token: invoke(
|
|
81
|
+
transport.auth_list_oauth_providers,
|
|
82
|
+
authorization=access_token,
|
|
83
|
+
),
|
|
84
|
+
binding=binding,
|
|
85
|
+
)
|
|
86
|
+
result = linked_oauth_providers_from_payload(response_payload(response, 200))
|
|
87
|
+
_ = self._requests.owned_session(binding)
|
|
88
|
+
return result
|
|
89
|
+
|
|
90
|
+
def get_hosted_auth_url(
|
|
91
|
+
self,
|
|
92
|
+
*,
|
|
93
|
+
project_id: str,
|
|
94
|
+
state: str,
|
|
95
|
+
action: Literal["login", "signup", "forgot-password"] = "login",
|
|
96
|
+
) -> str:
|
|
97
|
+
"""Build a managed hosted-auth URL without navigating or persisting state.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
The hosted-auth URL containing the action and caller state.
|
|
101
|
+
|
|
102
|
+
Raises:
|
|
103
|
+
ValueError: A parameter is empty or the action is unsupported.
|
|
104
|
+
|
|
105
|
+
"""
|
|
106
|
+
project = hosted_auth_parameter(project_id).strip()
|
|
107
|
+
auth_state = hosted_auth_parameter(state)
|
|
108
|
+
if action not in HOSTED_AUTH_ACTIONS:
|
|
109
|
+
raise ValueError(UNSUPPORTED_HOSTED_AUTH_ACTION)
|
|
110
|
+
query = urlencode(
|
|
111
|
+
{
|
|
112
|
+
"action": action,
|
|
113
|
+
"anon_key": self._client.anon_token(),
|
|
114
|
+
"state": auth_state,
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
project_path = quote(project, safe=PATH_SEGMENT_SAFE)
|
|
118
|
+
return (
|
|
119
|
+
f"{self._client.api_base_url()}/projects/{project_path}/auth/hosted?{query}"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def adopt_hosted_auth_session(
|
|
123
|
+
self,
|
|
124
|
+
session: Session,
|
|
125
|
+
*,
|
|
126
|
+
state: str,
|
|
127
|
+
expected_state: str,
|
|
128
|
+
) -> Session:
|
|
129
|
+
"""Validate returned hosted-auth state before storing its session.
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
The copied session stored after validating callback state.
|
|
133
|
+
|
|
134
|
+
"""
|
|
135
|
+
validate_hosted_auth_callback_state(state, expected_state)
|
|
136
|
+
owned = copy_complete_session(session)
|
|
137
|
+
self._client.set_session(owned, event="SIGNED_IN")
|
|
138
|
+
return owned
|
|
139
|
+
|
|
140
|
+
def sign_in_with_oauth(
|
|
141
|
+
self,
|
|
142
|
+
*,
|
|
143
|
+
provider: OAuthProviderName,
|
|
144
|
+
redirect_to: str,
|
|
145
|
+
state: str,
|
|
146
|
+
) -> str:
|
|
147
|
+
"""Return the URL that starts an OAuth sign-in flow.
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
The provider authorization URL containing the caller state.
|
|
151
|
+
|
|
152
|
+
Raises:
|
|
153
|
+
TypeError: The transport cannot start an OAuth sign-in flow.
|
|
154
|
+
|
|
155
|
+
"""
|
|
156
|
+
provider_name = oauth_provider_name(provider)
|
|
157
|
+
transport = self._client.transport()
|
|
158
|
+
if not isinstance(transport, AuthOAuthAuthorizationURLTransport):
|
|
159
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
160
|
+
return transport.auth_oauth_authorization_url(
|
|
161
|
+
anon_key=self._client.anon_token(),
|
|
162
|
+
provider=provider_name,
|
|
163
|
+
redirect_url=oauth_parameter(redirect_to),
|
|
164
|
+
client_state=oauth_state(state),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def exchange_oauth_code(
|
|
168
|
+
self,
|
|
169
|
+
*,
|
|
170
|
+
code: str,
|
|
171
|
+
redirect_to: str,
|
|
172
|
+
state: str,
|
|
173
|
+
expected_state: str,
|
|
174
|
+
) -> Session:
|
|
175
|
+
"""Validate callback state, exchange a code, and store the session.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
The exchanged session stored by the client.
|
|
179
|
+
|
|
180
|
+
Raises:
|
|
181
|
+
SessionChangedError: The local session changed during the exchange.
|
|
182
|
+
TypeError: The transport does not support this authentication operation.
|
|
183
|
+
|
|
184
|
+
"""
|
|
185
|
+
validate_oauth_callback_state(state, expected_state)
|
|
186
|
+
generation, _ = self._client.capture_session()
|
|
187
|
+
transport = self._client.transport()
|
|
188
|
+
if not isinstance(transport, AuthOAuthExchangeTransport):
|
|
189
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
190
|
+
response = invoke(
|
|
191
|
+
transport.auth_oauth_exchange,
|
|
192
|
+
authorization=self._client.anon_token(),
|
|
193
|
+
code=oauth_parameter(code),
|
|
194
|
+
redirect_url=oauth_parameter(redirect_to),
|
|
195
|
+
)
|
|
196
|
+
session = session_from_payload(response_payload(response, 200))
|
|
197
|
+
if not self._client.set_session_if_current(
|
|
198
|
+
session, generation, event="SIGNED_IN"
|
|
199
|
+
):
|
|
200
|
+
raise SessionChangedError
|
|
201
|
+
return session
|
|
202
|
+
|
|
203
|
+
def link_oauth_provider(self, *, provider: OAuthProviderName) -> str:
|
|
204
|
+
"""Return the authorization URL for linking an OAuth provider.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
The authorization URL for linking the requested provider.
|
|
208
|
+
|
|
209
|
+
Raises:
|
|
210
|
+
AuthenticationError: There is no active session.
|
|
211
|
+
TypeError: The transport does not support this authentication operation.
|
|
212
|
+
|
|
213
|
+
"""
|
|
214
|
+
provider_name = oauth_provider_name(provider)
|
|
215
|
+
binding = self._client.capture_session_binding()
|
|
216
|
+
if binding[2] is None:
|
|
217
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
218
|
+
transport = self._client.transport()
|
|
219
|
+
if not isinstance(transport, AuthLinkOAuthProviderTransport):
|
|
220
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
221
|
+
response = self._requests.request(
|
|
222
|
+
lambda access_token: invoke(
|
|
223
|
+
transport.auth_link_oauth_provider,
|
|
224
|
+
authorization=access_token,
|
|
225
|
+
provider=provider_name,
|
|
226
|
+
),
|
|
227
|
+
binding=binding,
|
|
228
|
+
)
|
|
229
|
+
result = oauth_link_from_payload(response_payload(response, 200))
|
|
230
|
+
_ = self._requests.owned_session(binding)
|
|
231
|
+
return result
|
|
232
|
+
|
|
233
|
+
def unlink_oauth_provider(self, *, provider: OAuthProviderName) -> None:
|
|
234
|
+
"""Unlink an OAuth provider from the current account.
|
|
235
|
+
|
|
236
|
+
Raises:
|
|
237
|
+
AuthenticationError: There is no active session.
|
|
238
|
+
TypeError: The transport cannot unlink an OAuth provider.
|
|
239
|
+
|
|
240
|
+
"""
|
|
241
|
+
provider_name = oauth_provider_name(provider)
|
|
242
|
+
binding = self._client.capture_session_binding()
|
|
243
|
+
if binding[2] is None:
|
|
244
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
245
|
+
transport = self._client.transport()
|
|
246
|
+
if not isinstance(transport, AuthUnlinkOAuthProviderTransport):
|
|
247
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
248
|
+
response = self._requests.request(
|
|
249
|
+
lambda access_token: invoke(
|
|
250
|
+
transport.auth_unlink_oauth_provider,
|
|
251
|
+
authorization=access_token,
|
|
252
|
+
provider=provider_name,
|
|
253
|
+
),
|
|
254
|
+
binding=binding,
|
|
255
|
+
)
|
|
256
|
+
_ = response_payload(response, 204)
|
|
257
|
+
_ = self._requests.owned_session(binding)
|
|
258
|
+
|
|
259
|
+
def get_oauth_provider_token(
|
|
260
|
+
self,
|
|
261
|
+
*,
|
|
262
|
+
provider: OAuthProviderName,
|
|
263
|
+
) -> OAuthProviderTokenStatus:
|
|
264
|
+
"""Return validity metadata for a server-held OAuth provider token.
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Validity metadata without exposing the provider token.
|
|
268
|
+
|
|
269
|
+
Raises:
|
|
270
|
+
AuthenticationError: There is no active session.
|
|
271
|
+
TypeError: The transport cannot read OAuth provider token status.
|
|
272
|
+
|
|
273
|
+
"""
|
|
274
|
+
provider_name = oauth_provider_name(provider)
|
|
275
|
+
binding = self._client.capture_session_binding()
|
|
276
|
+
if binding[2] is None:
|
|
277
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
278
|
+
transport = self._client.transport()
|
|
279
|
+
if not isinstance(transport, AuthGetOAuthProviderTokenTransport):
|
|
280
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
281
|
+
response = self._requests.request(
|
|
282
|
+
lambda access_token: invoke(
|
|
283
|
+
transport.auth_get_oauth_provider_token,
|
|
284
|
+
authorization=access_token,
|
|
285
|
+
provider=provider_name,
|
|
286
|
+
),
|
|
287
|
+
binding=binding,
|
|
288
|
+
)
|
|
289
|
+
result = oauth_provider_token_status_from_payload(
|
|
290
|
+
response_payload(response, 200)
|
|
291
|
+
)
|
|
292
|
+
_ = self._requests.owned_session(binding)
|
|
293
|
+
return result
|
|
294
|
+
|
|
295
|
+
def refresh_oauth_provider_token(
|
|
296
|
+
self,
|
|
297
|
+
*,
|
|
298
|
+
provider: OAuthProviderName,
|
|
299
|
+
) -> OAuthProviderTokenStatus:
|
|
300
|
+
"""Refresh a server-held OAuth provider token and return its status.
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
Validity metadata for the refreshed provider token.
|
|
304
|
+
|
|
305
|
+
Raises:
|
|
306
|
+
AuthenticationError: There is no active session.
|
|
307
|
+
TypeError: The transport cannot refresh an OAuth provider token.
|
|
308
|
+
|
|
309
|
+
"""
|
|
310
|
+
provider_name = oauth_provider_name(provider)
|
|
311
|
+
binding = self._client.capture_session_binding()
|
|
312
|
+
if binding[2] is None:
|
|
313
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
314
|
+
transport = self._client.transport()
|
|
315
|
+
if not isinstance(transport, AuthRefreshOAuthProviderTokenTransport):
|
|
316
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
317
|
+
response = self._requests.request(
|
|
318
|
+
lambda access_token: invoke(
|
|
319
|
+
transport.auth_refresh_oauth_provider_token,
|
|
320
|
+
authorization=access_token,
|
|
321
|
+
provider=provider_name,
|
|
322
|
+
),
|
|
323
|
+
binding=binding,
|
|
324
|
+
)
|
|
325
|
+
result = oauth_provider_token_status_from_payload(
|
|
326
|
+
response_payload(response, 200)
|
|
327
|
+
)
|
|
328
|
+
_ = self._requests.owned_session(binding)
|
|
329
|
+
return result
|
|
330
|
+
|
|
331
|
+
def call_oauth_api(
|
|
332
|
+
self,
|
|
333
|
+
*,
|
|
334
|
+
provider: OAuthProviderName,
|
|
335
|
+
endpoint: str,
|
|
336
|
+
method: Literal["GET", "POST"] = "GET",
|
|
337
|
+
body: Mapping[str, JSONValue] | None = None,
|
|
338
|
+
) -> JSONValue:
|
|
339
|
+
"""Call a provider API through Volcano's fixed-host server proxy.
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
The provider response as an immutable JSON value.
|
|
343
|
+
|
|
344
|
+
Raises:
|
|
345
|
+
AuthenticationError: There is no active session.
|
|
346
|
+
TypeError: The transport does not support this authentication operation.
|
|
347
|
+
|
|
348
|
+
"""
|
|
349
|
+
provider_name = oauth_provider_name(provider)
|
|
350
|
+
request_method = oauth_api_method(method)
|
|
351
|
+
binding = self._client.capture_session_binding()
|
|
352
|
+
if binding[2] is None:
|
|
353
|
+
raise AuthenticationError(NO_ACTIVE_SESSION)
|
|
354
|
+
transport = self._client.transport()
|
|
355
|
+
if not isinstance(transport, AuthCallOAuthAPITransport):
|
|
356
|
+
raise TypeError(INVALID_AUTH_TRANSPORT)
|
|
357
|
+
request_body = deepcopy(dict(body)) if body is not None else None
|
|
358
|
+
response = self._requests.request(
|
|
359
|
+
lambda access_token: invoke(
|
|
360
|
+
transport.auth_call_oauth_api,
|
|
361
|
+
authorization=access_token,
|
|
362
|
+
provider=provider_name,
|
|
363
|
+
endpoint=endpoint,
|
|
364
|
+
method=request_method,
|
|
365
|
+
body=request_body,
|
|
366
|
+
),
|
|
367
|
+
binding=binding,
|
|
368
|
+
)
|
|
369
|
+
result = oauth_api_data_from_payload(response_payload(response, 200))
|
|
370
|
+
_ = self._requests.owned_session(binding)
|
|
371
|
+
return result
|