diff --git a/sdk-endpoints.txt b/sdk-endpoints.txt index d131bd0..c5c92a9 100644 --- a/sdk-endpoints.txt +++ b/sdk-endpoints.txt @@ -99,6 +99,8 @@ GET /v1/settings # not yet wrapped PATCH /v1/settings # not yet wrapped GET /v1/settings/mail # not yet wrapped POST /v1/settings/mail/test # not yet wrapped +GET /v1/settings/maintenance-mode # not yet wrapped +PATCH /v1/settings/maintenance-mode # not yet wrapped # Model discovery / metadata GET /v1/models/discoverable # not yet wrapped GET /v1/models/metadata # not yet wrapped @@ -126,6 +128,17 @@ POST /v1/auth/verify-email # dashboard-only POST /v1/auth/resend-verification # dashboard-only POST /v1/auth/password/reset # dashboard-only POST /v1/auth/password/reset/confirm # dashboard-only +# Passkeys (otari#652): both ceremonies need a WebAuthn authenticator, which is +# a browser API. An SDK cannot produce an attestation or an assertion, so there +# is nothing here for one to wrap, including the credential list: it exists to +# render the account page's passkey rows. +POST /v1/auth/webauthn/register/options # dashboard-only +POST /v1/auth/webauthn/register # dashboard-only +POST /v1/auth/webauthn/authenticate/options # dashboard-only +POST /v1/auth/webauthn/authenticate # dashboard-only +GET /v1/auth/webauthn/credentials # dashboard-only +PATCH /v1/auth/webauthn/credentials/{credential_id} # dashboard-only +DELETE /v1/auth/webauthn/credentials/{credential_id} # dashboard-only # OTLP ingest: OpenTelemetry collector receivers, not an SDK surface. POST /v1/logs # otel ingest POST /v1/traces # otel ingest @@ -229,6 +242,14 @@ POST /v1/workspaces/{workspace_id}/activation/dismiss # dashboard-only GET /v1/workspaces/{workspace_id}/code-execution-policy # dashboard-only PUT /v1/workspaces/{workspace_id}/code-execution-policy # dashboard-only DELETE /v1/workspaces/{workspace_id}/code-execution-policy # dashboard-only +# The workspace's web-search configuration (otari#656) is the same shape of +# surface for the same reason: whoever administers the workspace decides whether +# it may search and how far, not the key-holder searching inside it. An SDK +# caller sees its effect on `otari_web_search` and on `POST /v1/search` (a 403, a +# lower result ceiling, a domain filter), never the row. +GET /v1/workspaces/{workspace_id}/web-search # dashboard-only +PUT /v1/workspaces/{workspace_id}/web-search # dashboard-only +DELETE /v1/workspaces/{workspace_id}/web-search # dashboard-only # Organization-scoped provider keys (otari-ai#1748, otari#643): the same # tenancy-admin surface as the organization/workspace rows just above, and # excluded for the same reason. An SDK caller acts inside one workspace with a diff --git a/src/otari/_client/__init__.py b/src/otari/_client/__init__.py index bd3ef9a..b929280 100644 --- a/src/otari/_client/__init__.py +++ b/src/otari/_client/__init__.py @@ -56,6 +56,7 @@ "WorkspaceActivationApi", "WorkspaceCodeExecutionPolicyApi", "WorkspaceMemberBudgetPoliciesApi", + "WorkspaceWebSearchApi", "WorkspacesApi", "ApiResponse", "ApiClient", @@ -94,6 +95,7 @@ "ApiKeyId", "AppliedEditsInner", "AudioSpeechRequest", + "AuthenticatePasskeyRequest", "BatchRequestItem", "BillingMeters", "BudgetResetLogResponse", @@ -327,6 +329,7 @@ "MSGImageURL", "MSGInputAudio", "MailSettings", + "MaintenanceMode", "ManagedTool", "McpServerConfig", "Message", @@ -352,6 +355,7 @@ "OrganizationModelPricingUpdate", "OrganizationModelPricingsPublic", "OrganizationPublic", + "PasskeySessionResponse", "PasswordResponse", "PolicyRequest", "PolicyResponse", @@ -376,6 +380,7 @@ "RecordedPool", "ReencryptProviderCredentialsResponse", "ReencryptSearchToolsResponse", + "RegisterPasskeyRequest", "RequestPasswordResetRequest", "RequestPasswordResetResponse", "RerankRequest", @@ -424,6 +429,7 @@ "Units1", "UpdateBudgetRequest", "UpdateKeyRequest", + "UpdateMaintenanceModeRequest", "UpdateScopedBudgetRequest", "UpdateSearchToolRequest", "UpdateSettingsRequest", @@ -454,6 +460,9 @@ "Value1", "VerifyEmailRequest", "VerifyEmailResponse", + "WebAuthnCredentialPublic", + "WebAuthnCredentialUpdate", + "WebAuthnCredentialsPublic", "WorkspaceActivationPublic", "WorkspaceAssignmentRequest", "WorkspaceCodeExecutionPolicyPublic", @@ -476,6 +485,8 @@ "WorkspaceProviderModelRestrictionsPublic", "WorkspacePublic", "WorkspaceUpdate", + "WorkspaceWebSearchConfigPublic", + "WorkspaceWebSearchConfigUpdate", "WorkspacesPublic", ] @@ -518,6 +529,7 @@ from otari._client.api.workspace_activation_api import WorkspaceActivationApi as WorkspaceActivationApi from otari._client.api.workspace_code_execution_policy_api import WorkspaceCodeExecutionPolicyApi as WorkspaceCodeExecutionPolicyApi from otari._client.api.workspace_member_budget_policies_api import WorkspaceMemberBudgetPoliciesApi as WorkspaceMemberBudgetPoliciesApi +from otari._client.api.workspace_web_search_api import WorkspaceWebSearchApi as WorkspaceWebSearchApi from otari._client.api.workspaces_api import WorkspacesApi as WorkspacesApi # import ApiClient @@ -560,6 +572,7 @@ from otari._client.models.api_key_id import ApiKeyId as ApiKeyId from otari._client.models.applied_edits_inner import AppliedEditsInner as AppliedEditsInner from otari._client.models.audio_speech_request import AudioSpeechRequest as AudioSpeechRequest +from otari._client.models.authenticate_passkey_request import AuthenticatePasskeyRequest as AuthenticatePasskeyRequest from otari._client.models.batch_request_item import BatchRequestItem as BatchRequestItem from otari._client.models.billing_meters import BillingMeters as BillingMeters from otari._client.models.budget_reset_log_response import BudgetResetLogResponse as BudgetResetLogResponse @@ -793,6 +806,7 @@ from otari._client.models.msg_image_url import MSGImageURL as MSGImageURL from otari._client.models.msg_input_audio import MSGInputAudio as MSGInputAudio from otari._client.models.mail_settings import MailSettings as MailSettings +from otari._client.models.maintenance_mode import MaintenanceMode as MaintenanceMode from otari._client.models.managed_tool import ManagedTool as ManagedTool from otari._client.models.mcp_server_config import McpServerConfig as McpServerConfig from otari._client.models.message import Message as Message @@ -818,6 +832,7 @@ from otari._client.models.organization_model_pricing_update import OrganizationModelPricingUpdate as OrganizationModelPricingUpdate from otari._client.models.organization_model_pricings_public import OrganizationModelPricingsPublic as OrganizationModelPricingsPublic from otari._client.models.organization_public import OrganizationPublic as OrganizationPublic +from otari._client.models.passkey_session_response import PasskeySessionResponse as PasskeySessionResponse from otari._client.models.password_response import PasswordResponse as PasswordResponse from otari._client.models.policy_request import PolicyRequest as PolicyRequest from otari._client.models.policy_response import PolicyResponse as PolicyResponse @@ -842,6 +857,7 @@ from otari._client.models.recorded_pool import RecordedPool as RecordedPool from otari._client.models.reencrypt_provider_credentials_response import ReencryptProviderCredentialsResponse as ReencryptProviderCredentialsResponse from otari._client.models.reencrypt_search_tools_response import ReencryptSearchToolsResponse as ReencryptSearchToolsResponse +from otari._client.models.register_passkey_request import RegisterPasskeyRequest as RegisterPasskeyRequest from otari._client.models.request_password_reset_request import RequestPasswordResetRequest as RequestPasswordResetRequest from otari._client.models.request_password_reset_response import RequestPasswordResetResponse as RequestPasswordResetResponse from otari._client.models.rerank_request import RerankRequest as RerankRequest @@ -890,6 +906,7 @@ from otari._client.models.units1 import Units1 as Units1 from otari._client.models.update_budget_request import UpdateBudgetRequest as UpdateBudgetRequest from otari._client.models.update_key_request import UpdateKeyRequest as UpdateKeyRequest +from otari._client.models.update_maintenance_mode_request import UpdateMaintenanceModeRequest as UpdateMaintenanceModeRequest from otari._client.models.update_scoped_budget_request import UpdateScopedBudgetRequest as UpdateScopedBudgetRequest from otari._client.models.update_search_tool_request import UpdateSearchToolRequest as UpdateSearchToolRequest from otari._client.models.update_settings_request import UpdateSettingsRequest as UpdateSettingsRequest @@ -920,6 +937,9 @@ from otari._client.models.value1 import Value1 as Value1 from otari._client.models.verify_email_request import VerifyEmailRequest as VerifyEmailRequest from otari._client.models.verify_email_response import VerifyEmailResponse as VerifyEmailResponse +from otari._client.models.web_authn_credential_public import WebAuthnCredentialPublic as WebAuthnCredentialPublic +from otari._client.models.web_authn_credential_update import WebAuthnCredentialUpdate as WebAuthnCredentialUpdate +from otari._client.models.web_authn_credentials_public import WebAuthnCredentialsPublic as WebAuthnCredentialsPublic from otari._client.models.workspace_activation_public import WorkspaceActivationPublic as WorkspaceActivationPublic from otari._client.models.workspace_assignment_request import WorkspaceAssignmentRequest as WorkspaceAssignmentRequest from otari._client.models.workspace_code_execution_policy_public import WorkspaceCodeExecutionPolicyPublic as WorkspaceCodeExecutionPolicyPublic @@ -942,5 +962,7 @@ from otari._client.models.workspace_provider_model_restrictions_public import WorkspaceProviderModelRestrictionsPublic as WorkspaceProviderModelRestrictionsPublic from otari._client.models.workspace_public import WorkspacePublic as WorkspacePublic from otari._client.models.workspace_update import WorkspaceUpdate as WorkspaceUpdate +from otari._client.models.workspace_web_search_config_public import WorkspaceWebSearchConfigPublic as WorkspaceWebSearchConfigPublic +from otari._client.models.workspace_web_search_config_update import WorkspaceWebSearchConfigUpdate as WorkspaceWebSearchConfigUpdate from otari._client.models.workspaces_public import WorkspacesPublic as WorkspacesPublic diff --git a/src/otari/_client/api/__init__.py b/src/otari/_client/api/__init__.py index 6bd9078..f3e2a20 100644 --- a/src/otari/_client/api/__init__.py +++ b/src/otari/_client/api/__init__.py @@ -39,5 +39,6 @@ from otari._client.api.workspace_activation_api import WorkspaceActivationApi from otari._client.api.workspace_code_execution_policy_api import WorkspaceCodeExecutionPolicyApi from otari._client.api.workspace_member_budget_policies_api import WorkspaceMemberBudgetPoliciesApi +from otari._client.api.workspace_web_search_api import WorkspaceWebSearchApi from otari._client.api.workspaces_api import WorkspacesApi diff --git a/src/otari/_client/api/auth_api.py b/src/otari/_client/api/auth_api.py index 3523ce5..643897e 100644 --- a/src/otari/_client/api/auth_api.py +++ b/src/otari/_client/api/auth_api.py @@ -15,8 +15,13 @@ from typing import Any, Dict, List, Optional, Tuple, Union from typing_extensions import Annotated +from typing import Any, Dict +from uuid import UUID +from otari._client.models.authenticate_passkey_request import AuthenticatePasskeyRequest from otari._client.models.create_session_request import CreateSessionRequest +from otari._client.models.passkey_session_response import PasskeySessionResponse from otari._client.models.password_response import PasswordResponse +from otari._client.models.register_passkey_request import RegisterPasskeyRequest from otari._client.models.request_password_reset_request import RequestPasswordResetRequest from otari._client.models.request_password_reset_response import RequestPasswordResetResponse from otari._client.models.resend_verification_request import ResendVerificationRequest @@ -28,6 +33,9 @@ from otari._client.models.signup_response import SignupResponse from otari._client.models.verify_email_request import VerifyEmailRequest from otari._client.models.verify_email_response import VerifyEmailResponse +from otari._client.models.web_authn_credential_public import WebAuthnCredentialPublic +from otari._client.models.web_authn_credential_update import WebAuthnCredentialUpdate +from otari._client.models.web_authn_credentials_public import WebAuthnCredentialsPublic from otari._client.api_client import ApiClient, RequestSerialized from otari._client.api_response import ApiResponse @@ -48,9 +56,9 @@ def __init__(self, api_client=None) -> None: @validate_call - def confirm_reset_v1_auth_password_reset_confirm_post( + def authenticate_passkey_v1_auth_webauthn_authenticate_post( self, - reset_password_request: ResetPasswordRequest, + authenticate_passkey_request: AuthenticatePasskeyRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -63,13 +71,13 @@ def confirm_reset_v1_auth_password_reset_confirm_post( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> None: - """Confirm Reset + ) -> PasskeySessionResponse: + """Authenticate Passkey - Complete a password reset. Single-use: the token stops working after this. + Verify an assertion and set the HttpOnly session cookie. The session is bound to the identity whose passkey signed, exactly as a password sign-in binds one to the identity that authenticated, so every request it later authenticates resolves the same caller. A refusal is counted like the other sign-in failures (``record_auth_failure``) and answered as a 401 by the tenancy error handler. Unlike the password path there is no separate post-failure throttle: this route is throttled unconditionally on the way in, because unlike a password there is no legitimate caller here whose correct credential must never be blocked (a passkey ceremony is one round trip a browser drives, not something a person retries by hand). **Maintenance mode freezes this the way it freezes the password sign-in.** The freeze is on starting a session, not on a credential, so a passkey has to answer to it or the switch is bypassable by anybody holding one, which is the whole population it exists to hold off during a redeploy. Refused before the assertion is verified, so a frozen deployment does no crypto and counts no auth failure: nobody failed to authenticate, the gateway declined to try. - :param reset_password_request: (required) - :type reset_password_request: ResetPasswordRequest + :param authenticate_passkey_request: (required) + :type authenticate_passkey_request: AuthenticatePasskeyRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -92,8 +100,8 @@ def confirm_reset_v1_auth_password_reset_confirm_post( :return: Returns the result object. """ # noqa: E501 - _param = self._confirm_reset_v1_auth_password_reset_confirm_post_serialize( - reset_password_request=reset_password_request, + _param = self._authenticate_passkey_v1_auth_webauthn_authenticate_post_serialize( + authenticate_passkey_request=authenticate_passkey_request, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -101,7 +109,7 @@ def confirm_reset_v1_auth_password_reset_confirm_post( ) _response_types_map: Dict[str, Optional[str]] = { - '204': None, + '200': "PasskeySessionResponse", '422': "HTTPValidationError", } response_data = self.api_client.call_api( @@ -116,9 +124,9 @@ def confirm_reset_v1_auth_password_reset_confirm_post( @validate_call - def confirm_reset_v1_auth_password_reset_confirm_post_with_http_info( + def authenticate_passkey_v1_auth_webauthn_authenticate_post_with_http_info( self, - reset_password_request: ResetPasswordRequest, + authenticate_passkey_request: AuthenticatePasskeyRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -131,13 +139,13 @@ def confirm_reset_v1_auth_password_reset_confirm_post_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[None]: - """Confirm Reset + ) -> ApiResponse[PasskeySessionResponse]: + """Authenticate Passkey - Complete a password reset. Single-use: the token stops working after this. + Verify an assertion and set the HttpOnly session cookie. The session is bound to the identity whose passkey signed, exactly as a password sign-in binds one to the identity that authenticated, so every request it later authenticates resolves the same caller. A refusal is counted like the other sign-in failures (``record_auth_failure``) and answered as a 401 by the tenancy error handler. Unlike the password path there is no separate post-failure throttle: this route is throttled unconditionally on the way in, because unlike a password there is no legitimate caller here whose correct credential must never be blocked (a passkey ceremony is one round trip a browser drives, not something a person retries by hand). **Maintenance mode freezes this the way it freezes the password sign-in.** The freeze is on starting a session, not on a credential, so a passkey has to answer to it or the switch is bypassable by anybody holding one, which is the whole population it exists to hold off during a redeploy. Refused before the assertion is verified, so a frozen deployment does no crypto and counts no auth failure: nobody failed to authenticate, the gateway declined to try. - :param reset_password_request: (required) - :type reset_password_request: ResetPasswordRequest + :param authenticate_passkey_request: (required) + :type authenticate_passkey_request: AuthenticatePasskeyRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -160,8 +168,8 @@ def confirm_reset_v1_auth_password_reset_confirm_post_with_http_info( :return: Returns the result object. """ # noqa: E501 - _param = self._confirm_reset_v1_auth_password_reset_confirm_post_serialize( - reset_password_request=reset_password_request, + _param = self._authenticate_passkey_v1_auth_webauthn_authenticate_post_serialize( + authenticate_passkey_request=authenticate_passkey_request, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -169,7 +177,7 @@ def confirm_reset_v1_auth_password_reset_confirm_post_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '204': None, + '200': "PasskeySessionResponse", '422': "HTTPValidationError", } response_data = self.api_client.call_api( @@ -184,9 +192,9 @@ def confirm_reset_v1_auth_password_reset_confirm_post_with_http_info( @validate_call - def confirm_reset_v1_auth_password_reset_confirm_post_without_preload_content( + def authenticate_passkey_v1_auth_webauthn_authenticate_post_without_preload_content( self, - reset_password_request: ResetPasswordRequest, + authenticate_passkey_request: AuthenticatePasskeyRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -200,12 +208,12 @@ def confirm_reset_v1_auth_password_reset_confirm_post_without_preload_content( _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, ) -> RESTResponseType: - """Confirm Reset + """Authenticate Passkey - Complete a password reset. Single-use: the token stops working after this. + Verify an assertion and set the HttpOnly session cookie. The session is bound to the identity whose passkey signed, exactly as a password sign-in binds one to the identity that authenticated, so every request it later authenticates resolves the same caller. A refusal is counted like the other sign-in failures (``record_auth_failure``) and answered as a 401 by the tenancy error handler. Unlike the password path there is no separate post-failure throttle: this route is throttled unconditionally on the way in, because unlike a password there is no legitimate caller here whose correct credential must never be blocked (a passkey ceremony is one round trip a browser drives, not something a person retries by hand). **Maintenance mode freezes this the way it freezes the password sign-in.** The freeze is on starting a session, not on a credential, so a passkey has to answer to it or the switch is bypassable by anybody holding one, which is the whole population it exists to hold off during a redeploy. Refused before the assertion is verified, so a frozen deployment does no crypto and counts no auth failure: nobody failed to authenticate, the gateway declined to try. - :param reset_password_request: (required) - :type reset_password_request: ResetPasswordRequest + :param authenticate_passkey_request: (required) + :type authenticate_passkey_request: AuthenticatePasskeyRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -228,8 +236,8 @@ def confirm_reset_v1_auth_password_reset_confirm_post_without_preload_content( :return: Returns the result object. """ # noqa: E501 - _param = self._confirm_reset_v1_auth_password_reset_confirm_post_serialize( - reset_password_request=reset_password_request, + _param = self._authenticate_passkey_v1_auth_webauthn_authenticate_post_serialize( + authenticate_passkey_request=authenticate_passkey_request, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -237,7 +245,7 @@ def confirm_reset_v1_auth_password_reset_confirm_post_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '204': None, + '200': "PasskeySessionResponse", '422': "HTTPValidationError", } response_data = self.api_client.call_api( @@ -247,9 +255,9 @@ def confirm_reset_v1_auth_password_reset_confirm_post_without_preload_content( return response_data.response - def _confirm_reset_v1_auth_password_reset_confirm_post_serialize( + def _authenticate_passkey_v1_auth_webauthn_authenticate_post_serialize( self, - reset_password_request, + authenticate_passkey_request, _request_auth, _content_type, _headers, @@ -275,8 +283,8 @@ def _confirm_reset_v1_auth_password_reset_confirm_post_serialize( # process the header parameters # process the form parameters # process the body parameter - if reset_password_request is not None: - _body_params = reset_password_request + if authenticate_passkey_request is not None: + _body_params = authenticate_passkey_request # set the HTTP header `Accept` @@ -307,7 +315,7 @@ def _confirm_reset_v1_auth_password_reset_confirm_post_serialize( return self.api_client.param_serialize( method='POST', - resource_path='/v1/auth/password/reset/confirm', + resource_path='/v1/auth/webauthn/authenticate', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -324,9 +332,8 @@ def _confirm_reset_v1_auth_password_reset_confirm_post_serialize( @validate_call - def create_session_v1_auth_session_post( + def authentication_options_v1_auth_webauthn_authenticate_options_post( self, - create_session_request: CreateSessionRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -339,13 +346,11 @@ def create_session_v1_auth_session_post( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> SessionResponse: - """Create Session + ) -> Dict[str, object]: + """Authentication Options - Verify a sign-in credential and set the HttpOnly session cookie. The session is bound to the identity that authenticated, so every request it later authenticates resolves a user and that user's active organization rather than only \"a credential was presented once\". The response names both, so a client knows who it is signed in as without a second call. The rate-limit check deliberately runs only after a failed verification, not before it: a pre-verification gate can't know whether *this* attempt would have succeeded, so once an IP has used up its failure quota it would end up blocking that IP's legitimate owner too, not just further attackers. Running after verification also means the throttle bounds how many verdicts an IP gets, not how much work it can cause: a password attempt pays for a bcrypt verification (cost 12, on the order of 200ms of CPU, and one is burned against a stand-in hash even for an address nobody holds) before the limit is consulted, so a 429 costs the same as a 401. A gateway exposed to the internet should rate-limit this path at the proxy as well. + Start a passkey sign-in. Public, throttled, and names no credentials. The options carry no ``allowCredentials``, so this publishes nothing about who holds a passkey here; see ``webauthn_service.begin_authentication``. - :param create_session_request: (required) - :type create_session_request: CreateSessionRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -368,8 +373,7 @@ def create_session_v1_auth_session_post( :return: Returns the result object. """ # noqa: E501 - _param = self._create_session_v1_auth_session_post_serialize( - create_session_request=create_session_request, + _param = self._authentication_options_v1_auth_webauthn_authenticate_options_post_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -377,8 +381,7 @@ def create_session_v1_auth_session_post( ) _response_types_map: Dict[str, Optional[str]] = { - '200': "SessionResponse", - '422': "HTTPValidationError", + '200': "Dict[str, object]", } response_data = self.api_client.call_api( *_param, @@ -392,9 +395,8 @@ def create_session_v1_auth_session_post( @validate_call - def create_session_v1_auth_session_post_with_http_info( + def authentication_options_v1_auth_webauthn_authenticate_options_post_with_http_info( self, - create_session_request: CreateSessionRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -407,13 +409,11 @@ def create_session_v1_auth_session_post_with_http_info( _content_type: Optional[StrictStr] = None, _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, - ) -> ApiResponse[SessionResponse]: - """Create Session + ) -> ApiResponse[Dict[str, object]]: + """Authentication Options - Verify a sign-in credential and set the HttpOnly session cookie. The session is bound to the identity that authenticated, so every request it later authenticates resolves a user and that user's active organization rather than only \"a credential was presented once\". The response names both, so a client knows who it is signed in as without a second call. The rate-limit check deliberately runs only after a failed verification, not before it: a pre-verification gate can't know whether *this* attempt would have succeeded, so once an IP has used up its failure quota it would end up blocking that IP's legitimate owner too, not just further attackers. Running after verification also means the throttle bounds how many verdicts an IP gets, not how much work it can cause: a password attempt pays for a bcrypt verification (cost 12, on the order of 200ms of CPU, and one is burned against a stand-in hash even for an address nobody holds) before the limit is consulted, so a 429 costs the same as a 401. A gateway exposed to the internet should rate-limit this path at the proxy as well. + Start a passkey sign-in. Public, throttled, and names no credentials. The options carry no ``allowCredentials``, so this publishes nothing about who holds a passkey here; see ``webauthn_service.begin_authentication``. - :param create_session_request: (required) - :type create_session_request: CreateSessionRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -436,8 +436,7 @@ def create_session_v1_auth_session_post_with_http_info( :return: Returns the result object. """ # noqa: E501 - _param = self._create_session_v1_auth_session_post_serialize( - create_session_request=create_session_request, + _param = self._authentication_options_v1_auth_webauthn_authenticate_options_post_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -445,8 +444,7 @@ def create_session_v1_auth_session_post_with_http_info( ) _response_types_map: Dict[str, Optional[str]] = { - '200': "SessionResponse", - '422': "HTTPValidationError", + '200': "Dict[str, object]", } response_data = self.api_client.call_api( *_param, @@ -460,9 +458,8 @@ def create_session_v1_auth_session_post_with_http_info( @validate_call - def create_session_v1_auth_session_post_without_preload_content( + def authentication_options_v1_auth_webauthn_authenticate_options_post_without_preload_content( self, - create_session_request: CreateSessionRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -476,12 +473,10 @@ def create_session_v1_auth_session_post_without_preload_content( _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, ) -> RESTResponseType: - """Create Session + """Authentication Options - Verify a sign-in credential and set the HttpOnly session cookie. The session is bound to the identity that authenticated, so every request it later authenticates resolves a user and that user's active organization rather than only \"a credential was presented once\". The response names both, so a client knows who it is signed in as without a second call. The rate-limit check deliberately runs only after a failed verification, not before it: a pre-verification gate can't know whether *this* attempt would have succeeded, so once an IP has used up its failure quota it would end up blocking that IP's legitimate owner too, not just further attackers. Running after verification also means the throttle bounds how many verdicts an IP gets, not how much work it can cause: a password attempt pays for a bcrypt verification (cost 12, on the order of 200ms of CPU, and one is burned against a stand-in hash even for an address nobody holds) before the limit is consulted, so a 429 costs the same as a 401. A gateway exposed to the internet should rate-limit this path at the proxy as well. + Start a passkey sign-in. Public, throttled, and names no credentials. The options carry no ``allowCredentials``, so this publishes nothing about who holds a passkey here; see ``webauthn_service.begin_authentication``. - :param create_session_request: (required) - :type create_session_request: CreateSessionRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -504,8 +499,7 @@ def create_session_v1_auth_session_post_without_preload_content( :return: Returns the result object. """ # noqa: E501 - _param = self._create_session_v1_auth_session_post_serialize( - create_session_request=create_session_request, + _param = self._authentication_options_v1_auth_webauthn_authenticate_options_post_serialize( _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -513,8 +507,7 @@ def create_session_v1_auth_session_post_without_preload_content( ) _response_types_map: Dict[str, Optional[str]] = { - '200': "SessionResponse", - '422': "HTTPValidationError", + '200': "Dict[str, object]", } response_data = self.api_client.call_api( *_param, @@ -523,9 +516,8 @@ def create_session_v1_auth_session_post_without_preload_content( return response_data.response - def _create_session_v1_auth_session_post_serialize( + def _authentication_options_v1_auth_webauthn_authenticate_options_post_serialize( self, - create_session_request, _request_auth, _content_type, _headers, @@ -551,8 +543,6 @@ def _create_session_v1_auth_session_post_serialize( # process the header parameters # process the form parameters # process the body parameter - if create_session_request is not None: - _body_params = create_session_request # set the HTTP header `Accept` @@ -563,19 +553,6 @@ def _create_session_v1_auth_session_post_serialize( ] ) - # set the HTTP header `Content-Type` - if _content_type: - _header_params['Content-Type'] = _content_type - else: - _default_content_type = ( - self.api_client.select_header_content_type( - [ - 'application/json' - ] - ) - ) - if _default_content_type is not None: - _header_params['Content-Type'] = _default_content_type # authentication setting _auth_settings: List[str] = [ @@ -583,7 +560,7 @@ def _create_session_v1_auth_session_post_serialize( return self.api_client.param_serialize( method='POST', - resource_path='/v1/auth/session', + resource_path='/v1/auth/webauthn/authenticate/options', path_params=_path_params, query_params=_query_params, header_params=_header_params, @@ -600,8 +577,9 @@ def _create_session_v1_auth_session_post_serialize( @validate_call - def delete_session_v1_auth_session_delete( + def confirm_reset_v1_auth_password_reset_confirm_post( self, + reset_password_request: ResetPasswordRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -615,10 +593,12 @@ def delete_session_v1_auth_session_delete( _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, ) -> None: - """Delete Session + """Confirm Reset - Sign out: revoke the cookie's session server-side and expire the cookie. Deliberately unauthenticated and idempotent: it only ever revokes the session named by the caller's own cookie, and the dashboard calls it on the 401-bounce path where no valid credential exists anymore. Unlike the read path in ``deps.py`` it applies no Sec-Fetch-Site check: ``SameSite=Strict`` already keeps cross-site requests from carrying the cookie, and the worst a forged call could do is sign the operator out. + Complete a password reset. Single-use: the token stops working after this. + :param reset_password_request: (required) + :type reset_password_request: ResetPasswordRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -641,7 +621,8 @@ def delete_session_v1_auth_session_delete( :return: Returns the result object. """ # noqa: E501 - _param = self._delete_session_v1_auth_session_delete_serialize( + _param = self._confirm_reset_v1_auth_password_reset_confirm_post_serialize( + reset_password_request=reset_password_request, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -650,6 +631,7 @@ def delete_session_v1_auth_session_delete( _response_types_map: Dict[str, Optional[str]] = { '204': None, + '422': "HTTPValidationError", } response_data = self.api_client.call_api( *_param, @@ -663,8 +645,9 @@ def delete_session_v1_auth_session_delete( @validate_call - def delete_session_v1_auth_session_delete_with_http_info( + def confirm_reset_v1_auth_password_reset_confirm_post_with_http_info( self, + reset_password_request: ResetPasswordRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -678,10 +661,12 @@ def delete_session_v1_auth_session_delete_with_http_info( _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, ) -> ApiResponse[None]: - """Delete Session + """Confirm Reset - Sign out: revoke the cookie's session server-side and expire the cookie. Deliberately unauthenticated and idempotent: it only ever revokes the session named by the caller's own cookie, and the dashboard calls it on the 401-bounce path where no valid credential exists anymore. Unlike the read path in ``deps.py`` it applies no Sec-Fetch-Site check: ``SameSite=Strict`` already keeps cross-site requests from carrying the cookie, and the worst a forged call could do is sign the operator out. + Complete a password reset. Single-use: the token stops working after this. + :param reset_password_request: (required) + :type reset_password_request: ResetPasswordRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -704,7 +689,8 @@ def delete_session_v1_auth_session_delete_with_http_info( :return: Returns the result object. """ # noqa: E501 - _param = self._delete_session_v1_auth_session_delete_serialize( + _param = self._confirm_reset_v1_auth_password_reset_confirm_post_serialize( + reset_password_request=reset_password_request, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -713,6 +699,7 @@ def delete_session_v1_auth_session_delete_with_http_info( _response_types_map: Dict[str, Optional[str]] = { '204': None, + '422': "HTTPValidationError", } response_data = self.api_client.call_api( *_param, @@ -726,8 +713,9 @@ def delete_session_v1_auth_session_delete_with_http_info( @validate_call - def delete_session_v1_auth_session_delete_without_preload_content( + def confirm_reset_v1_auth_password_reset_confirm_post_without_preload_content( self, + reset_password_request: ResetPasswordRequest, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -741,10 +729,12 @@ def delete_session_v1_auth_session_delete_without_preload_content( _headers: Optional[Dict[StrictStr, Any]] = None, _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, ) -> RESTResponseType: - """Delete Session + """Confirm Reset - Sign out: revoke the cookie's session server-side and expire the cookie. Deliberately unauthenticated and idempotent: it only ever revokes the session named by the caller's own cookie, and the dashboard calls it on the 401-bounce path where no valid credential exists anymore. Unlike the read path in ``deps.py`` it applies no Sec-Fetch-Site check: ``SameSite=Strict`` already keeps cross-site requests from carrying the cookie, and the worst a forged call could do is sign the operator out. + Complete a password reset. Single-use: the token stops working after this. + :param reset_password_request: (required) + :type reset_password_request: ResetPasswordRequest :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -767,7 +757,8 @@ def delete_session_v1_auth_session_delete_without_preload_content( :return: Returns the result object. """ # noqa: E501 - _param = self._delete_session_v1_auth_session_delete_serialize( + _param = self._confirm_reset_v1_auth_password_reset_confirm_post_serialize( + reset_password_request=reset_password_request, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -776,6 +767,7 @@ def delete_session_v1_auth_session_delete_without_preload_content( _response_types_map: Dict[str, Optional[str]] = { '204': None, + '422': "HTTPValidationError", } response_data = self.api_client.call_api( *_param, @@ -784,8 +776,9 @@ def delete_session_v1_auth_session_delete_without_preload_content( return response_data.response - def _delete_session_v1_auth_session_delete_serialize( + def _confirm_reset_v1_auth_password_reset_confirm_post_serialize( self, + reset_password_request, _request_auth, _content_type, _headers, @@ -811,17 +804,1883 @@ def _delete_session_v1_auth_session_delete_serialize( # process the header parameters # process the form parameters # process the body parameter + if reset_password_request is not None: + _body_params = reset_password_request + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type # authentication setting _auth_settings: List[str] = [ ] return self.api_client.param_serialize( - method='DELETE', - resource_path='/v1/auth/session', + method='POST', + resource_path='/v1/auth/password/reset/confirm', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def create_session_v1_auth_session_post( + self, + create_session_request: CreateSessionRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> SessionResponse: + """Create Session + + Verify a sign-in credential and set the HttpOnly session cookie. The session is bound to the identity that authenticated, so every request it later authenticates resolves a user and that user's active organization rather than only \"a credential was presented once\". The response names both, so a client knows who it is signed in as without a second call. The rate-limit check deliberately runs only after a failed verification, not before it: a pre-verification gate can't know whether *this* attempt would have succeeded, so once an IP has used up its failure quota it would end up blocking that IP's legitimate owner too, not just further attackers. Running after verification also means the throttle bounds how many verdicts an IP gets, not how much work it can cause: a password attempt pays for a bcrypt verification (cost 12, on the order of 200ms of CPU, and one is burned against a stand-in hash even for an address nobody holds) before the limit is consulted, so a 429 costs the same as a 401. A gateway exposed to the internet should rate-limit this path at the proxy as well. The maintenance-mode check runs before either credential is verified, and refuses both. Before, because a frozen deployment should not spend a bcrypt verification per attempt and the refusal is not about the credential anyway; both, because the way back out is the master key against ``PATCH /v1/settings/maintenance-mode`` through the header, which never passes through this door. That is what keeps the way back out off the frozen path, and it is why no identity needs an exemption here; an operator who no longer holds the master key recovers by setting ``OTARI_MASTER_KEY`` and restarting, which is a restart rather than a click. It leaks nothing either: ``GET /v1/bootstrap`` already publishes the same flag unauthenticated, so the sign-in screen can render the right page. + + :param create_session_request: (required) + :type create_session_request: CreateSessionRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_session_v1_auth_session_post_serialize( + create_session_request=create_session_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SessionResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_session_v1_auth_session_post_with_http_info( + self, + create_session_request: CreateSessionRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[SessionResponse]: + """Create Session + + Verify a sign-in credential and set the HttpOnly session cookie. The session is bound to the identity that authenticated, so every request it later authenticates resolves a user and that user's active organization rather than only \"a credential was presented once\". The response names both, so a client knows who it is signed in as without a second call. The rate-limit check deliberately runs only after a failed verification, not before it: a pre-verification gate can't know whether *this* attempt would have succeeded, so once an IP has used up its failure quota it would end up blocking that IP's legitimate owner too, not just further attackers. Running after verification also means the throttle bounds how many verdicts an IP gets, not how much work it can cause: a password attempt pays for a bcrypt verification (cost 12, on the order of 200ms of CPU, and one is burned against a stand-in hash even for an address nobody holds) before the limit is consulted, so a 429 costs the same as a 401. A gateway exposed to the internet should rate-limit this path at the proxy as well. The maintenance-mode check runs before either credential is verified, and refuses both. Before, because a frozen deployment should not spend a bcrypt verification per attempt and the refusal is not about the credential anyway; both, because the way back out is the master key against ``PATCH /v1/settings/maintenance-mode`` through the header, which never passes through this door. That is what keeps the way back out off the frozen path, and it is why no identity needs an exemption here; an operator who no longer holds the master key recovers by setting ``OTARI_MASTER_KEY`` and restarting, which is a restart rather than a click. It leaks nothing either: ``GET /v1/bootstrap`` already publishes the same flag unauthenticated, so the sign-in screen can render the right page. + + :param create_session_request: (required) + :type create_session_request: CreateSessionRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_session_v1_auth_session_post_serialize( + create_session_request=create_session_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SessionResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_session_v1_auth_session_post_without_preload_content( + self, + create_session_request: CreateSessionRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Create Session + + Verify a sign-in credential and set the HttpOnly session cookie. The session is bound to the identity that authenticated, so every request it later authenticates resolves a user and that user's active organization rather than only \"a credential was presented once\". The response names both, so a client knows who it is signed in as without a second call. The rate-limit check deliberately runs only after a failed verification, not before it: a pre-verification gate can't know whether *this* attempt would have succeeded, so once an IP has used up its failure quota it would end up blocking that IP's legitimate owner too, not just further attackers. Running after verification also means the throttle bounds how many verdicts an IP gets, not how much work it can cause: a password attempt pays for a bcrypt verification (cost 12, on the order of 200ms of CPU, and one is burned against a stand-in hash even for an address nobody holds) before the limit is consulted, so a 429 costs the same as a 401. A gateway exposed to the internet should rate-limit this path at the proxy as well. The maintenance-mode check runs before either credential is verified, and refuses both. Before, because a frozen deployment should not spend a bcrypt verification per attempt and the refusal is not about the credential anyway; both, because the way back out is the master key against ``PATCH /v1/settings/maintenance-mode`` through the header, which never passes through this door. That is what keeps the way back out off the frozen path, and it is why no identity needs an exemption here; an operator who no longer holds the master key recovers by setting ``OTARI_MASTER_KEY`` and restarting, which is a restart rather than a click. It leaks nothing either: ``GET /v1/bootstrap`` already publishes the same flag unauthenticated, so the sign-in screen can render the right page. + + :param create_session_request: (required) + :type create_session_request: CreateSessionRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_session_v1_auth_session_post_serialize( + create_session_request=create_session_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "SessionResponse", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_session_v1_auth_session_post_serialize( + self, + create_session_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if create_session_request is not None: + _body_params = create_session_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/auth/session', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def delete_passkey_v1_auth_webauthn_credentials_credential_id_delete( + self, + credential_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Delete Passkey + + Remove one of the caller's passkeys. Removing the last one is allowed: an email and password is still this deployment's login, so this is not a lockout, and refusing would strand whoever lost the authenticator. + + :param credential_id: (required) + :type credential_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_passkey_v1_auth_webauthn_credentials_credential_id_delete_serialize( + credential_id=credential_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_passkey_v1_auth_webauthn_credentials_credential_id_delete_with_http_info( + self, + credential_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Delete Passkey + + Remove one of the caller's passkeys. Removing the last one is allowed: an email and password is still this deployment's login, so this is not a lockout, and refusing would strand whoever lost the authenticator. + + :param credential_id: (required) + :type credential_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_passkey_v1_auth_webauthn_credentials_credential_id_delete_serialize( + credential_id=credential_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_passkey_v1_auth_webauthn_credentials_credential_id_delete_without_preload_content( + self, + credential_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete Passkey + + Remove one of the caller's passkeys. Removing the last one is allowed: an email and password is still this deployment's login, so this is not a lockout, and refusing would strand whoever lost the authenticator. + + :param credential_id: (required) + :type credential_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_passkey_v1_auth_webauthn_credentials_credential_id_delete_serialize( + credential_id=credential_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_passkey_v1_auth_webauthn_credentials_credential_id_delete_serialize( + self, + credential_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if credential_id is not None: + _path_params['credential_id'] = credential_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/v1/auth/webauthn/credentials/{credential_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def delete_session_v1_auth_session_delete( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Delete Session + + Sign out: revoke the cookie's session server-side and expire the cookie. Deliberately unauthenticated and idempotent: it only ever revokes the session named by the caller's own cookie, and the dashboard calls it on the 401-bounce path where no valid credential exists anymore. Unlike the read path in ``deps.py`` it applies no Sec-Fetch-Site check: ``SameSite=Strict`` already keeps cross-site requests from carrying the cookie, and the worst a forged call could do is sign the operator out. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_session_v1_auth_session_delete_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_session_v1_auth_session_delete_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Delete Session + + Sign out: revoke the cookie's session server-side and expire the cookie. Deliberately unauthenticated and idempotent: it only ever revokes the session named by the caller's own cookie, and the dashboard calls it on the 401-bounce path where no valid credential exists anymore. Unlike the read path in ``deps.py`` it applies no Sec-Fetch-Site check: ``SameSite=Strict`` already keeps cross-site requests from carrying the cookie, and the worst a forged call could do is sign the operator out. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_session_v1_auth_session_delete_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_session_v1_auth_session_delete_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete Session + + Sign out: revoke the cookie's session server-side and expire the cookie. Deliberately unauthenticated and idempotent: it only ever revokes the session named by the caller's own cookie, and the dashboard calls it on the 401-bounce path where no valid credential exists anymore. Unlike the read path in ``deps.py`` it applies no Sec-Fetch-Site check: ``SameSite=Strict`` already keeps cross-site requests from carrying the cookie, and the worst a forged call could do is sign the operator out. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_session_v1_auth_session_delete_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_session_v1_auth_session_delete_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + + + # authentication setting + _auth_settings: List[str] = [ + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/v1/auth/session', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def list_passkeys_v1_auth_webauthn_credentials_get( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> WebAuthnCredentialsPublic: + """List Passkeys + + The caller's own passkeys. Never anybody else's, and never key material. Deliberately *not* behind ``require_passkey_support``, and not filtered to the current relying-party ID. A deployment that has changed or lost that ID still holds the rows registered under the old one, and refusing to list them would leave somebody looking at an empty page with no way to clean up and no hint as to why. Each row carries ``is_usable`` instead, so an orphan is visible, explained, and deletable. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_passkeys_v1_auth_webauthn_credentials_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WebAuthnCredentialsPublic", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def list_passkeys_v1_auth_webauthn_credentials_get_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[WebAuthnCredentialsPublic]: + """List Passkeys + + The caller's own passkeys. Never anybody else's, and never key material. Deliberately *not* behind ``require_passkey_support``, and not filtered to the current relying-party ID. A deployment that has changed or lost that ID still holds the rows registered under the old one, and refusing to list them would leave somebody looking at an empty page with no way to clean up and no hint as to why. Each row carries ``is_usable`` instead, so an orphan is visible, explained, and deletable. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_passkeys_v1_auth_webauthn_credentials_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WebAuthnCredentialsPublic", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def list_passkeys_v1_auth_webauthn_credentials_get_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Passkeys + + The caller's own passkeys. Never anybody else's, and never key material. Deliberately *not* behind ``require_passkey_support``, and not filtered to the current relying-party ID. A deployment that has changed or lost that ID still holds the rows registered under the old one, and refusing to list them would leave somebody looking at an empty page with no way to clean up and no hint as to why. Each row carries ``is_usable`` instead, so an orphan is visible, explained, and deletable. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._list_passkeys_v1_auth_webauthn_credentials_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WebAuthnCredentialsPublic", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _list_passkeys_v1_auth_webauthn_credentials_get_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/auth/webauthn/credentials', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def register_passkey_v1_auth_webauthn_register_post( + self, + register_passkey_request: RegisterPasskeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> WebAuthnCredentialPublic: + """Register Passkey + + Verify a registration ceremony and store the passkey it produced. + + :param register_passkey_request: (required) + :type register_passkey_request: RegisterPasskeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._register_passkey_v1_auth_webauthn_register_post_serialize( + register_passkey_request=register_passkey_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "WebAuthnCredentialPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def register_passkey_v1_auth_webauthn_register_post_with_http_info( + self, + register_passkey_request: RegisterPasskeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[WebAuthnCredentialPublic]: + """Register Passkey + + Verify a registration ceremony and store the passkey it produced. + + :param register_passkey_request: (required) + :type register_passkey_request: RegisterPasskeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._register_passkey_v1_auth_webauthn_register_post_serialize( + register_passkey_request=register_passkey_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "WebAuthnCredentialPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def register_passkey_v1_auth_webauthn_register_post_without_preload_content( + self, + register_passkey_request: RegisterPasskeyRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Register Passkey + + Verify a registration ceremony and store the passkey it produced. + + :param register_passkey_request: (required) + :type register_passkey_request: RegisterPasskeyRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._register_passkey_v1_auth_webauthn_register_post_serialize( + register_passkey_request=register_passkey_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "WebAuthnCredentialPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _register_passkey_v1_auth_webauthn_register_post_serialize( + self, + register_passkey_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if register_passkey_request is not None: + _body_params = register_passkey_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/auth/webauthn/register', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def registration_options_v1_auth_webauthn_register_options_post( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> Dict[str, object]: + """Registration Options + + Start registering a passkey for the signed-in identity. A POST rather than a GET even though it reads like one: it issues a server-side challenge and writes it, so it is not safe to repeat, cache, or prefetch. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._registration_options_v1_auth_webauthn_register_options_post_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def registration_options_v1_auth_webauthn_register_options_post_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[Dict[str, object]]: + """Registration Options + + Start registering a passkey for the signed-in identity. A POST rather than a GET even though it reads like one: it issues a server-side challenge and writes it, so it is not safe to repeat, cache, or prefetch. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._registration_options_v1_auth_webauthn_register_options_post_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def registration_options_v1_auth_webauthn_register_options_post_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Registration Options + + Start registering a passkey for the signed-in identity. A POST rather than a GET even though it reads like one: it issues a server-side challenge and writes it, so it is not safe to repeat, cache, or prefetch. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._registration_options_v1_auth_webauthn_register_options_post_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Dict[str, object]", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _registration_options_v1_auth_webauthn_register_options_post_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/v1/auth/webauthn/register/options', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def rename_passkey_v1_auth_webauthn_credentials_credential_id_patch( + self, + credential_id: UUID, + web_authn_credential_update: WebAuthnCredentialUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> WebAuthnCredentialPublic: + """Rename Passkey + + Relabel one of the caller's passkeys, which is all that is editable. Ungated like the list, and for the same reason: naming an orphan before deleting it is not something a lost relying-party ID should prevent. + + :param credential_id: (required) + :type credential_id: UUID + :param web_authn_credential_update: (required) + :type web_authn_credential_update: WebAuthnCredentialUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._rename_passkey_v1_auth_webauthn_credentials_credential_id_patch_serialize( + credential_id=credential_id, + web_authn_credential_update=web_authn_credential_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WebAuthnCredentialPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def rename_passkey_v1_auth_webauthn_credentials_credential_id_patch_with_http_info( + self, + credential_id: UUID, + web_authn_credential_update: WebAuthnCredentialUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[WebAuthnCredentialPublic]: + """Rename Passkey + + Relabel one of the caller's passkeys, which is all that is editable. Ungated like the list, and for the same reason: naming an orphan before deleting it is not something a lost relying-party ID should prevent. + + :param credential_id: (required) + :type credential_id: UUID + :param web_authn_credential_update: (required) + :type web_authn_credential_update: WebAuthnCredentialUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._rename_passkey_v1_auth_webauthn_credentials_credential_id_patch_serialize( + credential_id=credential_id, + web_authn_credential_update=web_authn_credential_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WebAuthnCredentialPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def rename_passkey_v1_auth_webauthn_credentials_credential_id_patch_without_preload_content( + self, + credential_id: UUID, + web_authn_credential_update: WebAuthnCredentialUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Rename Passkey + + Relabel one of the caller's passkeys, which is all that is editable. Ungated like the list, and for the same reason: naming an orphan before deleting it is not something a lost relying-party ID should prevent. + + :param credential_id: (required) + :type credential_id: UUID + :param web_authn_credential_update: (required) + :type web_authn_credential_update: WebAuthnCredentialUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._rename_passkey_v1_auth_webauthn_credentials_credential_id_patch_serialize( + credential_id=credential_id, + web_authn_credential_update=web_authn_credential_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WebAuthnCredentialPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _rename_passkey_v1_auth_webauthn_credentials_credential_id_patch_serialize( + self, + credential_id, + web_authn_credential_update, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if credential_id is not None: + _path_params['credential_id'] = credential_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if web_authn_credential_update is not None: + _body_params = web_authn_credential_update + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='PATCH', + resource_path='/v1/auth/webauthn/credentials/{credential_id}', path_params=_path_params, query_params=_query_params, header_params=_header_params, diff --git a/src/otari/_client/api/settings_api.py b/src/otari/_client/api/settings_api.py index b2fd02e..9d79967 100644 --- a/src/otari/_client/api/settings_api.py +++ b/src/otari/_client/api/settings_api.py @@ -17,9 +17,11 @@ from otari._client.models.gateway_settings import GatewaySettings from otari._client.models.mail_settings import MailSettings +from otari._client.models.maintenance_mode import MaintenanceMode from otari._client.models.rotate_master_key_response import RotateMasterKeyResponse from otari._client.models.send_test_mail_request import SendTestMailRequest from otari._client.models.send_test_mail_response import SendTestMailResponse +from otari._client.models.update_maintenance_mode_request import UpdateMaintenanceModeRequest from otari._client.models.update_settings_request import UpdateSettingsRequest from otari._client.api_client import ApiClient, RequestSerialized @@ -287,6 +289,253 @@ def _get_mail_settings_v1_settings_mail_get_serialize( + @validate_call + def get_maintenance_mode_v1_settings_maintenance_mode_get( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> MaintenanceMode: + """Get Maintenance Mode + + Report whether new dashboard sign-ins are frozen. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_maintenance_mode_v1_settings_maintenance_mode_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MaintenanceMode", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_maintenance_mode_v1_settings_maintenance_mode_get_with_http_info( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[MaintenanceMode]: + """Get Maintenance Mode + + Report whether new dashboard sign-ins are frozen. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_maintenance_mode_v1_settings_maintenance_mode_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MaintenanceMode", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_maintenance_mode_v1_settings_maintenance_mode_get_without_preload_content( + self, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get Maintenance Mode + + Report whether new dashboard sign-ins are frozen. + + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_maintenance_mode_v1_settings_maintenance_mode_get_serialize( + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MaintenanceMode", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_maintenance_mode_v1_settings_maintenance_mode_get_serialize( + self, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/settings/maintenance-mode', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + @validate_call def get_settings_v1_settings_get( self, @@ -1059,6 +1308,284 @@ def _send_test_mail_v1_settings_mail_test_post_serialize( + @validate_call + def update_maintenance_mode_v1_settings_maintenance_mode_patch( + self, + update_maintenance_mode_request: UpdateMaintenanceModeRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> MaintenanceMode: + """Update Maintenance Mode + + Freeze or unfreeze dashboard sign-ins, for this and every other replica. The new state is persisted and nothing is applied to the running worker, because every reader goes back to the stored row. That is what makes one call enough for a deployment running more than one of them. + + :param update_maintenance_mode_request: (required) + :type update_maintenance_mode_request: UpdateMaintenanceModeRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_maintenance_mode_v1_settings_maintenance_mode_patch_serialize( + update_maintenance_mode_request=update_maintenance_mode_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MaintenanceMode", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def update_maintenance_mode_v1_settings_maintenance_mode_patch_with_http_info( + self, + update_maintenance_mode_request: UpdateMaintenanceModeRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[MaintenanceMode]: + """Update Maintenance Mode + + Freeze or unfreeze dashboard sign-ins, for this and every other replica. The new state is persisted and nothing is applied to the running worker, because every reader goes back to the stored row. That is what makes one call enough for a deployment running more than one of them. + + :param update_maintenance_mode_request: (required) + :type update_maintenance_mode_request: UpdateMaintenanceModeRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_maintenance_mode_v1_settings_maintenance_mode_patch_serialize( + update_maintenance_mode_request=update_maintenance_mode_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MaintenanceMode", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def update_maintenance_mode_v1_settings_maintenance_mode_patch_without_preload_content( + self, + update_maintenance_mode_request: UpdateMaintenanceModeRequest, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update Maintenance Mode + + Freeze or unfreeze dashboard sign-ins, for this and every other replica. The new state is persisted and nothing is applied to the running worker, because every reader goes back to the stored row. That is what makes one call enough for a deployment running more than one of them. + + :param update_maintenance_mode_request: (required) + :type update_maintenance_mode_request: UpdateMaintenanceModeRequest + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_maintenance_mode_v1_settings_maintenance_mode_patch_serialize( + update_maintenance_mode_request=update_maintenance_mode_request, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "MaintenanceMode", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_maintenance_mode_v1_settings_maintenance_mode_patch_serialize( + self, + update_maintenance_mode_request, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if update_maintenance_mode_request is not None: + _body_params = update_maintenance_mode_request + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='PATCH', + resource_path='/v1/settings/maintenance-mode', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + @validate_call def update_settings_v1_settings_patch( self, diff --git a/src/otari/_client/api/workspace_web_search_api.py b/src/otari/_client/api/workspace_web_search_api.py new file mode 100644 index 0000000..58dddff --- /dev/null +++ b/src/otari/_client/api/workspace_web_search_api.py @@ -0,0 +1,860 @@ +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from uuid import UUID +from otari._client.models.workspace_web_search_config_public import WorkspaceWebSearchConfigPublic +from otari._client.models.workspace_web_search_config_update import WorkspaceWebSearchConfigUpdate + +from otari._client.api_client import ApiClient, RequestSerialized +from otari._client.api_response import ApiResponse +from otari._client.rest import RESTResponseType + + +class WorkspaceWebSearchApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def clear_workspace_web_search_config_v1_workspaces_workspace_id_web_search_delete( + self, + workspace_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> WorkspaceWebSearchConfigPublic: + """Clear Workspace Web Search Config + + Drop a workspace's configuration, returning it to the deployment's behavior. Idempotent: a workspace that has no configuration is already in the state this asks for, so it answers with the unconfigured shape rather than a 404. + + :param workspace_id: (required) + :type workspace_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._clear_workspace_web_search_config_v1_workspaces_workspace_id_web_search_delete_serialize( + workspace_id=workspace_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def clear_workspace_web_search_config_v1_workspaces_workspace_id_web_search_delete_with_http_info( + self, + workspace_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[WorkspaceWebSearchConfigPublic]: + """Clear Workspace Web Search Config + + Drop a workspace's configuration, returning it to the deployment's behavior. Idempotent: a workspace that has no configuration is already in the state this asks for, so it answers with the unconfigured shape rather than a 404. + + :param workspace_id: (required) + :type workspace_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._clear_workspace_web_search_config_v1_workspaces_workspace_id_web_search_delete_serialize( + workspace_id=workspace_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def clear_workspace_web_search_config_v1_workspaces_workspace_id_web_search_delete_without_preload_content( + self, + workspace_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Clear Workspace Web Search Config + + Drop a workspace's configuration, returning it to the deployment's behavior. Idempotent: a workspace that has no configuration is already in the state this asks for, so it answers with the unconfigured shape rather than a 404. + + :param workspace_id: (required) + :type workspace_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._clear_workspace_web_search_config_v1_workspaces_workspace_id_web_search_delete_serialize( + workspace_id=workspace_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _clear_workspace_web_search_config_v1_workspaces_workspace_id_web_search_delete_serialize( + self, + workspace_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if workspace_id is not None: + _path_params['workspace_id'] = workspace_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/v1/workspaces/{workspace_id}/web-search', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_workspace_web_search_config_v1_workspaces_workspace_id_web_search_get( + self, + workspace_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> WorkspaceWebSearchConfigPublic: + """Get Workspace Web Search Config + + Read a workspace's web-search configuration. Takes the same role as setting it (an organization owner/admin, or an owner/admin of this workspace), because the row describes the workspace's posture rather than one member's allowance. A workspace with no row answers with the unconfigured shape (``configured: false``), which is the deployment's own behavior described in the same shape rather than a 404. + + :param workspace_id: (required) + :type workspace_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_workspace_web_search_config_v1_workspaces_workspace_id_web_search_get_serialize( + workspace_id=workspace_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_workspace_web_search_config_v1_workspaces_workspace_id_web_search_get_with_http_info( + self, + workspace_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[WorkspaceWebSearchConfigPublic]: + """Get Workspace Web Search Config + + Read a workspace's web-search configuration. Takes the same role as setting it (an organization owner/admin, or an owner/admin of this workspace), because the row describes the workspace's posture rather than one member's allowance. A workspace with no row answers with the unconfigured shape (``configured: false``), which is the deployment's own behavior described in the same shape rather than a 404. + + :param workspace_id: (required) + :type workspace_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_workspace_web_search_config_v1_workspaces_workspace_id_web_search_get_serialize( + workspace_id=workspace_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_workspace_web_search_config_v1_workspaces_workspace_id_web_search_get_without_preload_content( + self, + workspace_id: UUID, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get Workspace Web Search Config + + Read a workspace's web-search configuration. Takes the same role as setting it (an organization owner/admin, or an owner/admin of this workspace), because the row describes the workspace's posture rather than one member's allowance. A workspace with no row answers with the unconfigured shape (``configured: false``), which is the deployment's own behavior described in the same shape rather than a 404. + + :param workspace_id: (required) + :type workspace_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_workspace_web_search_config_v1_workspaces_workspace_id_web_search_get_serialize( + workspace_id=workspace_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_workspace_web_search_config_v1_workspaces_workspace_id_web_search_get_serialize( + self, + workspace_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if workspace_id is not None: + _path_params['workspace_id'] = workspace_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/v1/workspaces/{workspace_id}/web-search', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def set_workspace_web_search_config_v1_workspaces_workspace_id_web_search_put( + self, + workspace_id: UUID, + workspace_web_search_config_update: WorkspaceWebSearchConfigUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> WorkspaceWebSearchConfigPublic: + """Set Workspace Web Search Config + + Set a workspace's web-search configuration, replacing any existing one. An organization owner/admin, or an owner/admin of this workspace, may write it. The configuration can only narrow what the deployment permits: turning web search off for the workspace, lowering the result ceiling, and adding to the domains a search may not reach. It never turns on a backend the deployment has not configured, and it carries no credential. + + :param workspace_id: (required) + :type workspace_id: UUID + :param workspace_web_search_config_update: (required) + :type workspace_web_search_config_update: WorkspaceWebSearchConfigUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._set_workspace_web_search_config_v1_workspaces_workspace_id_web_search_put_serialize( + workspace_id=workspace_id, + workspace_web_search_config_update=workspace_web_search_config_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def set_workspace_web_search_config_v1_workspaces_workspace_id_web_search_put_with_http_info( + self, + workspace_id: UUID, + workspace_web_search_config_update: WorkspaceWebSearchConfigUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[WorkspaceWebSearchConfigPublic]: + """Set Workspace Web Search Config + + Set a workspace's web-search configuration, replacing any existing one. An organization owner/admin, or an owner/admin of this workspace, may write it. The configuration can only narrow what the deployment permits: turning web search off for the workspace, lowering the result ceiling, and adding to the domains a search may not reach. It never turns on a backend the deployment has not configured, and it carries no credential. + + :param workspace_id: (required) + :type workspace_id: UUID + :param workspace_web_search_config_update: (required) + :type workspace_web_search_config_update: WorkspaceWebSearchConfigUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._set_workspace_web_search_config_v1_workspaces_workspace_id_web_search_put_serialize( + workspace_id=workspace_id, + workspace_web_search_config_update=workspace_web_search_config_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def set_workspace_web_search_config_v1_workspaces_workspace_id_web_search_put_without_preload_content( + self, + workspace_id: UUID, + workspace_web_search_config_update: WorkspaceWebSearchConfigUpdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Set Workspace Web Search Config + + Set a workspace's web-search configuration, replacing any existing one. An organization owner/admin, or an owner/admin of this workspace, may write it. The configuration can only narrow what the deployment permits: turning web search off for the workspace, lowering the result ceiling, and adding to the domains a search may not reach. It never turns on a backend the deployment has not configured, and it carries no credential. + + :param workspace_id: (required) + :type workspace_id: UUID + :param workspace_web_search_config_update: (required) + :type workspace_web_search_config_update: WorkspaceWebSearchConfigUpdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._set_workspace_web_search_config_v1_workspaces_workspace_id_web_search_put_serialize( + workspace_id=workspace_id, + workspace_web_search_config_update=workspace_web_search_config_update, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "WorkspaceWebSearchConfigPublic", + '422': "HTTPValidationError", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _set_workspace_web_search_config_v1_workspaces_workspace_id_web_search_put_serialize( + self, + workspace_id, + workspace_web_search_config_update, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if workspace_id is not None: + _path_params['workspace_id'] = workspace_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if workspace_web_search_config_update is not None: + _body_params = workspace_web_search_config_update + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'XApiKeyAuth', + 'ApiKeyAuth' + ] + + return self.api_client.param_serialize( + method='PUT', + resource_path='/v1/workspaces/{workspace_id}/web-search', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/src/otari/_client/models/__init__.py b/src/otari/_client/models/__init__.py index f1288fb..0091468 100644 --- a/src/otari/_client/models/__init__.py +++ b/src/otari/_client/models/__init__.py @@ -41,6 +41,7 @@ from otari._client.models.api_key_id import ApiKeyId from otari._client.models.applied_edits_inner import AppliedEditsInner from otari._client.models.audio_speech_request import AudioSpeechRequest +from otari._client.models.authenticate_passkey_request import AuthenticatePasskeyRequest from otari._client.models.batch_request_item import BatchRequestItem from otari._client.models.billing_meters import BillingMeters from otari._client.models.budget_reset_log_response import BudgetResetLogResponse @@ -274,6 +275,7 @@ from otari._client.models.msg_image_url import MSGImageURL from otari._client.models.msg_input_audio import MSGInputAudio from otari._client.models.mail_settings import MailSettings +from otari._client.models.maintenance_mode import MaintenanceMode from otari._client.models.managed_tool import ManagedTool from otari._client.models.mcp_server_config import McpServerConfig from otari._client.models.message import Message @@ -299,6 +301,7 @@ from otari._client.models.organization_model_pricing_update import OrganizationModelPricingUpdate from otari._client.models.organization_model_pricings_public import OrganizationModelPricingsPublic from otari._client.models.organization_public import OrganizationPublic +from otari._client.models.passkey_session_response import PasskeySessionResponse from otari._client.models.password_response import PasswordResponse from otari._client.models.policy_request import PolicyRequest from otari._client.models.policy_response import PolicyResponse @@ -323,6 +326,7 @@ from otari._client.models.recorded_pool import RecordedPool from otari._client.models.reencrypt_provider_credentials_response import ReencryptProviderCredentialsResponse from otari._client.models.reencrypt_search_tools_response import ReencryptSearchToolsResponse +from otari._client.models.register_passkey_request import RegisterPasskeyRequest from otari._client.models.request_password_reset_request import RequestPasswordResetRequest from otari._client.models.request_password_reset_response import RequestPasswordResetResponse from otari._client.models.rerank_request import RerankRequest @@ -371,6 +375,7 @@ from otari._client.models.units1 import Units1 from otari._client.models.update_budget_request import UpdateBudgetRequest from otari._client.models.update_key_request import UpdateKeyRequest +from otari._client.models.update_maintenance_mode_request import UpdateMaintenanceModeRequest from otari._client.models.update_scoped_budget_request import UpdateScopedBudgetRequest from otari._client.models.update_search_tool_request import UpdateSearchToolRequest from otari._client.models.update_settings_request import UpdateSettingsRequest @@ -401,6 +406,9 @@ from otari._client.models.value1 import Value1 from otari._client.models.verify_email_request import VerifyEmailRequest from otari._client.models.verify_email_response import VerifyEmailResponse +from otari._client.models.web_authn_credential_public import WebAuthnCredentialPublic +from otari._client.models.web_authn_credential_update import WebAuthnCredentialUpdate +from otari._client.models.web_authn_credentials_public import WebAuthnCredentialsPublic from otari._client.models.workspace_activation_public import WorkspaceActivationPublic from otari._client.models.workspace_assignment_request import WorkspaceAssignmentRequest from otari._client.models.workspace_code_execution_policy_public import WorkspaceCodeExecutionPolicyPublic @@ -423,5 +431,7 @@ from otari._client.models.workspace_provider_model_restrictions_public import WorkspaceProviderModelRestrictionsPublic from otari._client.models.workspace_public import WorkspacePublic from otari._client.models.workspace_update import WorkspaceUpdate +from otari._client.models.workspace_web_search_config_public import WorkspaceWebSearchConfigPublic +from otari._client.models.workspace_web_search_config_update import WorkspaceWebSearchConfigUpdate from otari._client.models.workspaces_public import WorkspacesPublic diff --git a/src/otari/_client/models/authenticate_passkey_request.py b/src/otari/_client/models/authenticate_passkey_request.py new file mode 100644 index 0000000..c41a653 --- /dev/null +++ b/src/otari/_client/models/authenticate_passkey_request.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class AuthenticatePasskeyRequest(BaseModel): + """ + A completed sign-in ceremony. + """ # noqa: E501 + credential: Dict[str, Any] = Field(description="The browser's PublicKeyCredential assertion, serialized.") + __properties: ClassVar[List[str]] = ["credential"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AuthenticatePasskeyRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AuthenticatePasskeyRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "credential": obj.get("credential") + }) + return _obj + + diff --git a/src/otari/_client/models/deployment_bootstrap.py b/src/otari/_client/models/deployment_bootstrap.py index f690e5c..eb1298a 100644 --- a/src/otari/_client/models/deployment_bootstrap.py +++ b/src/otari/_client/models/deployment_bootstrap.py @@ -29,11 +29,13 @@ class DeploymentBootstrap(BaseModel): """ # noqa: E501 deployment_type: StrictStr = Field(description="Which deployment serves this URL. 'standalone' owns its own data; 'hosted' is otari.ai; 'hybrid' is a gateway attached to otari.ai, which is data-plane only and holds no management surface of its own.") mail_ready: StrictBool = Field(description="Whether this deployment can deliver a message carrying a link back to itself (an invitation's accept link, and the verification and reset links to come), not merely whether a transport is configured: it also needs to know its own public URL to put in one. Lets the dashboard disable or hide a mail-dependent affordance instead of offering one that would fail at send time. Every message this control plane sends carries such a link, which is why this is one flag and not one per feature. False for a hybrid gateway, whose control plane is otari.ai and which sends no mail of its own.") + maintenance_mode: StrictBool = Field(description="Whether this deployment is refusing new dashboard sign-ins while an operator redeploys it. The sign-in screen says so rather than presenting a form whose only outcome is a 503. Sessions already issued keep working, and the management API and the data plane are unaffected. False for a hybrid gateway, which issues no session.") management_url: Optional[StrictStr] = Field(description="Where the authoritative control plane lives when it is not this deployment. Set for a hybrid gateway so its landing page can link to otari.ai; null otherwise.") + passkeys_ready: StrictBool = Field(description="Whether this deployment can run a passkey ceremony at all: it has a relying-party ID (webauthn_rp_id, or derived from public_base_url) and an origin to serve one from. Distinct from 'passkey' in sign_in_methods, which is narrower and answers whether a registered passkey could sign somebody in *right now*: an operator with none yet needs this one, or the page that registers the first would be hidden from them. False for a hybrid gateway, which issues no session of its own.") session_type: StrictStr = Field(description="The kind of session this deployment issues, not whether the caller holds one. 'local_operator' is the standalone operator sign-in (see sign_in_methods for which credential it currently accepts), 'hosted_user' an otari.ai account, and 'none' a deployment that issues no management session at all.") - sign_in_methods: List[StrictStr] = Field(description="How POST /v1/auth/session may be authenticated right now, sorted. 'master_key' is the first-boot credential and is offered until the operator identity has a password, which is what claiming the deployment means; 'password' replaces it from then on, and the master key stays the credential for the management API. Empty for a hybrid gateway, which issues no session. The login page renders from this rather than trying a credential to find out.") + sign_in_methods: List[StrictStr] = Field(description="How POST /v1/auth/session may be authenticated right now, sorted. 'master_key' is the first-boot credential and is offered until the operator identity has a password, which is what claiming the deployment means; 'password' replaces it from then on, and the master key stays the credential for the management API. 'passkey' appears alongside either one when this deployment is configured for WebAuthn and holds at least one passkey that its current relying-party ID can assert. Empty for a hybrid gateway, which issues no session. The login page renders from this rather than trying a credential to find out.") surfaces: List[StrictStr] = Field(description="Management API groups this deployment serves, sorted, which is what its dashboard pages gate on. Named surfaces, not capabilities: capability is otari.ai's word for the entitlement (licensing) axis, and this is the deployment (topology) axis. Empty for a hybrid gateway.") - __properties: ClassVar[List[str]] = ["deployment_type", "mail_ready", "management_url", "session_type", "sign_in_methods", "surfaces"] + __properties: ClassVar[List[str]] = ["deployment_type", "mail_ready", "maintenance_mode", "management_url", "passkeys_ready", "session_type", "sign_in_methods", "surfaces"] @field_validator('deployment_type') def deployment_type_validate_enum(cls, value): @@ -53,8 +55,8 @@ def session_type_validate_enum(cls, value): def sign_in_methods_validate_enum(cls, value): """Validates the enum""" for i in value: - if i not in set(['master_key', 'password']): - raise ValueError("each list item must be one of ('master_key', 'password')") + if i not in set(['master_key', 'password', 'passkey']): + raise ValueError("each list item must be one of ('master_key', 'password', 'passkey')") return value model_config = ConfigDict( @@ -115,7 +117,9 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: _obj = cls.model_validate({ "deployment_type": obj.get("deployment_type"), "mail_ready": obj.get("mail_ready"), + "maintenance_mode": obj.get("maintenance_mode"), "management_url": obj.get("management_url"), + "passkeys_ready": obj.get("passkeys_ready"), "session_type": obj.get("session_type"), "sign_in_methods": obj.get("sign_in_methods"), "surfaces": obj.get("surfaces") diff --git a/src/otari/_client/models/maintenance_mode.py b/src/otari/_client/models/maintenance_mode.py new file mode 100644 index 0000000..60411c4 --- /dev/null +++ b/src/otari/_client/models/maintenance_mode.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class MaintenanceMode(BaseModel): + """ + Whether this deployment is currently refusing new dashboard sign-ins. + """ # noqa: E501 + enabled: StrictBool = Field(description="When true, POST /v1/auth/session refuses every credential with 503 so nobody starts a new dashboard session during a redeploy. Sessions already issued keep working, and the management API and the data plane are unaffected: a caller presenting the master key or an API key through the header is never frozen out.") + __properties: ClassVar[List[str]] = ["enabled"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of MaintenanceMode from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of MaintenanceMode from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "enabled": obj.get("enabled") + }) + return _obj + + diff --git a/src/otari/_client/models/passkey_session_response.py b/src/otari/_client/models/passkey_session_response.py new file mode 100644 index 0000000..3040830 --- /dev/null +++ b/src/otari/_client/models/passkey_session_response.py @@ -0,0 +1,94 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List +from uuid import UUID +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class PasskeySessionResponse(BaseModel): + """ + A dashboard session minted by a passkey (the token travels only in the cookie). The same three fields ``POST /v1/auth/session`` answers, deliberately: the dashboard's sign-in path does not care which credential got it here. + """ # noqa: E501 + active_organization_id: UUID = Field(description="The organization that identity is acting in, which scopes every tenancy surface.") + expires_at: datetime = Field(description="When the session cookie stops being accepted.") + user_id: UUID = Field(description="The identity this session speaks for.") + __properties: ClassVar[List[str]] = ["active_organization_id", "expires_at", "user_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of PasskeySessionResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of PasskeySessionResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "active_organization_id": obj.get("active_organization_id"), + "expires_at": obj.get("expires_at"), + "user_id": obj.get("user_id") + }) + return _obj + + diff --git a/src/otari/_client/models/register_passkey_request.py b/src/otari/_client/models/register_passkey_request.py new file mode 100644 index 0000000..8dd8d1b --- /dev/null +++ b/src/otari/_client/models/register_passkey_request.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class RegisterPasskeyRequest(BaseModel): + """ + A completed registration ceremony, with the label to file it under. + """ # noqa: E501 + credential: Dict[str, Any] = Field(description="The browser's PublicKeyCredential, serialized.") + name: Optional[Annotated[str, Field(strict=True, max_length=255)]] = Field(default=None, description="What to call this passkey in the credential list. Optional: an unnamed one is numbered rather than refused, so a browser that offers no prompt still works.") + __properties: ClassVar[List[str]] = ["credential", "name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RegisterPasskeyRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if name (nullable) is None + # and model_fields_set contains the field + if self.name is None and "name" in self.model_fields_set: + _dict['name'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RegisterPasskeyRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "credential": obj.get("credential"), + "name": obj.get("name") + }) + return _obj + + diff --git a/src/otari/_client/models/update_maintenance_mode_request.py b/src/otari/_client/models/update_maintenance_mode_request.py new file mode 100644 index 0000000..d48184b --- /dev/null +++ b/src/otari/_client/models/update_maintenance_mode_request.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class UpdateMaintenanceModeRequest(BaseModel): + """ + Turn the sign-in freeze on or off. + """ # noqa: E501 + enabled: StrictBool = Field(description="True to freeze new dashboard sign-ins, false to allow them again.") + __properties: ClassVar[List[str]] = ["enabled"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of UpdateMaintenanceModeRequest from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of UpdateMaintenanceModeRequest from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "enabled": obj.get("enabled") + }) + return _obj + + diff --git a/src/otari/_client/models/web_authn_credential_public.py b/src/otari/_client/models/web_authn_credential_public.py new file mode 100644 index 0000000..75f520c --- /dev/null +++ b/src/otari/_client/models/web_authn_credential_public.py @@ -0,0 +1,112 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from uuid import UUID +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class WebAuthnCredentialPublic(BaseModel): + """ + A passkey as the settings page lists it. Carries no key material. ``credential_id`` is here because the browser needs it to tell the passkey it just used from the others in the list, and it is a public identifier the authenticator hands to any site that asks: it is what ``allowCredentials`` publishes to an unauthenticated caller during a ceremony. + """ # noqa: E501 + backed_up: StrictBool + created_at: datetime + credential_id: StrictStr + id: UUID + is_usable: StrictBool + last_used_at: Optional[datetime] + name: Annotated[str, Field(strict=True, max_length=255)] + rp_id: StrictStr + transports: List[StrictStr] + __properties: ClassVar[List[str]] = ["backed_up", "created_at", "credential_id", "id", "is_usable", "last_used_at", "name", "rp_id", "transports"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of WebAuthnCredentialPublic from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if last_used_at (nullable) is None + # and model_fields_set contains the field + if self.last_used_at is None and "last_used_at" in self.model_fields_set: + _dict['last_used_at'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WebAuthnCredentialPublic from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "backed_up": obj.get("backed_up"), + "created_at": obj.get("created_at"), + "credential_id": obj.get("credential_id"), + "id": obj.get("id"), + "is_usable": obj.get("is_usable"), + "last_used_at": obj.get("last_used_at"), + "name": obj.get("name"), + "rp_id": obj.get("rp_id"), + "transports": obj.get("transports") + }) + return _obj + + diff --git a/src/otari/_client/models/web_authn_credential_update.py b/src/otari/_client/models/web_authn_credential_update.py new file mode 100644 index 0000000..4e45c22 --- /dev/null +++ b/src/otari/_client/models/web_authn_credential_update.py @@ -0,0 +1,89 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class WebAuthnCredentialUpdate(BaseModel): + """ + Renaming a passkey, which is the only thing about one that is editable. Everything else on the row is what the authenticator asserted, so there is nothing else a person could correct. + """ # noqa: E501 + name: Annotated[str, Field(strict=True, max_length=255)] + __properties: ClassVar[List[str]] = ["name"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of WebAuthnCredentialUpdate from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WebAuthnCredentialUpdate from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "name": obj.get("name") + }) + return _obj + + diff --git a/src/otari/_client/models/web_authn_credentials_public.py b/src/otari/_client/models/web_authn_credentials_public.py new file mode 100644 index 0000000..34fce15 --- /dev/null +++ b/src/otari/_client/models/web_authn_credentials_public.py @@ -0,0 +1,98 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictInt +from typing import Any, ClassVar, Dict, List +from otari._client.models.web_authn_credential_public import WebAuthnCredentialPublic +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class WebAuthnCredentialsPublic(BaseModel): + """ + WebAuthnCredentialsPublic + """ # noqa: E501 + count: StrictInt + data: List[WebAuthnCredentialPublic] + __properties: ClassVar[List[str]] = ["count", "data"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of WebAuthnCredentialsPublic from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in data (list) + _items = [] + if self.data: + for _item_data in self.data: + if _item_data: + _items.append(_item_data.to_dict()) + _dict['data'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WebAuthnCredentialsPublic from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "count": obj.get("count"), + "data": [WebAuthnCredentialPublic.from_dict(_item) for _item in obj["data"]] if obj.get("data") is not None else None + }) + return _obj + + diff --git a/src/otari/_client/models/workspace_member_budget_policy_public.py b/src/otari/_client/models/workspace_member_budget_policy_public.py index 32381a9..0e9cfd5 100644 --- a/src/otari/_client/models/workspace_member_budget_policy_public.py +++ b/src/otari/_client/models/workspace_member_budget_policy_public.py @@ -35,9 +35,10 @@ class WorkspaceMemberBudgetPolicyPublic(BaseModel): max_budget: Optional[Union[StrictFloat, StrictInt]] name: Optional[StrictStr] provider_key_id: Optional[StrictStr] + reset_alignment: Optional[StrictStr] updated_at: StrictStr workspace_id: UUID - __properties: ClassVar[List[str]] = ["budget_duration_sec", "budget_id", "created_at", "id", "max_budget", "name", "provider_key_id", "updated_at", "workspace_id"] + __properties: ClassVar[List[str]] = ["budget_duration_sec", "budget_id", "created_at", "id", "max_budget", "name", "provider_key_id", "reset_alignment", "updated_at", "workspace_id"] model_config = ConfigDict( validate_by_name=True, @@ -98,6 +99,11 @@ def to_dict(self) -> Dict[str, Any]: if self.provider_key_id is None and "provider_key_id" in self.model_fields_set: _dict['provider_key_id'] = None + # set to None if reset_alignment (nullable) is None + # and model_fields_set contains the field + if self.reset_alignment is None and "reset_alignment" in self.model_fields_set: + _dict['reset_alignment'] = None + return _dict @classmethod @@ -117,6 +123,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "max_budget": obj.get("max_budget"), "name": obj.get("name"), "provider_key_id": obj.get("provider_key_id"), + "reset_alignment": obj.get("reset_alignment"), "updated_at": obj.get("updated_at"), "workspace_id": obj.get("workspace_id") }) diff --git a/src/otari/_client/models/workspace_web_search_config_public.py b/src/otari/_client/models/workspace_web_search_config_public.py new file mode 100644 index 0000000..afe6ce0 --- /dev/null +++ b/src/otari/_client/models/workspace_web_search_config_public.py @@ -0,0 +1,144 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from uuid import UUID +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class WorkspaceWebSearchConfigPublic(BaseModel): + """ + A workspace's web-search configuration, or the unconfigured one it has without a row. + """ # noqa: E501 + allowed_domains: Optional[List[StrictStr]] + blocked_domains: Optional[List[StrictStr]] + configured: StrictBool + created_at: Optional[StrictStr] + enabled: StrictBool + max_results: Optional[StrictInt] + provider_options: Optional[Dict[str, Any]] = Field(description="Provider-native request fields used as defaults (e.g. exa's 'type', searxng's 'engines').") + purpose_hint: Optional[StrictStr] + updated_at: Optional[StrictStr] + web_search_configured: StrictBool + workspace_id: UUID + __properties: ClassVar[List[str]] = ["allowed_domains", "blocked_domains", "configured", "created_at", "enabled", "max_results", "provider_options", "purpose_hint", "updated_at", "web_search_configured", "workspace_id"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of WorkspaceWebSearchConfigPublic from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if allowed_domains (nullable) is None + # and model_fields_set contains the field + if self.allowed_domains is None and "allowed_domains" in self.model_fields_set: + _dict['allowed_domains'] = None + + # set to None if blocked_domains (nullable) is None + # and model_fields_set contains the field + if self.blocked_domains is None and "blocked_domains" in self.model_fields_set: + _dict['blocked_domains'] = None + + # set to None if created_at (nullable) is None + # and model_fields_set contains the field + if self.created_at is None and "created_at" in self.model_fields_set: + _dict['created_at'] = None + + # set to None if max_results (nullable) is None + # and model_fields_set contains the field + if self.max_results is None and "max_results" in self.model_fields_set: + _dict['max_results'] = None + + # set to None if provider_options (nullable) is None + # and model_fields_set contains the field + if self.provider_options is None and "provider_options" in self.model_fields_set: + _dict['provider_options'] = None + + # set to None if purpose_hint (nullable) is None + # and model_fields_set contains the field + if self.purpose_hint is None and "purpose_hint" in self.model_fields_set: + _dict['purpose_hint'] = None + + # set to None if updated_at (nullable) is None + # and model_fields_set contains the field + if self.updated_at is None and "updated_at" in self.model_fields_set: + _dict['updated_at'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WorkspaceWebSearchConfigPublic from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "allowed_domains": obj.get("allowed_domains"), + "blocked_domains": obj.get("blocked_domains"), + "configured": obj.get("configured"), + "created_at": obj.get("created_at"), + "enabled": obj.get("enabled"), + "max_results": obj.get("max_results"), + "provider_options": obj.get("provider_options"), + "purpose_hint": obj.get("purpose_hint"), + "updated_at": obj.get("updated_at"), + "web_search_configured": obj.get("web_search_configured"), + "workspace_id": obj.get("workspace_id") + }) + return _obj + + diff --git a/src/otari/_client/models/workspace_web_search_config_update.py b/src/otari/_client/models/workspace_web_search_config_update.py new file mode 100644 index 0000000..0c8b668 --- /dev/null +++ b/src/otari/_client/models/workspace_web_search_config_update.py @@ -0,0 +1,124 @@ +# coding: utf-8 + +""" + otari + + Otari, an OpenAI-compatible LLM gateway with API key management + + The version of the OpenAPI document: 0.0.0-dev + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class WorkspaceWebSearchConfigUpdate(BaseModel): + """ + The configuration to store for a workspace, as a whole. ``PUT`` semantics, ported from the hosted ``WorkspaceWebSearchConfigUpdate``: what is sent is what the workspace has afterwards, so an omitted field is cleared rather than left as it was. + """ # noqa: E501 + allowed_domains: Optional[List[StrictStr]] = Field(default=None, description="Results are kept only from these domains; intersected with any list the request sends") + blocked_domains: Optional[List[StrictStr]] = Field(default=None, description="Results from these domains are dropped; added to any list the request sends") + enabled: StrictBool = Field(description="False refuses web search for this workspace, both the otari_web_search tool and POST /v1/search. The fields below narrow the tool only.") + max_results: Optional[Annotated[int, Field(le=20, strict=True, gt=0)]] = Field(default=None, description="Ceiling on results one search returns; only ever lowers the effective limit, so at most 20") + provider_options: Optional[Dict[str, Any]] = Field(default=None, description="Provider-native request fields used as defaults (e.g. exa's 'type', searxng's 'engines').") + purpose_hint: Optional[Annotated[str, Field(strict=True, max_length=2048)]] = Field(default=None, description="Hint used when a request declares otari_web_search without one of its own") + __properties: ClassVar[List[str]] = ["allowed_domains", "blocked_domains", "enabled", "max_results", "provider_options", "purpose_hint"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of WorkspaceWebSearchConfigUpdate from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if allowed_domains (nullable) is None + # and model_fields_set contains the field + if self.allowed_domains is None and "allowed_domains" in self.model_fields_set: + _dict['allowed_domains'] = None + + # set to None if blocked_domains (nullable) is None + # and model_fields_set contains the field + if self.blocked_domains is None and "blocked_domains" in self.model_fields_set: + _dict['blocked_domains'] = None + + # set to None if max_results (nullable) is None + # and model_fields_set contains the field + if self.max_results is None and "max_results" in self.model_fields_set: + _dict['max_results'] = None + + # set to None if provider_options (nullable) is None + # and model_fields_set contains the field + if self.provider_options is None and "provider_options" in self.model_fields_set: + _dict['provider_options'] = None + + # set to None if purpose_hint (nullable) is None + # and model_fields_set contains the field + if self.purpose_hint is None and "purpose_hint" in self.model_fields_set: + _dict['purpose_hint'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of WorkspaceWebSearchConfigUpdate from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "allowed_domains": obj.get("allowed_domains"), + "blocked_domains": obj.get("blocked_domains"), + "enabled": obj.get("enabled"), + "max_results": obj.get("max_results"), + "provider_options": obj.get("provider_options"), + "purpose_hint": obj.get("purpose_hint") + }) + return _obj + +