from kagglesdk.kaggle_object import *
from typing import Optional, List

class ExchangeOAuthTokenRequest(KaggleObject):
  r"""
  Attributes:
    code (str)
      Temporary OAuth code that was generated by the backend based on OAuth
      parameters passed to the '/api/v1/oauth2/authorize' (StartOAuthFlowRequest)
      endpoint. This is also known as OAuth flow token. It is sent to the flow
      initiator as a query string parameter to their redirect_uri
      (https://dataverse.org?code=808f9afcabb3489a8b30353a8ae4dc4b)
    code_verifier (str)
      Original code_verifier (hash of code_challenge) for PKCE protection.
    grant_type (str)
      Can be 'authorization_code' or 'refresh_token'.
    client_id (str)
      The client id of the OAuth client that initiated this flow.
    redirect_uri (str)
      The redirect URI that was used in the initial authorization request.
    resource (str)
      The 'resource' parameter is not part of the OAuth2 spec, but is sent by
      some clients. We are capturing it here to avoid 'invalid field' errors.
    refresh_token (str)
      This field is used by MCP clients to refresh an access token. The client
      sends a refresh_token to the standard /token endpoint, and this field
      allows the server to correctly deserialize the request.
  """

  def __init__(self):
    self._code = None
    self._code_verifier = None
    self._grant_type = ""
    self._client_id = None
    self._redirect_uri = None
    self._resource = None
    self._refresh_token = None
    self._freeze()

  @property
  def code(self) -> str:
    r"""
    Temporary OAuth code that was generated by the backend based on OAuth
    parameters passed to the '/api/v1/oauth2/authorize' (StartOAuthFlowRequest)
    endpoint. This is also known as OAuth flow token. It is sent to the flow
    initiator as a query string parameter to their redirect_uri
    (https://dataverse.org?code=808f9afcabb3489a8b30353a8ae4dc4b)
    """
    return self._code or ""

  @code.setter
  def code(self, code: Optional[str]):
    if code is None:
      del self.code
      return
    if not isinstance(code, str):
      raise TypeError('code must be of type str')
    self._code = code

  @property
  def code_verifier(self) -> str:
    """Original code_verifier (hash of code_challenge) for PKCE protection."""
    return self._code_verifier or ""

  @code_verifier.setter
  def code_verifier(self, code_verifier: Optional[str]):
    if code_verifier is None:
      del self.code_verifier
      return
    if not isinstance(code_verifier, str):
      raise TypeError('code_verifier must be of type str')
    self._code_verifier = code_verifier

  @property
  def grant_type(self) -> str:
    """Can be 'authorization_code' or 'refresh_token'."""
    return self._grant_type

  @grant_type.setter
  def grant_type(self, grant_type: str):
    if grant_type is None:
      del self.grant_type
      return
    if not isinstance(grant_type, str):
      raise TypeError('grant_type must be of type str')
    self._grant_type = grant_type

  @property
  def client_id(self) -> str:
    """The client id of the OAuth client that initiated this flow."""
    return self._client_id or ""

  @client_id.setter
  def client_id(self, client_id: Optional[str]):
    if client_id is None:
      del self.client_id
      return
    if not isinstance(client_id, str):
      raise TypeError('client_id must be of type str')
    self._client_id = client_id

  @property
  def redirect_uri(self) -> str:
    """The redirect URI that was used in the initial authorization request."""
    return self._redirect_uri or ""

  @redirect_uri.setter
  def redirect_uri(self, redirect_uri: Optional[str]):
    if redirect_uri is None:
      del self.redirect_uri
      return
    if not isinstance(redirect_uri, str):
      raise TypeError('redirect_uri must be of type str')
    self._redirect_uri = redirect_uri

  @property
  def resource(self) -> str:
    r"""
    The 'resource' parameter is not part of the OAuth2 spec, but is sent by
    some clients. We are capturing it here to avoid 'invalid field' errors.
    """
    return self._resource or ""

  @resource.setter
  def resource(self, resource: Optional[str]):
    if resource is None:
      del self.resource
      return
    if not isinstance(resource, str):
      raise TypeError('resource must be of type str')
    self._resource = resource

  @property
  def refresh_token(self) -> str:
    r"""
    This field is used by MCP clients to refresh an access token. The client
    sends a refresh_token to the standard /token endpoint, and this field
    allows the server to correctly deserialize the request.
    """
    return self._refresh_token or ""

  @refresh_token.setter
  def refresh_token(self, refresh_token: Optional[str]):
    if refresh_token is None:
      del self.refresh_token
      return
    if not isinstance(refresh_token, str):
      raise TypeError('refresh_token must be of type str')
    self._refresh_token = refresh_token

  def endpoint(self):
    path = '/api/v1/oauth2/token'
    return path.format_map(self.to_field_map(self))


  @staticmethod
  def method():
    return 'POST'

  @staticmethod
  def body_fields():
    return '*'


