"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from .basesdk import BaseSDK
from .httpclient import AsyncHttpClient, ClientOwner, HttpClient, close_clients
from .sdkconfiguration import SDKConfiguration
from .utils.logger import Logger, get_default_logger
from .utils.retries import RetryConfig
import httpx
import importlib
from novu_py import models, utils
from novu_py._hooks import HookContext, SDKHooks
from novu_py.types import OptionalNullable, UNSET
from novu_py.utils import get_security_from_env
from novu_py.utils.unmarshal_json_response import unmarshal_json_response
import sys
from typing import (
    Any,
    Callable,
    Dict,
    List,
    Mapping,
    Optional,
    TYPE_CHECKING,
    Union,
    cast,
)
import weakref

if TYPE_CHECKING:
    from novu_py.activity import Activity
    from novu_py.channel_connections import ChannelConnections
    from novu_py.channel_endpoints import ChannelEndpoints
    from novu_py.contexts import Contexts
    from novu_py.environments import Environments
    from novu_py.integrations import Integrations
    from novu_py.layouts import Layouts
    from novu_py.messages import Messages
    from novu_py.notifications import Notifications
    from novu_py.subscribers import Subscribers
    from novu_py.topics import Topics
    from novu_py.translations import Translations
    from novu_py.workflows import Workflows


