# This file was auto-generated by Fern from our API Definition.

import typing
import httpx
from .backend.core.client_wrapper import SyncClientWrapper
from .backend.admin.client import AdminClient
from .backend.vault.client import VaultClient
from .backend.access_control.client import AccessControlClient
from .backend.scopes.client import ScopesClient
from .backend.apps.client import AppsClient
from .backend.variants.client import VariantsClient
from .backend.evaluations.client import EvaluationsClient
from .backend.human_evaluations.client import HumanEvaluationsClient
from .backend.evaluators.client import EvaluatorsClient
from .backend.testsets.client import TestsetsClient
from .backend.containers.client import ContainersClient
from .backend.environments.client import EnvironmentsClient
from .backend.bases.client import BasesClient
from .backend.configs.client import ConfigsClient
from .backend.observability.client import ObservabilityClient
from .backend.core.request_options import RequestOptions
from .backend.types.list_api_keys_response import ListApiKeysResponse
from .backend.core.pydantic_utilities import parse_obj_as
from json.decoder import JSONDecodeError
from .backend.core.api_error import ApiError
from .backend.core.jsonable_encoder import jsonable_encoder
from .backend.errors.unprocessable_entity_error import UnprocessableEntityError
from .backend.types.http_validation_error import HttpValidationError
from .backend.types.organization import Organization
from .backend.types.organization_output import OrganizationOutput
from .backend.types.invite_request import InviteRequest
from .backend.core.serialization import convert_and_respect_annotation_metadata
from .backend.types.workspace_response import WorkspaceResponse
import datetime as dt
from .backend.types.workspace_role_response import WorkspaceRoleResponse
from .backend.types.permission import Permission
from .backend.core.client_wrapper import AsyncClientWrapper
from .backend.admin.client import AsyncAdminClient
from .backend.vault.client import AsyncVaultClient
from .backend.access_control.client import AsyncAccessControlClient
from .backend.scopes.client import AsyncScopesClient
from .backend.apps.client import AsyncAppsClient
from .backend.variants.client import AsyncVariantsClient
from .backend.evaluations.client import AsyncEvaluationsClient
from .backend.human_evaluations.client import AsyncHumanEvaluationsClient
from .backend.evaluators.client import AsyncEvaluatorsClient
from .backend.testsets.client import AsyncTestsetsClient
from .backend.containers.client import AsyncContainersClient
from .backend.environments.client import AsyncEnvironmentsClient
from .backend.bases.client import AsyncBasesClient
from .backend.configs.client import AsyncConfigsClient
from .backend.observability.client import AsyncObservabilityClient

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class AgentaApi:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : str
        The base url to use for requests from the client.

    api_key : str
    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.Client]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    Examples
    --------
    from agenta import AgentaApi

    client = AgentaApi(
        api_key="YOUR_API_KEY",
        base_url="https://yourhost.com/path/to/api",
    )
    """

    def __init__(
        self,
        *,
        base_url: str,
        api_key: str,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.Client] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 if httpx_client is None else None
        )
        self._client_wrapper = SyncClientWrapper(
            base_url=base_url,
            api_key=api_key,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.Client(
                timeout=_defaulted_timeout, follow_redirects=follow_redirects
            )
            if follow_redirects is not None
            else httpx.Client(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
        )
        self.admin = AdminClient(client_wrapper=self._client_wrapper)
        self.vault = VaultClient(client_wrapper=self._client_wrapper)
        self.access_control = AccessControlClient(client_wrapper=self._client_wrapper)
        self.scopes = ScopesClient(client_wrapper=self._client_wrapper)
        self.apps = AppsClient(client_wrapper=self._client_wrapper)
        self.variants = VariantsClient(client_wrapper=self._client_wrapper)
        self.evaluations = EvaluationsClient(client_wrapper=self._client_wrapper)
        self.human_evaluations = HumanEvaluationsClient(
            client_wrapper=self._client_wrapper
        )
        self.evaluators = EvaluatorsClient(client_wrapper=self._client_wrapper)
        self.testsets = TestsetsClient(client_wrapper=self._client_wrapper)
        self.containers = ContainersClient(client_wrapper=self._client_wrapper)
        self.environments = EnvironmentsClient(client_wrapper=self._client_wrapper)
        self.bases = BasesClient(client_wrapper=self._client_wrapper)
        self.configs = ConfigsClient(client_wrapper=self._client_wrapper)
        self.observability = ObservabilityClient(client_wrapper=self._client_wrapper)

    def list_api_keys(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[ListApiKeysResponse]:
        """
        List all API keys associated with the authenticated user.

        Args:
            request (Request): The incoming request object.

        Returns:
            List[ListAPIKeysResponse]: A list of API Keys associated with the user.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[ListApiKeysResponse]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.list_api_keys()
        """
        _response = self._client_wrapper.httpx_client.request(
            "keys",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[ListApiKeysResponse],
                    parse_obj_as(
                        type_=typing.List[ListApiKeysResponse],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_api_key(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> str:
        """
        Creates an API key for a user.

        Args:
            request (Request): The request object containing the user ID in the request state.

        Returns:
            str: The created API key.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        str
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.create_api_key()
        """
        _response = self._client_wrapper.httpx_client.request(
            "keys",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    str,
                    parse_obj_as(
                        type_=str,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def delete_api_key(
        self,
        key_prefix: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Dict[str, typing.Optional[typing.Any]]:
        """
        Delete an API key with the given key prefix for the authenticated user.

        Args:
            key_prefix (str): The prefix of the API key to be deleted.
            request (Request): The incoming request object.

        Returns:
            dict: A dictionary containing a success message upon successful deletion.

        Raises:
            HTTPException: If the API key is not found or does not belong to the user.

        Parameters
        ----------
        key_prefix : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Dict[str, typing.Optional[typing.Any]]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.delete_api_key(
            key_prefix="key_prefix",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"keys/{jsonable_encoder(key_prefix)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, typing.Optional[typing.Any]],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Optional[typing.Any]],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def validate_api_key(
        self,
        key_prefix: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> bool:
        """
        This Function is called by the CLI and is used to validate an API key provided by a user in agenta init setup.
        Returns:
            bool: True. If the request reaches this point, the API key is valid.

        Parameters
        ----------
        key_prefix : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        bool
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.validate_api_key(
            key_prefix="key_prefix",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"keys/{jsonable_encoder(key_prefix)}/validate",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    bool,
                    parse_obj_as(
                        type_=bool,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def list_organizations(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Organization]:
        """
        Returns a list of organizations associated with the user's session.

        Args:
            stoken_session (SessionContainer): The user's session token.

        Returns:
            list[Organization]: A list of organizations associated with the user's session.

        Raises:
            HTTPException: If there is an error retrieving the organizations from the database.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Organization]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.list_organizations()
        """
        _response = self._client_wrapper.httpx_client.request(
            "organizations",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[Organization],
                    parse_obj_as(
                        type_=typing.List[Organization],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_organization(
        self,
        *,
        name: str,
        owner: str,
        description: typing.Optional[str] = OMIT,
        type: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        name : str

        owner : str

        description : typing.Optional[str]

        type : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.create_organization(
            name="name",
            owner="owner",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "organizations",
            method="POST",
            json={
                "name": name,
                "owner": owner,
                "description": description,
                "type": type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_own_org(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> OrganizationOutput:
        """
        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        OrganizationOutput
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.get_own_org()
        """
        _response = self._client_wrapper.httpx_client.request(
            "organizations/own",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    OrganizationOutput,
                    parse_obj_as(
                        type_=OrganizationOutput,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def fetch_organization_details(
        self, org_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[typing.Any]:
        """
        Get an organization's details.

        Raises:
            HTTPException: _description_
            Permission Denied

        Returns:
            OrganizationDB Instance

        Parameters
        ----------
        org_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.fetch_organization_details(
            org_id="org_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_organization(
        self,
        org_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        updated_at: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        org_id : str

        name : typing.Optional[str]

        description : typing.Optional[str]

        updated_at : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.update_organization(
            org_id="org_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}",
            method="PUT",
            json={
                "name": name,
                "description": description,
                "updated_at": updated_at,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def invite_user_to_workspace(
        self,
        org_id: str,
        workspace_id: str,
        *,
        request: typing.Sequence[InviteRequest],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        org_id : str

        workspace_id : str

        request : typing.Sequence[InviteRequest]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi, InviteRequest

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.invite_user_to_workspace(
            org_id="org_id",
            workspace_id="workspace_id",
            request=[
                InviteRequest(
                    email="email",
                    roles=["roles"],
                )
            ],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces/{jsonable_encoder(workspace_id)}/invite",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request,
                annotation=typing.Sequence[InviteRequest],
                direction="write",
            ),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def resend_invitation(
        self,
        org_id: str,
        workspace_id: str,
        *,
        email: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Resend an invitation to a user to an Organization.

        Raises:
            HTTPException: _description_; status_code: 500
            HTTPException: Invitation not found or has expired; status_code: 400
            HTTPException: You already belong to this organization; status_code: 400

        Returns:
            JSONResponse: Resent invitation to user; status_code: 200

        Parameters
        ----------
        org_id : str

        workspace_id : str

        email : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.resend_invitation(
            org_id="org_id",
            workspace_id="workspace_id",
            email="email",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces/{jsonable_encoder(workspace_id)}/invite/resend",
            method="POST",
            json={
                "email": email,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def accept_invitation(
        self,
        org_id: str,
        workspace_id: str,
        *,
        project_id: str,
        token: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Accept an invitation to a workspace.

        Raises:
            HTTPException: _description_; status_code: 500
            HTTPException: Invitation not found or has expired; status_code: 400
            HTTPException: You already belong to this organization; status_code: 400

        Returns:
            JSONResponse: Accepted invitation to workspace; status_code: 200

        Parameters
        ----------
        org_id : str

        workspace_id : str

        project_id : str

        token : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.accept_invitation(
            org_id="org_id",
            workspace_id="workspace_id",
            project_id="project_id",
            token="token",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces/{jsonable_encoder(workspace_id)}/invite/accept",
            method="POST",
            params={
                "project_id": project_id,
            },
            json={
                "token": token,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def create_workspace(
        self,
        org_id: str,
        *,
        name: str,
        description: typing.Optional[str] = OMIT,
        type: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> WorkspaceResponse:
        """
        Parameters
        ----------
        org_id : str

        name : str

        description : typing.Optional[str]

        type : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        WorkspaceResponse
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.create_workspace(
            org_id="org_id",
            name="name",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces",
            method="POST",
            json={
                "name": name,
                "description": description,
                "type": type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    WorkspaceResponse,
                    parse_obj_as(
                        type_=WorkspaceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def update_workspace(
        self,
        org_id: str,
        workspace_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        updated_at: typing.Optional[dt.datetime] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> WorkspaceResponse:
        """
        Parameters
        ----------
        org_id : str

        workspace_id : str

        name : typing.Optional[str]

        description : typing.Optional[str]

        updated_at : typing.Optional[dt.datetime]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        WorkspaceResponse
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.update_workspace(
            org_id="org_id",
            workspace_id="workspace_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces/{jsonable_encoder(workspace_id)}",
            method="PUT",
            json={
                "name": name,
                "description": description,
                "updated_at": updated_at,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    WorkspaceResponse,
                    parse_obj_as(
                        type_=WorkspaceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_all_workspace_roles(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[WorkspaceRoleResponse]:
        """
        Get all workspace roles.

        Returns a list of all available workspace roles.

        Returns:
            List[WorkspaceRoleResponse]: A list of WorkspaceRole objects representing the available workspace roles.

        Raises:
            HTTPException: If an error occurs while retrieving the workspace roles.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[WorkspaceRoleResponse]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.get_all_workspace_roles()
        """
        _response = self._client_wrapper.httpx_client.request(
            "workspaces/roles",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[WorkspaceRoleResponse],
                    parse_obj_as(
                        type_=typing.List[WorkspaceRoleResponse],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def get_all_workspace_permissions(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Permission]:
        """
        Get all workspace permissions.

        Returns a list of all available workspace permissions.

        Returns:
            List[Permission]: A list of Permission objects representing the available workspace permissions.

        Raises:
            HTTPException: If there is an error retrieving the workspace permissions.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Permission]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.get_all_workspace_permissions()
        """
        _response = self._client_wrapper.httpx_client.request(
            "workspaces/permissions",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[Permission],
                    parse_obj_as(
                        type_=typing.List[Permission],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def assign_role_to_user(
        self,
        workspace_id: str,
        *,
        email: str,
        organization_id: str,
        role: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> bool:
        """
        Assigns a role to a user in a workspace.

        Args:
            payload (UserRole): The payload containing the organization id, user email, and role to assign.
            workspace_id (str): The ID of the workspace.
            request (Request): The FastAPI request object.

        Returns:
            bool: True if the role was successfully assigned, False otherwise.

        Raises:
            HTTPException: If the user does not have permission to perform this action.
            HTTPException: If there is an error assigning the role to the user.

        Parameters
        ----------
        workspace_id : str

        email : str

        organization_id : str

        role : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        bool
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.assign_role_to_user(
            workspace_id="workspace_id",
            email="email",
            organization_id="organization_id",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"workspaces/{jsonable_encoder(workspace_id)}/roles",
            method="POST",
            json={
                "email": email,
                "organization_id": organization_id,
                "role": role,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    bool,
                    parse_obj_as(
                        type_=bool,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def unassign_role_from_user(
        self,
        workspace_id: str,
        *,
        email: str,
        org_id: str,
        role: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Delete a role assignment from a user in a workspace.

        Args:
            workspace_id (str): The ID of the workspace.
            email (str): The email of the user to remove the role from.
            org_id (str): The ID of the organization.
            role (str): The role to remove from the user.
            request (Request): The FastAPI request object.

        Returns:
            bool: True if the role assignment was successfully deleted.

        Raises:
            HTTPException: If there is an error in the request or the user does not have permission to perform the action.
            HTTPException: If there is an error in updating the user's roles.

        Parameters
        ----------
        workspace_id : str

        email : str

        org_id : str

        role : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.unassign_role_from_user(
            workspace_id="workspace_id",
            email="email",
            org_id="org_id",
            role="role",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"workspaces/{jsonable_encoder(workspace_id)}/roles",
            method="DELETE",
            params={
                "email": email,
                "org_id": org_id,
                "role": role,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def remove_user_from_workspace(
        self,
        workspace_id: str,
        *,
        org_id: str,
        email: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> WorkspaceResponse:
        """
        Remove a user from a workspace.

        Parameters:
        - payload (UserRole): The payload containing the user email and organization ID.
        - workspace_id (str): The ID of the workspace.
        - request (Request): The FastAPI request object.

        Returns:
        - WorkspaceResponse: The updated workspace.

        Raises:
        - HTTPException: If the user does not have permission to perform this action.
        - HTTPException: If there is an error during the removal process.

        Parameters
        ----------
        workspace_id : str

        org_id : str

        email : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        WorkspaceResponse
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.remove_user_from_workspace(
            workspace_id="workspace_id",
            org_id="org_id",
            email="email",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"workspaces/{jsonable_encoder(workspace_id)}/users",
            method="DELETE",
            params={
                "org_id": org_id,
                "email": email,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    WorkspaceResponse,
                    parse_obj_as(
                        type_=WorkspaceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def health_check(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.health_check()
        """
        _response = self._client_wrapper.httpx_client.request(
            "health",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def fetch_user_profile(
        self,
        *,
        user_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        user_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        from agenta import AgentaApi

        client = AgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )
        client.fetch_user_profile()
        """
        _response = self._client_wrapper.httpx_client.request(
            "profile",
            method="GET",
            params={
                "user_id": user_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncAgentaApi:
    """
    Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.

    Parameters
    ----------
    base_url : str
        The base url to use for requests from the client.

    api_key : str
    timeout : typing.Optional[float]
        The timeout to be used, in seconds, for requests. By default the timeout is 60 seconds, unless a custom httpx client is used, in which case this default is not enforced.

    follow_redirects : typing.Optional[bool]
        Whether the default httpx client follows redirects or not, this is irrelevant if a custom httpx client is passed in.

    httpx_client : typing.Optional[httpx.AsyncClient]
        The httpx client to use for making requests, a preconfigured client is used by default, however this is useful should you want to pass in any custom httpx configuration.

    Examples
    --------
    from agenta import AsyncAgentaApi

    client = AsyncAgentaApi(
        api_key="YOUR_API_KEY",
        base_url="https://yourhost.com/path/to/api",
    )
    """

    def __init__(
        self,
        *,
        base_url: str,
        api_key: str,
        timeout: typing.Optional[float] = None,
        follow_redirects: typing.Optional[bool] = True,
        httpx_client: typing.Optional[httpx.AsyncClient] = None,
    ):
        _defaulted_timeout = (
            timeout if timeout is not None else 60 if httpx_client is None else None
        )
        self._client_wrapper = AsyncClientWrapper(
            base_url=base_url,
            api_key=api_key,
            httpx_client=httpx_client
            if httpx_client is not None
            else httpx.AsyncClient(
                timeout=_defaulted_timeout, follow_redirects=follow_redirects
            )
            if follow_redirects is not None
            else httpx.AsyncClient(timeout=_defaulted_timeout),
            timeout=_defaulted_timeout,
        )
        self.admin = AsyncAdminClient(client_wrapper=self._client_wrapper)
        self.vault = AsyncVaultClient(client_wrapper=self._client_wrapper)
        self.access_control = AsyncAccessControlClient(
            client_wrapper=self._client_wrapper
        )
        self.scopes = AsyncScopesClient(client_wrapper=self._client_wrapper)
        self.apps = AsyncAppsClient(client_wrapper=self._client_wrapper)
        self.variants = AsyncVariantsClient(client_wrapper=self._client_wrapper)
        self.evaluations = AsyncEvaluationsClient(client_wrapper=self._client_wrapper)
        self.human_evaluations = AsyncHumanEvaluationsClient(
            client_wrapper=self._client_wrapper
        )
        self.evaluators = AsyncEvaluatorsClient(client_wrapper=self._client_wrapper)
        self.testsets = AsyncTestsetsClient(client_wrapper=self._client_wrapper)
        self.containers = AsyncContainersClient(client_wrapper=self._client_wrapper)
        self.environments = AsyncEnvironmentsClient(client_wrapper=self._client_wrapper)
        self.bases = AsyncBasesClient(client_wrapper=self._client_wrapper)
        self.configs = AsyncConfigsClient(client_wrapper=self._client_wrapper)
        self.observability = AsyncObservabilityClient(
            client_wrapper=self._client_wrapper
        )

    async def list_api_keys(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[ListApiKeysResponse]:
        """
        List all API keys associated with the authenticated user.

        Args:
            request (Request): The incoming request object.

        Returns:
            List[ListAPIKeysResponse]: A list of API Keys associated with the user.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[ListApiKeysResponse]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.list_api_keys()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "keys",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[ListApiKeysResponse],
                    parse_obj_as(
                        type_=typing.List[ListApiKeysResponse],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_api_key(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> str:
        """
        Creates an API key for a user.

        Args:
            request (Request): The request object containing the user ID in the request state.

        Returns:
            str: The created API key.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        str
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.create_api_key()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "keys",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    str,
                    parse_obj_as(
                        type_=str,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def delete_api_key(
        self,
        key_prefix: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Dict[str, typing.Optional[typing.Any]]:
        """
        Delete an API key with the given key prefix for the authenticated user.

        Args:
            key_prefix (str): The prefix of the API key to be deleted.
            request (Request): The incoming request object.

        Returns:
            dict: A dictionary containing a success message upon successful deletion.

        Raises:
            HTTPException: If the API key is not found or does not belong to the user.

        Parameters
        ----------
        key_prefix : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Dict[str, typing.Optional[typing.Any]]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.delete_api_key(
                key_prefix="key_prefix",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"keys/{jsonable_encoder(key_prefix)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Dict[str, typing.Optional[typing.Any]],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Optional[typing.Any]],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def validate_api_key(
        self,
        key_prefix: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> bool:
        """
        This Function is called by the CLI and is used to validate an API key provided by a user in agenta init setup.
        Returns:
            bool: True. If the request reaches this point, the API key is valid.

        Parameters
        ----------
        key_prefix : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        bool
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.validate_api_key(
                key_prefix="key_prefix",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"keys/{jsonable_encoder(key_prefix)}/validate",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    bool,
                    parse_obj_as(
                        type_=bool,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def list_organizations(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Organization]:
        """
        Returns a list of organizations associated with the user's session.

        Args:
            stoken_session (SessionContainer): The user's session token.

        Returns:
            list[Organization]: A list of organizations associated with the user's session.

        Raises:
            HTTPException: If there is an error retrieving the organizations from the database.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Organization]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.list_organizations()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "organizations",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[Organization],
                    parse_obj_as(
                        type_=typing.List[Organization],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_organization(
        self,
        *,
        name: str,
        owner: str,
        description: typing.Optional[str] = OMIT,
        type: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        name : str

        owner : str

        description : typing.Optional[str]

        type : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.create_organization(
                name="name",
                owner="owner",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "organizations",
            method="POST",
            json={
                "name": name,
                "owner": owner,
                "description": description,
                "type": type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_own_org(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> OrganizationOutput:
        """
        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        OrganizationOutput
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.get_own_org()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "organizations/own",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    OrganizationOutput,
                    parse_obj_as(
                        type_=OrganizationOutput,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def fetch_organization_details(
        self, org_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[typing.Any]:
        """
        Get an organization's details.

        Raises:
            HTTPException: _description_
            Permission Denied

        Returns:
            OrganizationDB Instance

        Parameters
        ----------
        org_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.fetch_organization_details(
                org_id="org_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_organization(
        self,
        org_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        updated_at: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        org_id : str

        name : typing.Optional[str]

        description : typing.Optional[str]

        updated_at : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.update_organization(
                org_id="org_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}",
            method="PUT",
            json={
                "name": name,
                "description": description,
                "updated_at": updated_at,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def invite_user_to_workspace(
        self,
        org_id: str,
        workspace_id: str,
        *,
        request: typing.Sequence[InviteRequest],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        org_id : str

        workspace_id : str

        request : typing.Sequence[InviteRequest]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi, InviteRequest

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.invite_user_to_workspace(
                org_id="org_id",
                workspace_id="workspace_id",
                request=[
                    InviteRequest(
                        email="email",
                        roles=["roles"],
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces/{jsonable_encoder(workspace_id)}/invite",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request,
                annotation=typing.Sequence[InviteRequest],
                direction="write",
            ),
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def resend_invitation(
        self,
        org_id: str,
        workspace_id: str,
        *,
        email: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Resend an invitation to a user to an Organization.

        Raises:
            HTTPException: _description_; status_code: 500
            HTTPException: Invitation not found or has expired; status_code: 400
            HTTPException: You already belong to this organization; status_code: 400

        Returns:
            JSONResponse: Resent invitation to user; status_code: 200

        Parameters
        ----------
        org_id : str

        workspace_id : str

        email : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.resend_invitation(
                org_id="org_id",
                workspace_id="workspace_id",
                email="email",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces/{jsonable_encoder(workspace_id)}/invite/resend",
            method="POST",
            json={
                "email": email,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def accept_invitation(
        self,
        org_id: str,
        workspace_id: str,
        *,
        project_id: str,
        token: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Accept an invitation to a workspace.

        Raises:
            HTTPException: _description_; status_code: 500
            HTTPException: Invitation not found or has expired; status_code: 400
            HTTPException: You already belong to this organization; status_code: 400

        Returns:
            JSONResponse: Accepted invitation to workspace; status_code: 200

        Parameters
        ----------
        org_id : str

        workspace_id : str

        project_id : str

        token : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.accept_invitation(
                org_id="org_id",
                workspace_id="workspace_id",
                project_id="project_id",
                token="token",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces/{jsonable_encoder(workspace_id)}/invite/accept",
            method="POST",
            params={
                "project_id": project_id,
            },
            json={
                "token": token,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def create_workspace(
        self,
        org_id: str,
        *,
        name: str,
        description: typing.Optional[str] = OMIT,
        type: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> WorkspaceResponse:
        """
        Parameters
        ----------
        org_id : str

        name : str

        description : typing.Optional[str]

        type : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        WorkspaceResponse
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.create_workspace(
                org_id="org_id",
                name="name",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces",
            method="POST",
            json={
                "name": name,
                "description": description,
                "type": type,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    WorkspaceResponse,
                    parse_obj_as(
                        type_=WorkspaceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def update_workspace(
        self,
        org_id: str,
        workspace_id: str,
        *,
        name: typing.Optional[str] = OMIT,
        description: typing.Optional[str] = OMIT,
        updated_at: typing.Optional[dt.datetime] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> WorkspaceResponse:
        """
        Parameters
        ----------
        org_id : str

        workspace_id : str

        name : typing.Optional[str]

        description : typing.Optional[str]

        updated_at : typing.Optional[dt.datetime]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        WorkspaceResponse
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.update_workspace(
                org_id="org_id",
                workspace_id="workspace_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"organizations/{jsonable_encoder(org_id)}/workspaces/{jsonable_encoder(workspace_id)}",
            method="PUT",
            json={
                "name": name,
                "description": description,
                "updated_at": updated_at,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    WorkspaceResponse,
                    parse_obj_as(
                        type_=WorkspaceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_all_workspace_roles(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[WorkspaceRoleResponse]:
        """
        Get all workspace roles.

        Returns a list of all available workspace roles.

        Returns:
            List[WorkspaceRoleResponse]: A list of WorkspaceRole objects representing the available workspace roles.

        Raises:
            HTTPException: If an error occurs while retrieving the workspace roles.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[WorkspaceRoleResponse]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.get_all_workspace_roles()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "workspaces/roles",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[WorkspaceRoleResponse],
                    parse_obj_as(
                        type_=typing.List[WorkspaceRoleResponse],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def get_all_workspace_permissions(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Permission]:
        """
        Get all workspace permissions.

        Returns a list of all available workspace permissions.

        Returns:
            List[Permission]: A list of Permission objects representing the available workspace permissions.

        Raises:
            HTTPException: If there is an error retrieving the workspace permissions.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.List[Permission]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.get_all_workspace_permissions()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "workspaces/permissions",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.List[Permission],
                    parse_obj_as(
                        type_=typing.List[Permission],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def assign_role_to_user(
        self,
        workspace_id: str,
        *,
        email: str,
        organization_id: str,
        role: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> bool:
        """
        Assigns a role to a user in a workspace.

        Args:
            payload (UserRole): The payload containing the organization id, user email, and role to assign.
            workspace_id (str): The ID of the workspace.
            request (Request): The FastAPI request object.

        Returns:
            bool: True if the role was successfully assigned, False otherwise.

        Raises:
            HTTPException: If the user does not have permission to perform this action.
            HTTPException: If there is an error assigning the role to the user.

        Parameters
        ----------
        workspace_id : str

        email : str

        organization_id : str

        role : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        bool
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.assign_role_to_user(
                workspace_id="workspace_id",
                email="email",
                organization_id="organization_id",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"workspaces/{jsonable_encoder(workspace_id)}/roles",
            method="POST",
            json={
                "email": email,
                "organization_id": organization_id,
                "role": role,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    bool,
                    parse_obj_as(
                        type_=bool,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def unassign_role_from_user(
        self,
        workspace_id: str,
        *,
        email: str,
        org_id: str,
        role: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Delete a role assignment from a user in a workspace.

        Args:
            workspace_id (str): The ID of the workspace.
            email (str): The email of the user to remove the role from.
            org_id (str): The ID of the organization.
            role (str): The role to remove from the user.
            request (Request): The FastAPI request object.

        Returns:
            bool: True if the role assignment was successfully deleted.

        Raises:
            HTTPException: If there is an error in the request or the user does not have permission to perform the action.
            HTTPException: If there is an error in updating the user's roles.

        Parameters
        ----------
        workspace_id : str

        email : str

        org_id : str

        role : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.unassign_role_from_user(
                workspace_id="workspace_id",
                email="email",
                org_id="org_id",
                role="role",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"workspaces/{jsonable_encoder(workspace_id)}/roles",
            method="DELETE",
            params={
                "email": email,
                "org_id": org_id,
                "role": role,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def remove_user_from_workspace(
        self,
        workspace_id: str,
        *,
        org_id: str,
        email: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> WorkspaceResponse:
        """
        Remove a user from a workspace.

        Parameters:
        - payload (UserRole): The payload containing the user email and organization ID.
        - workspace_id (str): The ID of the workspace.
        - request (Request): The FastAPI request object.

        Returns:
        - WorkspaceResponse: The updated workspace.

        Raises:
        - HTTPException: If the user does not have permission to perform this action.
        - HTTPException: If there is an error during the removal process.

        Parameters
        ----------
        workspace_id : str

        org_id : str

        email : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        WorkspaceResponse
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.remove_user_from_workspace(
                workspace_id="workspace_id",
                org_id="org_id",
                email="email",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"workspaces/{jsonable_encoder(workspace_id)}/users",
            method="DELETE",
            params={
                "org_id": org_id,
                "email": email,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    WorkspaceResponse,
                    parse_obj_as(
                        type_=WorkspaceResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def health_check(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.health_check()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "health",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def fetch_user_profile(
        self,
        *,
        user_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Optional[typing.Any]:
        """
        Parameters
        ----------
        user_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Optional[typing.Any]
            Successful Response

        Examples
        --------
        import asyncio

        from agenta import AsyncAgentaApi

        client = AsyncAgentaApi(
            api_key="YOUR_API_KEY",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.fetch_user_profile()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "profile",
            method="GET",
            params={
                "user_id": user_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