class ExchangeOAuthTokenResponse(KaggleObject):
  r"""
  Attributes:
    access_token (str)
      Short-lived access token.
    refresh_token (str)
      Long-lived refresh token that can be used to generate access tokens using
      the '/api/v1/access-tokens/generate' (GenerateAccessTokenRequest) endpoint.
    token_type (str)
      Type of the token. Set to 'Bearer'.
    expires_in (int)
      Lifetime of the access token in seconds.
    username (str)
      Username of the user who authorized/owns this token.
    user_id (int)
      Id the of user who authorized/owns this token.
    scope (str)
      The scope of the access token as a space-delimited list of strings.
  """

  def __init__(self):
    self._access_token = ""
    self._refresh_token = ""
    self._token_type = ""
    self._expires_in = 0
    self._username = ""
    self._user_id = 0
    self._scope = None
    self._freeze()

  @property
  def access_token(self) -> str:
    """Short-lived access token."""
    return self._access_token

  @access_token.setter
  def access_token(self, access_token: str):
    if access_token is None:
      del self.access_token
      return
    if not isinstance(access_token, str):
      raise TypeError('access_token must be of type str')
    self._access_token = access_token

  @property
  def refresh_token(self) -> str:
    r"""
    Long-lived refresh token that can be used to generate access tokens using
    the '/api/v1/access-tokens/generate' (GenerateAccessTokenRequest) endpoint.
    """
    return self._refresh_token

  @refresh_token.setter
  def refresh_token(self, refresh_token: str):
    if refresh_token is None:
      del self.refresh_token
      return
    if not isinstance(refresh_token, str):
      raise TypeError('refresh_token must be of type str')
    self._refresh_token = refresh_token

  @property
  def token_type(self) -> str:
    """Type of the token. Set to 'Bearer'."""
    return self._token_type

  @token_type.setter
  def token_type(self, token_type: str):
    if token_type is None:
      del self.token_type
      return
    if not isinstance(token_type, str):
      raise TypeError('token_type must be of type str')
    self._token_type = token_type

  @property
  def expires_in(self) -> int:
    """Lifetime of the access token in seconds."""
    return self._expires_in

  @expires_in.setter
  def expires_in(self, expires_in: int):
    if expires_in is None:
      del self.expires_in
      return
    if not isinstance(expires_in, int):
      raise TypeError('expires_in must be of type int')
    self._expires_in = expires_in

  @property
  def username(self) -> str:
    """Username of the user who authorized/owns this token."""
    return self._username

  @username.setter
  def username(self, username: str):
    if username is None:
      del self.username
      return
    if not isinstance(username, str):
      raise TypeError('username must be of type str')
    self._username = username

  @property
  def user_id(self) -> int:
    """Id the of user who authorized/owns this token."""
    return self._user_id

  @user_id.setter
  def user_id(self, user_id: int):
    if user_id is None:
      del self.user_id
      return
    if not isinstance(user_id, int):
      raise TypeError('user_id must be of type int')
    self._user_id = user_id

  @property
  def scope(self) -> str:
    """The scope of the access token as a space-delimited list of strings."""
    return self._scope or ""

  @scope.setter
  def scope(self, scope: Optional[str]):
    if scope is None:
      del self.scope
      return
    if not isinstance(scope, str):
      raise TypeError('scope must be of type str')
    self._scope = scope

  @property
  def accessToken(self):
    return self.access_token

  @property
  def refreshToken(self):
    return self.refresh_token

  @property
  def tokenType(self):
    return self.token_type

  @property
  def expiresIn(self):
    return self.expires_in

  @property
  def userId(self):
    return self.user_id