class Novu(BaseSDK):
    r"""Novu API: Novu REST API. Please see https://docs.novu.co/api-reference for more details.
    https://docs.novu.co - Novu Documentation
    """

    contexts: "Contexts"
    environments: "Environments"
    r"""Environments allow you to manage different stages of your application development lifecycle. Each environment has its own set of API keys and configurations, enabling you to separate development, staging, and production workflows.
    https://docs.novu.co/platform/environments
    """
    activity: "Activity"
    layouts: "Layouts"
    r"""Layouts are reusable wrappers for your email notifications.
    https://docs.novu.co/platform/workflow/layouts
    """
    subscribers: "Subscribers"
    r"""A subscriber in Novu represents someone who should receive a message. A subscriber's profile information contains important attributes about the subscriber that will be used in messages (name, email). The subscriber object can contain other key-value pairs that can be used to further personalize your messages.
    https://docs.novu.co/subscribers/subscribers
    """
    topics: "Topics"
    r"""Topics are a way to group subscribers together so that they can be notified of events at once. A topic is identified by a custom key. This can be helpful for things like sending out marketing emails or notifying users of new features. Topics can also be used to send notifications to the subscribers who have been grouped together based on their interests, location, activities and much more.
    https://docs.novu.co/subscribers/topics
    """
    translations: "Translations"
    r"""Used to localize your notifications to different languages.
    https://docs.novu.co/platform/workflow/translations
    """
    workflows: "Workflows"
    r"""All notifications are sent via a workflow. Each workflow acts as a container for the logic and blueprint that are associated with a type of notification in your system.
    https://docs.novu.co/workflows
    """
    channel_connections: "ChannelConnections"
    channel_endpoints: "ChannelEndpoints"
    integrations: "Integrations"
    r"""With the help of the Integration Store, you can easily integrate your favorite delivery provider. During the runtime of the API, the Integrations Store is responsible for storing the configurations of all the providers.
    https://docs.novu.co/platform/integrations/overview
    """
    messages: "Messages"
    r"""A message in Novu represents a notification delivered to a recipient on a particular channel. Messages contain information about the request that triggered its delivery, a view of the data sent to the recipient, and a timeline of its lifecycle events. Learn more about messages.
    https://docs.novu.co/workflows/messages
    """
    notifications: "Notifications"
    _sub_sdk_map = {
        "contexts": ("novu_py.contexts", "Contexts"),
        "environments": ("novu_py.environments", "Environments"),
        "activity": ("novu_py.activity", "Activity"),
        "layouts": ("novu_py.layouts", "Layouts"),
        "subscribers": ("novu_py.subscribers", "Subscribers"),
        "topics": ("novu_py.topics", "Topics"),
        "translations": ("novu_py.translations", "Translations"),
        "workflows": ("novu_py.workflows", "Workflows"),
        "channel_connections": ("novu_py.channel_connections", "ChannelConnections"),
        "channel_endpoints": ("novu_py.channel_endpoints", "ChannelEndpoints"),
        "integrations": ("novu_py.integrations", "Integrations"),
        "messages": ("novu_py.messages", "Messages"),
        "notifications": ("novu_py.notifications", "Notifications"),
    }

    def __init__(
        self,
        secret_key: Optional[Union[Optional[str], Callable[[], Optional[str]]]] = None,
        server_idx: Optional[int] = None,
        server_url: Optional[str] = None,
        url_params: Optional[Dict[str, str]] = None,
        client: Optional[HttpClient] = None,
        async_client: Optional[AsyncHttpClient] = None,
        retry_config: OptionalNullable[RetryConfig] = UNSET,
        timeout_ms: Optional[int] = None,
        debug_logger: Optional[Logger] = None,
    ) -> None:
        r"""Instantiates the SDK configuring it with the provided parameters.

        :param secret_key: The secret_key required for authentication
        :param server_idx: The index of the server to use for all methods
        :param server_url: The server URL to use for all methods
        :param url_params: Parameters to optionally template the server URL with
        :param client: The HTTP client to use for all synchronous methods
        :param async_client: The Async HTTP client to use for all asynchronous methods
        :param retry_config: The retry configuration to use for all supported methods
        :param timeout_ms: Optional request timeout applied to each operation in milliseconds
        """
        client_supplied = True
        if client is None:
            client = httpx.Client(follow_redirects=True)
            client_supplied = False

        assert issubclass(
            type(client), HttpClient
        ), "The provided client must implement the HttpClient protocol."

        async_client_supplied = True
        if async_client is None:
            async_client = httpx.AsyncClient(follow_redirects=True)
            async_client_supplied = False

        if debug_logger is None:
            debug_logger = get_default_logger()

        assert issubclass(
            type(async_client), AsyncHttpClient
        ), "The provided async_client must implement the AsyncHttpClient protocol."

        security: Any = None
        if callable(secret_key):
            # pylint: disable=unnecessary-lambda-assignment
            security = lambda: models.Security(secret_key=secret_key())
        else:
            security = models.Security(secret_key=secret_key)

        if server_url is not None:
            if url_params is not None:
                server_url = utils.template_url(server_url, url_params)

        BaseSDK.__init__(
            self,
            SDKConfiguration(
                client=client,
                client_supplied=client_supplied,
                async_client=async_client,
                async_client_supplied=async_client_supplied,
                security=security,
                server_url=server_url,
                server_idx=server_idx,
                retry_config=retry_config,
                timeout_ms=timeout_ms,
                debug_logger=debug_logger,
            ),
            parent_ref=self,
        )

        hooks = SDKHooks()

        # pylint: disable=protected-access
        self.sdk_configuration.__dict__["_hooks"] = hooks

        current_server_url, *_ = self.sdk_configuration.get_server_details()
        server_url, self.sdk_configuration.client = hooks.sdk_init(
            current_server_url, client
        )
        if current_server_url != server_url:
            self.sdk_configuration.server_url = server_url

        weakref.finalize(
            self,
            close_clients,
            cast(ClientOwner, self.sdk_configuration),
            self.sdk_configuration.client,
            self.sdk_configuration.client_supplied,
            self.sdk_configuration.async_client,
            self.sdk_configuration.async_client_supplied,
        )

    def dynamic_import(self, modname, retries=3):
        for attempt in range(retries):
            try:
                return importlib.import_module(modname)
            except KeyError:
                # Clear any half-initialized module and retry
                sys.modules.pop(modname, None)
                if attempt == retries - 1:
                    break
        raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")

    def __getattr__(self, name: str):
        if name in self._sub_sdk_map:
            module_path, class_name = self._sub_sdk_map[name]
            try:
                module = self.dynamic_import(module_path)
                klass = getattr(module, class_name)
                instance = klass(self.sdk_configuration, parent_ref=self)
                setattr(self, name, instance)
                return instance
            except ImportError as e:
                raise AttributeError(
                    f"Failed to import module {module_path} for attribute {name}: {e}"
                ) from e
            except AttributeError as e:
                raise AttributeError(
                    f"Failed to find class {class_name} in module {module_path} for attribute {name}: {e}"
                ) from e

        raise AttributeError(
            f"'{type(self).__name__}' object has no attribute '{name}'"
        )

    def __dir__(self):
        default_attrs = list(super().__dir__())
        lazy_attrs = list(self._sub_sdk_map.keys())
        return sorted(list(set(default_attrs + lazy_attrs)))

    def __enter__(self):
        return self

    async def __aenter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if (
            self.sdk_configuration.client is not None
            and not self.sdk_configuration.client_supplied
        ):
            self.sdk_configuration.client.close()
        self.sdk_configuration.client = None

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        if (
            self.sdk_configuration.async_client is not None
            and not self.sdk_configuration.async_client_supplied
        ):
            await self.sdk_configuration.async_client.aclose()
        self.sdk_configuration.async_client = None

    def trigger(
        self,
        *,
        trigger_event_request_dto: Union[
            models.TriggerEventRequestDto, models.TriggerEventRequestDtoTypedDict
        ],
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.EventsControllerTriggerResponse:
        r"""Trigger event

        Trigger event is the main (and only) way to send notifications to subscribers. The trigger identifier is used to match the particular workflow associated with it. Maximum number of recipients can be 100. Additional information can be passed according the body interface below.
        To prevent duplicate triggers, you can optionally pass a **transactionId** in the request body. If the same **transactionId** is used again, the trigger will be ignored. The retention period depends on your billing tier.

        :param trigger_event_request_dto:
        :param idempotency_key: A header for idempotency purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.EventsControllerTriggerRequest(
            idempotency_key=idempotency_key,
            trigger_event_request_dto=utils.get_pydantic_model(
                trigger_event_request_dto, models.TriggerEventRequestDto
            ),
        )

        req = self._build_request(
            method="POST",
            path="/v1/events/trigger",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.trigger_event_request_dto,
                False,
                False,
                "json",
                models.TriggerEventRequestDto,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(1000, 30000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "409", "429", "5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="EventsController_trigger",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "413",
                "414",
                "415",
                "422",
                "429",
                "4XX",
                "500",
                "503",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return models.EventsControllerTriggerResponse(
                result=unmarshal_json_response(
                    models.TriggerEventResponseDto, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.PayloadValidationExceptionDtoData, http_res
            )
            raise models.PayloadValidationExceptionDto(response_data, http_res)
        if utils.match_response(http_res, "414", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(
            http_res,
            ["401", "403", "404", "405", "409", "413", "415"],
            "application/json",
        ):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.ValidationErrorDtoData, http_res
            )
            raise models.ValidationErrorDto(response_data, http_res)
        if utils.match_response(http_res, "429", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "503", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    async def trigger_async(
        self,
        *,
        trigger_event_request_dto: Union[
            models.TriggerEventRequestDto, models.TriggerEventRequestDtoTypedDict
        ],
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.EventsControllerTriggerResponse:
        r"""Trigger event

        Trigger event is the main (and only) way to send notifications to subscribers. The trigger identifier is used to match the particular workflow associated with it. Maximum number of recipients can be 100. Additional information can be passed according the body interface below.
        To prevent duplicate triggers, you can optionally pass a **transactionId** in the request body. If the same **transactionId** is used again, the trigger will be ignored. The retention period depends on your billing tier.

        :param trigger_event_request_dto:
        :param idempotency_key: A header for idempotency purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.EventsControllerTriggerRequest(
            idempotency_key=idempotency_key,
            trigger_event_request_dto=utils.get_pydantic_model(
                trigger_event_request_dto, models.TriggerEventRequestDto
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/v1/events/trigger",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.trigger_event_request_dto,
                False,
                False,
                "json",
                models.TriggerEventRequestDto,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(1000, 30000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "409", "429", "5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="EventsController_trigger",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "413",
                "414",
                "415",
                "422",
                "429",
                "4XX",
                "500",
                "503",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return models.EventsControllerTriggerResponse(
                result=unmarshal_json_response(
                    models.TriggerEventResponseDto, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.PayloadValidationExceptionDtoData, http_res
            )
            raise models.PayloadValidationExceptionDto(response_data, http_res)
        if utils.match_response(http_res, "414", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(
            http_res,
            ["401", "403", "404", "405", "409", "413", "415"],
            "application/json",
        ):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.ValidationErrorDtoData, http_res
            )
            raise models.ValidationErrorDto(response_data, http_res)
        if utils.match_response(http_res, "429", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "503", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    def cancel(
        self,
        *,
        transaction_id: str,
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.EventsControllerCancelResponse:
        r"""Cancel triggered event


        Using a previously generated transactionId during the event trigger,
        will cancel any active or pending workflows. This is useful to cancel active digests, delays etc...


        :param transaction_id:
        :param idempotency_key: A header for idempotency purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.EventsControllerCancelRequest(
            transaction_id=transaction_id,
            idempotency_key=idempotency_key,
        )

        req = self._build_request(
            method="DELETE",
            path="/v1/events/trigger/{transactionId}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(1000, 30000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "409", "429", "5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="EventsController_cancel",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "413",
                "414",
                "415",
                "422",
                "429",
                "4XX",
                "500",
                "503",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.EventsControllerCancelResponse(
                result=unmarshal_json_response(bool, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "414", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(
            http_res,
            ["400", "401", "403", "404", "405", "409", "413", "415"],
            "application/json",
        ):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.ValidationErrorDtoData, http_res
            )
            raise models.ValidationErrorDto(response_data, http_res)
        if utils.match_response(http_res, "429", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "503", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    async def cancel_async(
        self,
        *,
        transaction_id: str,
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.EventsControllerCancelResponse:
        r"""Cancel triggered event


        Using a previously generated transactionId during the event trigger,
        will cancel any active or pending workflows. This is useful to cancel active digests, delays etc...


        :param transaction_id:
        :param idempotency_key: A header for idempotency purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.EventsControllerCancelRequest(
            transaction_id=transaction_id,
            idempotency_key=idempotency_key,
        )

        req = self._build_request_async(
            method="DELETE",
            path="/v1/events/trigger/{transactionId}",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=False,
            request_has_path_params=True,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(1000, 30000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "409", "429", "5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="EventsController_cancel",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "413",
                "414",
                "415",
                "422",
                "429",
                "4XX",
                "500",
                "503",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "200", "application/json"):
            return models.EventsControllerCancelResponse(
                result=unmarshal_json_response(bool, http_res),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "414", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(
            http_res,
            ["400", "401", "403", "404", "405", "409", "413", "415"],
            "application/json",
        ):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.ValidationErrorDtoData, http_res
            )
            raise models.ValidationErrorDto(response_data, http_res)
        if utils.match_response(http_res, "429", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "503", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    def trigger_broadcast(
        self,
        *,
        trigger_event_to_all_request_dto: Union[
            models.TriggerEventToAllRequestDto,
            models.TriggerEventToAllRequestDtoTypedDict,
        ],
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.EventsControllerBroadcastEventToAllResponse:
        r"""Broadcast event to all

        Trigger a broadcast event to all existing subscribers, could be used to send announcements, etc.

        In the future could be used to trigger events to a subset of subscribers based on defined filters.

        :param trigger_event_to_all_request_dto:
        :param idempotency_key: A header for idempotency purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.EventsControllerBroadcastEventToAllRequest(
            idempotency_key=idempotency_key,
            trigger_event_to_all_request_dto=utils.get_pydantic_model(
                trigger_event_to_all_request_dto, models.TriggerEventToAllRequestDto
            ),
        )

        req = self._build_request(
            method="POST",
            path="/v1/events/trigger/broadcast",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.trigger_event_to_all_request_dto,
                False,
                False,
                "json",
                models.TriggerEventToAllRequestDto,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(1000, 30000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "409", "429", "5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="EventsController_broadcastEventToAll",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "413",
                "414",
                "415",
                "422",
                "429",
                "4XX",
                "500",
                "503",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, ["200", "201"], "application/json"):
            return models.EventsControllerBroadcastEventToAllResponse(
                result=unmarshal_json_response(
                    models.TriggerEventResponseDto, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.PayloadValidationExceptionDtoData, http_res
            )
            raise models.PayloadValidationExceptionDto(response_data, http_res)
        if utils.match_response(http_res, "414", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(
            http_res,
            ["401", "403", "404", "405", "409", "413", "415"],
            "application/json",
        ):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.ValidationErrorDtoData, http_res
            )
            raise models.ValidationErrorDto(response_data, http_res)
        if utils.match_response(http_res, "429", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "503", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    async def trigger_broadcast_async(
        self,
        *,
        trigger_event_to_all_request_dto: Union[
            models.TriggerEventToAllRequestDto,
            models.TriggerEventToAllRequestDtoTypedDict,
        ],
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.EventsControllerBroadcastEventToAllResponse:
        r"""Broadcast event to all

        Trigger a broadcast event to all existing subscribers, could be used to send announcements, etc.

        In the future could be used to trigger events to a subset of subscribers based on defined filters.

        :param trigger_event_to_all_request_dto:
        :param idempotency_key: A header for idempotency purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.EventsControllerBroadcastEventToAllRequest(
            idempotency_key=idempotency_key,
            trigger_event_to_all_request_dto=utils.get_pydantic_model(
                trigger_event_to_all_request_dto, models.TriggerEventToAllRequestDto
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/v1/events/trigger/broadcast",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.trigger_event_to_all_request_dto,
                False,
                False,
                "json",
                models.TriggerEventToAllRequestDto,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(1000, 30000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "409", "429", "5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="EventsController_broadcastEventToAll",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "413",
                "414",
                "415",
                "422",
                "429",
                "4XX",
                "500",
                "503",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, ["200", "201"], "application/json"):
            return models.EventsControllerBroadcastEventToAllResponse(
                result=unmarshal_json_response(
                    models.TriggerEventResponseDto, http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.PayloadValidationExceptionDtoData, http_res
            )
            raise models.PayloadValidationExceptionDto(response_data, http_res)
        if utils.match_response(http_res, "414", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(
            http_res,
            ["401", "403", "404", "405", "409", "413", "415"],
            "application/json",
        ):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.ValidationErrorDtoData, http_res
            )
            raise models.ValidationErrorDto(response_data, http_res)
        if utils.match_response(http_res, "429", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "503", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    def trigger_bulk(
        self,
        *,
        bulk_trigger_event_dto: Union[
            models.BulkTriggerEventDto, models.BulkTriggerEventDtoTypedDict
        ],
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.EventsControllerTriggerBulkResponse:
        r"""Bulk trigger event


        Using this endpoint you can trigger multiple events at once, to avoid multiple calls to the API.
        The bulk API is limited to 100 events per request.


        :param bulk_trigger_event_dto:
        :param idempotency_key: A header for idempotency purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.EventsControllerTriggerBulkRequest(
            idempotency_key=idempotency_key,
            bulk_trigger_event_dto=utils.get_pydantic_model(
                bulk_trigger_event_dto, models.BulkTriggerEventDto
            ),
        )

        req = self._build_request(
            method="POST",
            path="/v1/events/trigger/bulk",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.bulk_trigger_event_dto,
                False,
                False,
                "json",
                models.BulkTriggerEventDto,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(1000, 30000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "409", "429", "5XX"])

        http_res = self.do_request(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="EventsController_triggerBulk",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "413",
                "414",
                "415",
                "422",
                "429",
                "4XX",
                "500",
                "503",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return models.EventsControllerTriggerBulkResponse(
                result=unmarshal_json_response(
                    List[models.TriggerEventResponseDto], http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.PayloadValidationExceptionDtoData, http_res
            )
            raise models.PayloadValidationExceptionDto(response_data, http_res)
        if utils.match_response(http_res, "414", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(
            http_res,
            ["401", "403", "404", "405", "409", "413", "415"],
            "application/json",
        ):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.ValidationErrorDtoData, http_res
            )
            raise models.ValidationErrorDto(response_data, http_res)
        if utils.match_response(http_res, "429", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "503", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = utils.stream_to_text(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)

    async def trigger_bulk_async(
        self,
        *,
        bulk_trigger_event_dto: Union[
            models.BulkTriggerEventDto, models.BulkTriggerEventDtoTypedDict
        ],
        idempotency_key: Optional[str] = None,
        retries: OptionalNullable[utils.RetryConfig] = UNSET,
        server_url: Optional[str] = None,
        timeout_ms: Optional[int] = None,
        http_headers: Optional[Mapping[str, str]] = None,
    ) -> models.EventsControllerTriggerBulkResponse:
        r"""Bulk trigger event


        Using this endpoint you can trigger multiple events at once, to avoid multiple calls to the API.
        The bulk API is limited to 100 events per request.


        :param bulk_trigger_event_dto:
        :param idempotency_key: A header for idempotency purposes
        :param retries: Override the default retry configuration for this method
        :param server_url: Override the default server URL for this method
        :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
        :param http_headers: Additional headers to set or replace on requests.
        """
        base_url = None
        url_variables = None
        if timeout_ms is None:
            timeout_ms = self.sdk_configuration.timeout_ms

        if server_url is not None:
            base_url = server_url
        else:
            base_url = self._get_url(base_url, url_variables)

        request = models.EventsControllerTriggerBulkRequest(
            idempotency_key=idempotency_key,
            bulk_trigger_event_dto=utils.get_pydantic_model(
                bulk_trigger_event_dto, models.BulkTriggerEventDto
            ),
        )

        req = self._build_request_async(
            method="POST",
            path="/v1/events/trigger/bulk",
            base_url=base_url,
            url_variables=url_variables,
            request=request,
            request_body_required=True,
            request_has_path_params=False,
            request_has_query_params=True,
            user_agent_header="user-agent",
            accept_header_value="application/json",
            http_headers=http_headers,
            security=self.sdk_configuration.security,
            get_serialized_body=lambda: utils.serialize_request_body(
                request.bulk_trigger_event_dto,
                False,
                False,
                "json",
                models.BulkTriggerEventDto,
            ),
            allow_empty_value=None,
            timeout_ms=timeout_ms,
        )

        if retries == UNSET:
            if self.sdk_configuration.retry_config is not UNSET:
                retries = self.sdk_configuration.retry_config
            else:
                retries = utils.RetryConfig(
                    "backoff", utils.BackoffStrategy(1000, 30000, 1.5, 3600000), True
                )

        retry_config = None
        if isinstance(retries, utils.RetryConfig):
            retry_config = (retries, ["408", "409", "429", "5XX"])

        http_res = await self.do_request_async(
            hook_ctx=HookContext(
                config=self.sdk_configuration,
                base_url=base_url or "",
                operation_id="EventsController_triggerBulk",
                oauth2_scopes=None,
                security_source=get_security_from_env(
                    self.sdk_configuration.security, models.Security
                ),
            ),
            request=req,
            error_status_codes=[
                "400",
                "401",
                "403",
                "404",
                "405",
                "409",
                "413",
                "414",
                "415",
                "422",
                "429",
                "4XX",
                "500",
                "503",
                "5XX",
            ],
            retry_config=retry_config,
        )

        response_data: Any = None
        if utils.match_response(http_res, "201", "application/json"):
            return models.EventsControllerTriggerBulkResponse(
                result=unmarshal_json_response(
                    List[models.TriggerEventResponseDto], http_res
                ),
                headers=utils.get_response_headers(http_res.headers),
            )
        if utils.match_response(http_res, "400", "application/json"):
            response_data = unmarshal_json_response(
                models.PayloadValidationExceptionDtoData, http_res
            )
            raise models.PayloadValidationExceptionDto(response_data, http_res)
        if utils.match_response(http_res, "414", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(
            http_res,
            ["401", "403", "404", "405", "409", "413", "415"],
            "application/json",
        ):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "422", "application/json"):
            response_data = unmarshal_json_response(
                models.ValidationErrorDtoData, http_res
            )
            raise models.ValidationErrorDto(response_data, http_res)
        if utils.match_response(http_res, "429", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "500", "application/json"):
            response_data = unmarshal_json_response(models.ErrorDtoData, http_res)
            raise models.ErrorDto(response_data, http_res)
        if utils.match_response(http_res, "503", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "4XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)
        if utils.match_response(http_res, "5XX", "*"):
            http_res_text = await utils.stream_to_text_async(http_res)
            raise models.APIError("API error occurred", http_res, http_res_text)

        raise models.APIError("Unexpected response received", http_res)