class IntrospectTokenRequest(KaggleObject):
  r"""
  Attributes:
    token (str)
      Token to introspect (access token or refresh token), returned in the
      response of '/api/v1/oauth2/token' (ExchangeOAuthToken) RPC.
  """

  def __init__(self):
    self._token = ""
    self._freeze()

  @property
  def token(self) -> str:
    r"""
    Token to introspect (access token or refresh token), returned in the
    response of '/api/v1/oauth2/token' (ExchangeOAuthToken) RPC.
    """
    return self._token

  @token.setter
  def token(self, token: str):
    if token is None:
      del self.token
      return
    if not isinstance(token, str):
      raise TypeError('token must be of type str')
    self._token = token

  def endpoint(self):
    path = '/api/v1/oauth2/introspect'
    return path.format_map(self.to_field_map(self))


  @staticmethod
  def method():
    return 'POST'

  @staticmethod
  def body_fields():
    return '*'


class IntrospectTokenResponse(KaggleObject):
  r"""
  Attributes:
    active (bool)
      Indicates if the token is active, i.e., not revoked nor expired.
    client_id (str)
      The client identifier for the OAuth 2.0 client that the token was issued
      to.
    username (str)
      Username of the user who authorized this token.
    user_id (int)
      Id of the user who authorized this token.
    scope (str)
      Space-separated list of scopes.
    exp (int)
      The unix timestamp indicating when this token will expire.
  """

  def __init__(self):
    self._active = False
    self._client_id = ""
    self._username = ""
    self._user_id = None
    self._scope = ""
    self._exp = None
    self._freeze()

  @property
  def active(self) -> bool:
    """Indicates if the token is active, i.e., not revoked nor expired."""
    return self._active

  @active.setter
  def active(self, active: bool):
    if active is None:
      del self.active
      return
    if not isinstance(active, bool):
      raise TypeError('active must be of type bool')
    self._active = active

  @property
  def client_id(self) -> str:
    r"""
    The client identifier for the OAuth 2.0 client that the token was issued
    to.
    """
    return self._client_id

  @client_id.setter
  def client_id(self, client_id: str):
    if client_id is None:
      del self.client_id
      return
    if not isinstance(client_id, str):
      raise TypeError('client_id must be of type str')
    self._client_id = client_id

  @property
  def username(self) -> str:
    """Username of the user who authorized this token."""
    return self._username

  @username.setter
  def username(self, username: str):
    if username is None:
      del self.username
      return
    if not isinstance(username, str):
      raise TypeError('username must be of type str')
    self._username = username

  @property
  def user_id(self) -> int:
    """Id of the user who authorized this token."""
    return self._user_id or 0

  @user_id.setter
  def user_id(self, user_id: Optional[int]):
    if user_id is None:
      del self.user_id
      return
    if not isinstance(user_id, int):
      raise TypeError('user_id must be of type int')
    self._user_id = user_id

  @property
  def scope(self) -> str:
    """Space-separated list of scopes."""
    return self._scope

  @scope.setter
  def scope(self, scope: str):
    if scope is None:
      del self.scope
      return
    if not isinstance(scope, str):
      raise TypeError('scope must be of type str')
    self._scope = scope

  @property
  def exp(self) -> int:
    """The unix timestamp indicating when this token will expire."""
    return self._exp or 0

  @exp.setter
  def exp(self, exp: Optional[int]):
    if exp is None:
      del self.exp
      return
    if not isinstance(exp, int):
      raise TypeError('exp must be of type int')
    self._exp = exp

  @property
  def clientId(self):
    return self.client_id

  @property
  def userId(self):
    return self.user_id


class RegisterOAuthClientRequest(KaggleObject):
  r"""
  Attributes:
    client_name (str)
      Human-readable name for the client (e.g., 'Gemini CLI MCP Client')
    redirect_uris (str)
      Array of redirect URIs the client will use (e.g.,
      'http://localhost:7777/oauth/callback')
    grant_types (str)
      Array of OAuth 2.0 grant types the client requests (expected:
      authorization_code, refresh_token)
    token_endpoint_auth_method (str)
      Client Authentication method (expected: 'none')
    scope (str)
      Space-separated list of scopes the client would like to use
    code_challenge_method (str)
      Array of supported PKCE methods (expected: 'S256')
  """

  def __init__(self):
    self._client_name = ""
    self._redirect_uris = []
    self._grant_types = []
    self._token_endpoint_auth_method = ""
    self._scope = None
    self._code_challenge_method = []
    self._freeze()

  @property
  def client_name(self) -> str:
    """Human-readable name for the client (e.g., 'Gemini CLI MCP Client')"""
    return self._client_name

  @client_name.setter
  def client_name(self, client_name: str):
    if client_name is None:
      del self.client_name
      return
    if not isinstance(client_name, str):
      raise TypeError('client_name must be of type str')
    self._client_name = client_name

  @property
  def redirect_uris(self) -> Optional[List[str]]:
    r"""
    Array of redirect URIs the client will use (e.g.,
    'http://localhost:7777/oauth/callback')
    """
    return self._redirect_uris

  @redirect_uris.setter
  def redirect_uris(self, redirect_uris: Optional[List[str]]):
    if redirect_uris is None:
      del self.redirect_uris
      return
    if not isinstance(redirect_uris, list):
      raise TypeError('redirect_uris must be of type list')
    if not all([isinstance(t, str) for t in redirect_uris]):
      raise TypeError('redirect_uris must contain only items of type str')
    self._redirect_uris = redirect_uris

  @property
  def grant_types(self) -> Optional[List[str]]:
    r"""
    Array of OAuth 2.0 grant types the client requests (expected:
    authorization_code, refresh_token)
    """
    return self._grant_types

  @grant_types.setter
  def grant_types(self, grant_types: Optional[List[str]]):
    if grant_types is None:
      del self.grant_types
      return
    if not isinstance(grant_types, list):
      raise TypeError('grant_types must be of type list')
    if not all([isinstance(t, str) for t in grant_types]):
      raise TypeError('grant_types must contain only items of type str')
    self._grant_types = grant_types

  @property
  def token_endpoint_auth_method(self) -> str:
    """Client Authentication method (expected: 'none')"""
    return self._token_endpoint_auth_method

  @token_endpoint_auth_method.setter
  def token_endpoint_auth_method(self, token_endpoint_auth_method: str):
    if token_endpoint_auth_method is None:
      del self.token_endpoint_auth_method
      return
    if not isinstance(token_endpoint_auth_method, str):
      raise TypeError('token_endpoint_auth_method must be of type str')
    self._token_endpoint_auth_method = token_endpoint_auth_method

  @property
  def scope(self) -> str:
    """Space-separated list of scopes the client would like to use"""
    return self._scope or ""

  @scope.setter
  def scope(self, scope: Optional[str]):
    if scope is None:
      del self.scope
      return
    if not isinstance(scope, str):
      raise TypeError('scope must be of type str')
    self._scope = scope

  @property
  def code_challenge_method(self) -> Optional[List[str]]:
    """Array of supported PKCE methods (expected: 'S256')"""
    return self._code_challenge_method

  @code_challenge_method.setter
  def code_challenge_method(self, code_challenge_method: Optional[List[str]]):
    if code_challenge_method is None:
      del self.code_challenge_method
      return
    if not isinstance(code_challenge_method, list):
      raise TypeError('code_challenge_method must be of type list')
    if not all([isinstance(t, str) for t in code_challenge_method]):
      raise TypeError('code_challenge_method must contain only items of type str')
    self._code_challenge_method = code_challenge_method

  def endpoint(self):
    path = '/api/v1/oauth2/register'
    return path.format_map(self.to_field_map(self))


  @staticmethod
  def method():
    return 'POST'

  @staticmethod
  def body_fields():
    return '*'


class RegisterOAuthClientResponse(KaggleObject):
  r"""
  According to RFC 7591 &&
  https://github.com/google-gemini/gemini-cli/blob/56f394cefd04696a5192fef9bbff8ba0e5b0583f/packages/core/src/mcp/oauth-provider.ts#L69

  Attributes:
    client_id (str)
    redirect_uris (str)
    grant_types (str)
    response_types (str)
    token_endpoint_auth_method (str)
    scope (str)
    authorization_url (str)
    token_url (str)
    client_secret (str)
    client_id_issued_at (int)
    client_secret_expires_at (int)
    revocation_url (str)
    userinfo_url (str)
    code_challenge_methods_supported (str)
  """

  def __init__(self):
    self._client_id = ""
    self._redirect_uris = []
    self._grant_types = []
    self._response_types = []
    self._token_endpoint_auth_method = ""
    self._scope = None
    self._authorization_url = None
    self._token_url = None
    self._client_secret = None
    self._client_id_issued_at = None
    self._client_secret_expires_at = None
    self._revocation_url = None
    self._userinfo_url = None
    self._code_challenge_methods_supported = []
    self._freeze()

  @property
  def client_id(self) -> str:
    return self._client_id

  @client_id.setter
  def client_id(self, client_id: str):
    if client_id is None:
      del self.client_id
      return
    if not isinstance(client_id, str):
      raise TypeError('client_id must be of type str')
    self._client_id = client_id

  @property
  def redirect_uris(self) -> Optional[List[str]]:
    return self._redirect_uris

  @redirect_uris.setter
  def redirect_uris(self, redirect_uris: Optional[List[str]]):
    if redirect_uris is None:
      del self.redirect_uris
      return
    if not isinstance(redirect_uris, list):
      raise TypeError('redirect_uris must be of type list')
    if not all([isinstance(t, str) for t in redirect_uris]):
      raise TypeError('redirect_uris must contain only items of type str')
    self._redirect_uris = redirect_uris

  @property
  def grant_types(self) -> Optional[List[str]]:
    return self._grant_types

  @grant_types.setter
  def grant_types(self, grant_types: Optional[List[str]]):
    if grant_types is None:
      del self.grant_types
      return
    if not isinstance(grant_types, list):
      raise TypeError('grant_types must be of type list')
    if not all([isinstance(t, str) for t in grant_types]):
      raise TypeError('grant_types must contain only items of type str')
    self._grant_types = grant_types

  @property
  def response_types(self) -> Optional[List[str]]:
    return self._response_types

  @response_types.setter
  def response_types(self, response_types: Optional[List[str]]):
    if response_types is None:
      del self.response_types
      return
    if not isinstance(response_types, list):
      raise TypeError('response_types must be of type list')
    if not all([isinstance(t, str) for t in response_types]):
      raise TypeError('response_types must contain only items of type str')
    self._response_types = response_types

  @property
  def token_endpoint_auth_method(self) -> str:
    return self._token_endpoint_auth_method

  @token_endpoint_auth_method.setter
  def token_endpoint_auth_method(self, token_endpoint_auth_method: str):
    if token_endpoint_auth_method is None:
      del self.token_endpoint_auth_method
      return
    if not isinstance(token_endpoint_auth_method, str):
      raise TypeError('token_endpoint_auth_method must be of type str')
    self._token_endpoint_auth_method = token_endpoint_auth_method

  @property
  def scope(self) -> str:
    return self._scope or ""

  @scope.setter
  def scope(self, scope: Optional[str]):
    if scope is None:
      del self.scope
      return
    if not isinstance(scope, str):
      raise TypeError('scope must be of type str')
    self._scope = scope

  @property
  def authorization_url(self) -> str:
    return self._authorization_url or ""

  @authorization_url.setter
  def authorization_url(self, authorization_url: Optional[str]):
    if authorization_url is None:
      del self.authorization_url
      return
    if not isinstance(authorization_url, str):
      raise TypeError('authorization_url must be of type str')
    self._authorization_url = authorization_url

  @property
  def token_url(self) -> str:
    return self._token_url or ""

  @token_url.setter
  def token_url(self, token_url: Optional[str]):
    if token_url is None:
      del self.token_url
      return
    if not isinstance(token_url, str):
      raise TypeError('token_url must be of type str')
    self._token_url = token_url

  @property
  def revocation_url(self) -> str:
    return self._revocation_url or ""

  @revocation_url.setter
  def revocation_url(self, revocation_url: Optional[str]):
    if revocation_url is None:
      del self.revocation_url
      return
    if not isinstance(revocation_url, str):
      raise TypeError('revocation_url must be of type str')
    self._revocation_url = revocation_url

  @property
  def userinfo_url(self) -> str:
    return self._userinfo_url or ""

  @userinfo_url.setter
  def userinfo_url(self, userinfo_url: Optional[str]):
    if userinfo_url is None:
      del self.userinfo_url
      return
    if not isinstance(userinfo_url, str):
      raise TypeError('userinfo_url must be of type str')
    self._userinfo_url = userinfo_url

  @property
  def code_challenge_methods_supported(self) -> Optional[List[str]]:
    return self._code_challenge_methods_supported

  @code_challenge_methods_supported.setter
  def code_challenge_methods_supported(self, code_challenge_methods_supported: Optional[List[str]]):
    if code_challenge_methods_supported is None:
      del self.code_challenge_methods_supported
      return
    if not isinstance(code_challenge_methods_supported, list):
      raise TypeError('code_challenge_methods_supported must be of type list')
    if not all([isinstance(t, str) for t in code_challenge_methods_supported]):
      raise TypeError('code_challenge_methods_supported must contain only items of type str')
    self._code_challenge_methods_supported = code_challenge_methods_supported

  @property
  def client_secret(self) -> str:
    return self._client_secret or ""

  @client_secret.setter
  def client_secret(self, client_secret: Optional[str]):
    if client_secret is None:
      del self.client_secret
      return
    if not isinstance(client_secret, str):
      raise TypeError('client_secret must be of type str')
    self._client_secret = client_secret

  @property
  def client_id_issued_at(self) -> int:
    return self._client_id_issued_at or 0

  @client_id_issued_at.setter
  def client_id_issued_at(self, client_id_issued_at: Optional[int]):
    if client_id_issued_at is None:
      del self.client_id_issued_at
      return
    if not isinstance(client_id_issued_at, int):
      raise TypeError('client_id_issued_at must be of type int')
    self._client_id_issued_at = client_id_issued_at

  @property
  def client_secret_expires_at(self) -> int:
    return self._client_secret_expires_at or 0

  @client_secret_expires_at.setter
  def client_secret_expires_at(self, client_secret_expires_at: Optional[int]):
    if client_secret_expires_at is None:
      del self.client_secret_expires_at
      return
    if not isinstance(client_secret_expires_at, int):
      raise TypeError('client_secret_expires_at must be of type int')
    self._client_secret_expires_at = client_secret_expires_at

  @property
  def clientId(self):
    return self.client_id

  @property
  def redirectUris(self):
    return self.redirect_uris

  @property
  def grantTypes(self):
    return self.grant_types

  @property
  def responseTypes(self):
    return self.response_types

  @property
  def tokenEndpointAuthMethod(self):
    return self.token_endpoint_auth_method

  @property
  def authorizationUrl(self):
    return self.authorization_url

  @property
  def tokenUrl(self):
    return self.token_url

  @property
  def revocationUrl(self):
    return self.revocation_url

  @property
  def userinfoUrl(self):
    return self.userinfo_url

  @property
  def codeChallengeMethodsSupported(self):
    return self.code_challenge_methods_supported

  @property
  def clientSecret(self):
    return self.client_secret

  @property
  def clientIdIssuedAt(self):
    return self.client_id_issued_at

  @property
  def clientSecretExpiresAt(self):
    return self.client_secret_expires_at


class StartOAuthFlowRequest(KaggleObject):
  r"""
  Attributes:
    client_id (str)
      Client id that is initiating this OAuth flow.
    redirect_uri (str)
      Url to redirect the user after the OAuth flow is complete. For example, if
      you specify https://dataverse.org/auth/kaggle, you will receive a request
      like
      https://dataverse.org/auth/kaggle?code=808f9afcabb3489a8b30353a8ae4dc4b.
      Note that this url must match the allowed urls defined for your OAuth
      client. Also it must be a loopback url for public clients.
    scope (str)
      Set of authorization scopes to restrict the generated tokens. Must be
      specified.
    state (str)
      Random string to protect against CSRF attacks.
    code_challenge (str)
      Hash of the random 'code_verifier' string generated by the caller. The
      client will later send the 'code_verifier' to the backend, which will
      verify its hash against this value (see the 'api/v1/oauth2/exchange'
      (ExchangeOAuthTokenRequest) endpoint). Required for public clients.
    code_challenge_method (str)
      Code challenge method used to hash the 'code_challenge' above. Must be set
      to 'S256', which means the SHA-256 hash of the 'code_verifier', Base64URL
      encoded. Required for public clients.
    response_type (str)
      Type of the OAuth flow completed response. Must be set to 'code', which
      means OAuth code will be sent instead of a refresh token.
    response_mode (str)
      Mode of the OAuth flow completed response. Must be set to 'query', which
      means response will be sent as query string parameters.
    resource (str)
      The 'resource' parameter is not part of the OAuth2 spec, but is sent by
      some clients. We are capturing it here to avoid 'invalid field' errors.
  """

  def __init__(self):
    self._client_id = ""
    self._redirect_uri = ""
    self._scope = ""
    self._state = ""
    self._code_challenge = None
    self._code_challenge_method = None
    self._response_type = ""
    self._response_mode = ""
    self._resource = None
    self._freeze()

  @property
  def client_id(self) -> str:
    """Client id that is initiating this OAuth flow."""
    return self._client_id

  @client_id.setter
  def client_id(self, client_id: str):
    if client_id is None:
      del self.client_id
      return
    if not isinstance(client_id, str):
      raise TypeError('client_id must be of type str')
    self._client_id = client_id

  @property
  def redirect_uri(self) -> str:
    r"""
    Url to redirect the user after the OAuth flow is complete. For example, if
    you specify https://dataverse.org/auth/kaggle, you will receive a request
    like
    https://dataverse.org/auth/kaggle?code=808f9afcabb3489a8b30353a8ae4dc4b.
    Note that this url must match the allowed urls defined for your OAuth
    client. Also it must be a loopback url for public clients.
    """
    return self._redirect_uri

  @redirect_uri.setter
  def redirect_uri(self, redirect_uri: str):
    if redirect_uri is None:
      del self.redirect_uri
      return
    if not isinstance(redirect_uri, str):
      raise TypeError('redirect_uri must be of type str')
    self._redirect_uri = redirect_uri

  @property
  def scope(self) -> str:
    r"""
    Set of authorization scopes to restrict the generated tokens. Must be
    specified.
    """
    return self._scope

  @scope.setter
  def scope(self, scope: str):
    if scope is None:
      del self.scope
      return
    if not isinstance(scope, str):
      raise TypeError('scope must be of type str')
    self._scope = scope

  @property
  def state(self) -> str:
    """Random string to protect against CSRF attacks."""
    return self._state

  @state.setter
  def state(self, state: str):
    if state is None:
      del self.state
      return
    if not isinstance(state, str):
      raise TypeError('state must be of type str')
    self._state = state

  @property
  def code_challenge(self) -> str:
    r"""
    Hash of the random 'code_verifier' string generated by the caller. The
    client will later send the 'code_verifier' to the backend, which will
    verify its hash against this value (see the 'api/v1/oauth2/exchange'
    (ExchangeOAuthTokenRequest) endpoint). Required for public clients.
    """
    return self._code_challenge or ""

  @code_challenge.setter
  def code_challenge(self, code_challenge: Optional[str]):
    if code_challenge is None:
      del self.code_challenge
      return
    if not isinstance(code_challenge, str):
      raise TypeError('code_challenge must be of type str')
    self._code_challenge = code_challenge

  @property
  def code_challenge_method(self) -> str:
    r"""
    Code challenge method used to hash the 'code_challenge' above. Must be set
    to 'S256', which means the SHA-256 hash of the 'code_verifier', Base64URL
    encoded. Required for public clients.
    """
    return self._code_challenge_method or ""

  @code_challenge_method.setter
  def code_challenge_method(self, code_challenge_method: Optional[str]):
    if code_challenge_method is None:
      del self.code_challenge_method
      return
    if not isinstance(code_challenge_method, str):
      raise TypeError('code_challenge_method must be of type str')
    self._code_challenge_method = code_challenge_method

  @property
  def response_type(self) -> str:
    r"""
    Type of the OAuth flow completed response. Must be set to 'code', which
    means OAuth code will be sent instead of a refresh token.
    """
    return self._response_type

  @response_type.setter
  def response_type(self, response_type: str):
    if response_type is None:
      del self.response_type
      return
    if not isinstance(response_type, str):
      raise TypeError('response_type must be of type str')
    self._response_type = response_type

  @property
  def response_mode(self) -> str:
    r"""
    Mode of the OAuth flow completed response. Must be set to 'query', which
    means response will be sent as query string parameters.
    """
    return self._response_mode

  @response_mode.setter
  def response_mode(self, response_mode: str):
    if response_mode is None:
      del self.response_mode
      return
    if not isinstance(response_mode, str):
      raise TypeError('response_mode must be of type str')
    self._response_mode = response_mode

  @property
  def resource(self) -> str:
    r"""
    The 'resource' parameter is not part of the OAuth2 spec, but is sent by
    some clients. We are capturing it here to avoid 'invalid field' errors.
    """
    return self._resource or ""

  @resource.setter
  def resource(self, resource: Optional[str]):
    if resource is None:
      del self.resource
      return
    if not isinstance(resource, str):
      raise TypeError('resource must be of type str')
    self._resource = resource

  def endpoint(self):
    path = '/api/v1/oauth2/authorize'
    return path.format_map(self.to_field_map(self))


ExchangeOAuthTokenRequest._fields = [
  FieldMetadata("code", "code", "_code", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("codeVerifier", "code_verifier", "_code_verifier", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("grantType", "grant_type", "_grant_type", str, "", PredefinedSerializer()),
  FieldMetadata("clientId", "client_id", "_client_id", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("redirectUri", "redirect_uri", "_redirect_uri", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("resource", "resource", "_resource", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("refreshToken", "refresh_token", "_refresh_token", str, None, PredefinedSerializer(), optional=True),
]

ExchangeOAuthTokenResponse._fields = [
  FieldMetadata("accessToken", "access_token", "_access_token", str, "", PredefinedSerializer()),
  FieldMetadata("refreshToken", "refresh_token", "_refresh_token", str, "", PredefinedSerializer()),
  FieldMetadata("tokenType", "token_type", "_token_type", str, "", PredefinedSerializer()),
  FieldMetadata("expiresIn", "expires_in", "_expires_in", int, 0, PredefinedSerializer()),
  FieldMetadata("username", "username", "_username", str, "", PredefinedSerializer()),
  FieldMetadata("userId", "user_id", "_user_id", int, 0, PredefinedSerializer()),
  FieldMetadata("scope", "scope", "_scope", str, None, PredefinedSerializer(), optional=True),
]

IntrospectTokenRequest._fields = [
  FieldMetadata("token", "token", "_token", str, "", PredefinedSerializer()),
]

IntrospectTokenResponse._fields = [
  FieldMetadata("active", "active", "_active", bool, False, PredefinedSerializer()),
  FieldMetadata("clientId", "client_id", "_client_id", str, "", PredefinedSerializer()),
  FieldMetadata("username", "username", "_username", str, "", PredefinedSerializer()),
  FieldMetadata("userId", "user_id", "_user_id", int, None, PredefinedSerializer(), optional=True),
  FieldMetadata("scope", "scope", "_scope", str, "", PredefinedSerializer()),
  FieldMetadata("exp", "exp", "_exp", int, None, PredefinedSerializer(), optional=True),
]

RegisterOAuthClientRequest._fields = [
  FieldMetadata("clientName", "client_name", "_client_name", str, "", PredefinedSerializer()),
  FieldMetadata("redirectUris", "redirect_uris", "_redirect_uris", str, [], ListSerializer(PredefinedSerializer())),
  FieldMetadata("grantTypes", "grant_types", "_grant_types", str, [], ListSerializer(PredefinedSerializer())),
  FieldMetadata("tokenEndpointAuthMethod", "token_endpoint_auth_method", "_token_endpoint_auth_method", str, "", PredefinedSerializer()),
  FieldMetadata("scope", "scope", "_scope", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("codeChallengeMethod", "code_challenge_method", "_code_challenge_method", str, [], ListSerializer(PredefinedSerializer())),
]

RegisterOAuthClientResponse._fields = [
  FieldMetadata("client_id", "client_id", "_client_id", str, "", PredefinedSerializer()),
  FieldMetadata("redirect_uris", "redirect_uris", "_redirect_uris", str, [], ListSerializer(PredefinedSerializer())),
  FieldMetadata("grant_types", "grant_types", "_grant_types", str, [], ListSerializer(PredefinedSerializer())),
  FieldMetadata("response_types", "response_types", "_response_types", str, [], ListSerializer(PredefinedSerializer())),
  FieldMetadata("token_endpoint_auth_method", "token_endpoint_auth_method", "_token_endpoint_auth_method", str, "", PredefinedSerializer()),
  FieldMetadata("scope", "scope", "_scope", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("authorization_url", "authorization_url", "_authorization_url", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("token_url", "token_url", "_token_url", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("client_secret", "client_secret", "_client_secret", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("client_id_issued_at", "client_id_issued_at", "_client_id_issued_at", int, None, PredefinedSerializer(), optional=True),
  FieldMetadata("client_secret_expires_at", "client_secret_expires_at", "_client_secret_expires_at", int, None, PredefinedSerializer(), optional=True),
  FieldMetadata("revocation_url", "revocation_url", "_revocation_url", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("userinfo_url", "userinfo_url", "_userinfo_url", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("code_challenge_methods_supported", "code_challenge_methods_supported", "_code_challenge_methods_supported", str, [], ListSerializer(PredefinedSerializer())),
]

StartOAuthFlowRequest._fields = [
  FieldMetadata("clientId", "client_id", "_client_id", str, "", PredefinedSerializer()),
  FieldMetadata("redirectUri", "redirect_uri", "_redirect_uri", str, "", PredefinedSerializer()),
  FieldMetadata("scope", "scope", "_scope", str, "", PredefinedSerializer()),
  FieldMetadata("state", "state", "_state", str, "", PredefinedSerializer()),
  FieldMetadata("codeChallenge", "code_challenge", "_code_challenge", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("codeChallengeMethod", "code_challenge_method", "_code_challenge_method", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("responseType", "response_type", "_response_type", str, "", PredefinedSerializer()),
  FieldMetadata("responseMode", "response_mode", "_response_mode", str, "", PredefinedSerializer()),
  FieldMetadata("resource", "resource", "_resource", str, None, PredefinedSerializer(), optional=True),
]

