# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: keyapis/banner/v1/keyapis_banner_banner_v1.proto, keyapis/banner/v1/keyapis_banner_system_v1.proto
# plugin: python-betterproto
from dataclasses import dataclass
from datetime import datetime
from typing import (
    TYPE_CHECKING,
    AsyncIterator,
    Dict,
    List,
    Optional,
)

import betterproto
import grpclib
from betterproto.grpc.grpclib_server import ServiceBase

if TYPE_CHECKING:
    import grpclib.server
    from betterproto.grpc.grpclib_client import MetadataLike
    from grpclib.metadata import Deadline


class BannerType(betterproto.Enum):
    """Справочник типов баннеров. # Тип: byte"""

    TYPE_UNKNOWN = 0
    """Значение не указано"""

    STANDARD = 1
    """Стандартный баннер"""


class BannerPriorityType(betterproto.Enum):
    """Справочник типов приоритетов. # Тип: byte"""

    PRIORITY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    NORMAL = 1
    """
    Обычный. Приоритет 31. Вычисляется в логике приложения как priority меньше
    64. Извлекаются из базы по фильтру end_priority = 64
    """

    WHITE_LABEL = 2
    """
    Вайт-лейбл. Приоритет 127. Вычисляется в логике приложения как priority
    больше или равно 64 и priority меньше 160. Извлекаются из базы по фильтру
    begin_priority = 64 и end_priority = 160
    """

    CRITICAL = 3
    """
    Критикл. Приоритет 191. Вычисляется в логике приложения как priority больше
    или равно 160. Извлекаются из базы по фильтру begin_priority = 160
    """


class BannerStatusType(betterproto.Enum):
    """Справочник статусов баннеров. # Тип: byte"""

    STATUS_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DEFERRED = 1
    """
    Отложен. Вычисляется в логике приложения как сurr_date меньше
    show_start_at. Извлекаются из базы по фильтру end_show_start_at = сurr_date
    """

    ACTIVE = 2
    """
    Активен. Вычисляется в логике приложения как сurr_date больше или равно
    show_start_at и сurr_date меньше show_ended_at. Извлекаются из базы по
    фильтру begin_show_start_at = сurr_date и end_show_ended_at = сurr_date
    """

    EXPIRED = 3
    """
    Истёк. Вычисляется в логике приложения как сurr_date больше или равно
    show_ended_at. Извлекаются из базы по фильтру begin_show_ended_at =
    сurr_date
    """


class BannerPlatformType(betterproto.Enum):
    """Справочник платформ. # Тип: byte"""

    PLATFORM_TYPE_UNKNOWN = 0
    """Значение не указано"""

    IOS = 1
    """Платформа iOS. Приложение размещается в App Store"""

    ANDROID = 2
    """
    Платформа Android. Приложение размещается в Google Play, App Gallery или
    прочих сторах
    """

    WEB = 3
    """Платформа Web. Приложение размещается по интернет адресу"""


class BannerImageType(betterproto.Enum):
    """Справочник типов картинок. # Тип: byte"""

    TYPE_UNKNOWN = 0
    """Значение не указано"""

    PORTRAIT = 1
    """
    Пререндеренный баннер в портретном режиме. В портретном режиме ширина
    меньше или равна высоте. Представление характерно для телефонов. Может
    содержать дополнительные параметры запроса в
    ссылке(https://docs.imgproxy.net/generating_the_url?id=processing-options).
    После загрузки изображения отрисовывается поверх цвета и градиента. Если
    ссылки нет то нужно использовать ссылку из ландшафтного режима
    """

    LANDSCAPE = 2
    """
    Пререндеренный баннер в ландшафтном режиме. В ландшафтном режиме ширина
    больше высоты. Представление характерно для планшетов и декстопа. Может
    содержать дополнительные параметры запроса в
    ссылке(https://docs.imgproxy.net/generating_the_url?id=processing-options).
    После загрузки изображения отрисовывается поверх цвета и градиента. Если
    ссылки нет то нужно использовать ссылку из портретного режима
    """

    ICON = 3
    """
    Иконка. Может содержать дополнительные параметры запроса в
    ссылке(https://docs.imgproxy.net/generating_the_url?id=processing-options).
    После загрузки изображения отрисовывается поверх цвета и градиента
    """


class BannerLinkType(betterproto.Enum):
    """Справочник типов ссылок. # Тип: byte"""

    TYPE_UNKNOWN = 0
    """Значение не указано"""

    INTERNAL_APP = 1
    """Ссылка для перехода на раздел текущего приложения"""

    EXTERNAL_APP = 2
    """Ссылка для перехода на стороннее приложение"""

    WEB_VIEW = 3
    """
    Ссылка для перехода на веб-вью внутренних (своих) приложений. В окне
    отсутствует адресаная строка. Для iOS используется WKWebView, для Android
    используется WebView
    """

    WEB_BROWSER = 4
    """Ссылка для перехода на веб-браузер"""

    EXTERNAL_WEB_VIEW = 5
    """
    Ссылка для перехода на веб-вью внешних (партнёрских) приложений. В окне
    присутствует адресаная строка. Для iOS используется SFSafariViewController,
    для Android используется ChromeCustomTabs
    """


class BannerPagingOrderByType(betterproto.Enum):
    """Справочник типов значений сортировки. # Тип: byte"""

    ORDER_BY_TYPE_UNKNOWN = 0
    """Значение не указано"""

    CHANGED_AT = 1
    """Дата последнего изменения"""

    PRIORITY_THEN_SHOW_START_AT = 2
    """По приоритету, затем по дате начала показа"""

    CREATED_AT = 3
    """Дата создания"""

    SHOW_START_AT = 4
    """Дата начала показа"""

    SHOW_ENDED_AT = 5
    """Дата конца показа"""

    RANK = 6
    """
    По рангу для поиска по тексту. Применяется когда передано поле для поиска
    по тексту. В случае если текстовое поле не передано, применяется значение
    по умолчанию
    """


class BannerPagingDirectionType(betterproto.Enum):
    """Справочник типов направлений сортировки. # Тип: byte"""

    DIRECTION_TYPE_UNKNOWN = 0
    """Значение не указано"""

    DESC = 1
    """От большего к меньшему"""

    ASC = 2
    """От меньшего к большему"""


@dataclass(eq=False, repr=False)
class Banner(betterproto.Message):
    """Баннер. # Описание модели"""

    id: str = betterproto.string_field(1)
    """Идентификатор. Если не передан создаётся сервером. # Тип: Guid"""

    type: "BannerType" = betterproto.enum_field(2)
    """Тип баннера. Обязательное"""

    priority: int = betterproto.int32_field(3)
    """Приоритет. Обязательное. # Диапазон: 1..255"""

    priority_type: "BannerPriorityType" = betterproto.enum_field(4)
    """Тип приоритета. # Поле вычисляется в коде приложения"""

    title: str = betterproto.string_field(5)
    """
    Название. Обязательное. Обычно это название рекламной компании. Не
    отображается пользователям. # Диапазон: 3..256
    """

    header: Optional[str] = betterproto.message_field(6, wraps=betterproto.TYPE_STRING)
    """Заголовок. # Диапазон: 3..64"""

    header_color: Optional[str] = betterproto.message_field(
        7, wraps=betterproto.TYPE_STRING
    )
    """
    Цвет текста заголовка. Все цвета должны быть в формате hex #RRGGBBAA.
    Пример: #7e00c380. # Диапазон: 9..9. # Паттерн: /^#[0-9a-fA-F]{8}$/
    """

    subtitle: Optional[str] = betterproto.message_field(
        8, wraps=betterproto.TYPE_STRING
    )
    """Подзаголовок. # Диапазон: 3..256"""

    subtitle_color: Optional[str] = betterproto.message_field(
        9, wraps=betterproto.TYPE_STRING
    )
    """
    Цвет текста подзаголовка. Все цвета должны быть в формате hex #RRGGBBAA.
    Пример: #7e00c380. # Диапазон: 9..9. # Паттерн: /^#[0-9a-fA-F]{8}$/
    """

    background_color: Optional[str] = betterproto.message_field(
        10, wraps=betterproto.TYPE_STRING
    )
    """
    Цвет заднего плана(подложки). Отрисовывается до загрузки картинки и
    градиента. Все цвета должны быть в формате hex #RRGGBBAA. Пример:
    #7e00c380. # Диапазон: 9..9. # Паттерн: /^#[0-9a-fA-F]{8}$/
    """

    background_gradient: "BannerGradient" = betterproto.message_field(11)
    """Градиент"""

    repeat_after_days: Optional[int] = betterproto.message_field(
        12, wraps=betterproto.TYPE_INT32
    )
    """
    Количество дней через которое можно повторно показать баннер. Если null, то
    закрыть нельзя, баннер повторно выводится каждый раз. # Диапазон: 0..366
    """

    show_start_at: datetime = betterproto.message_field(13)
    """
    Дата начала показа. Обязательное. Бессрочно если значение 2000-01-01. #
    Тип: DateOnly. # Диапазон: 730119..1095362
    """

    show_ended_at: datetime = betterproto.message_field(14)
    """
    Дата конца показа. Обязательное. Бессрочно если значение 3000-01-01. # Тип:
    DateOnly. # Диапазон: 730119..1095362
    """

    status_type: "BannerStatusType" = betterproto.enum_field(15)
    """Статус баннера. # Поле вычисляется в коде приложения"""

    images: List["BannerImage"] = betterproto.message_field(16)
    """Картинки. # Диапазон: 0..20"""

    links: List["BannerLink"] = betterproto.message_field(17)
    """Ссылки для переходов. # Диапазон: 0..100"""

    user_tags: List[str] = betterproto.string_field(18)
    """
    Список тегов пользователей. Обязательное. Описывает кто может видеть
    баннер. Тэг - максимум 5 символов, значение - максимум 19 символов,
    количество сегментов - максимум 10. # Диапазон: 1..100. # Паттерн:
    /^[A-Z-]{1,5}_[0-9A-Z-]{1,19}(?:\.[A-Z-]{1,5}_[0-9A-Z-]{1,19}){0,9}$/
    """

    app_tags: List[str] = betterproto.string_field(19)
    """
    Список тегов приложений. Обязательное. Описывает какие клиенты могут видеть
    баннер. Тэг - максимум 5 символов, значение - максимум 19 символов,
    количество сегментов - максимум 10. # Диапазон: 1..20. # Паттерн:
    /^[A-Z-]{1,5}_[0-9A-Z-]{1,19}(?:\.[A-Z-]{1,5}_[0-9A-Z-]{1,19}){0,9}$/
    """

    created_at: datetime = betterproto.message_field(20)
    """Дата создания. # Тип: DateTime"""

    changed_at: datetime = betterproto.message_field(21)
    """
    Дата последнего изменения. Заполняется и обновляется сервером. Заполняется
    при создании и изменении. Является версией объекта. # Тип: DateTime
    """


@dataclass(eq=False, repr=False)
class BannerGradient(betterproto.Message):
    """Градиент"""

    linear: "BannerGradientLinear" = betterproto.message_field(1, group="type")
    """Линейный градиент"""


@dataclass(eq=False, repr=False)
class BannerGradientLinear(betterproto.Message):
    """Линейный градиент"""

    angle: float = betterproto.float_field(1)
    """Угол направления линейного градиента в градусах. # Диапазон: 0..360"""

    points: List["BannerGradientLinearPoint"] = betterproto.message_field(2)
    """Точки градиента. Обязательное. # Диапазон: 2..20"""


@dataclass(eq=False, repr=False)
class BannerGradientLinearPoint(betterproto.Message):
    """Точка"""

    color: str = betterproto.string_field(1)
    """
    Цвет линейного градиента. Обязательное. Отрисовывается до загрузки картинки
    и градиента. Все цвета должны быть в формате hex #RRGGBBAA. Пример:
    #7e00c380. # Диапазон: 9..9. # Паттерн: /^#[0-9a-fA-F]{8}$/
    """

    stop: float = betterproto.float_field(2)
    """
    Стоп линейного градиента. Записывается в процентах. # Диапазон: 0..100
    """


@dataclass(eq=False, repr=False)
class BannerImage(betterproto.Message):
    """Объект картинки"""

    type: "BannerImageType" = betterproto.enum_field(1)
    """Тип картинки. Обязательное"""

    url: str = betterproto.string_field(2)
    """Значение ссылки на картинку. Обязательное. # Диапазон: 12..512"""


@dataclass(eq=False, repr=False)
class BannerLink(betterproto.Message):
    """Ссылка"""

    platform_type: "BannerPlatformType" = betterproto.enum_field(1)
    """Тип платформы. Обязательное"""

    type: "BannerLinkType" = betterproto.enum_field(2)
    """Тип ссылки. Обязательное"""

    url: str = betterproto.string_field(3)
    """Значение ссылки для перехода. Обязательное. # Диапазон: 12..512"""

    packages: List[str] = betterproto.string_field(4)
    """
    Список пакетов. Если пусто попытка перехода осуществляется безусловно. Если
    заполнено, то переход осуществляется только в случае если хоть один пакет
    есть на устройстве, иначе обработка переходит к следующей ссылке. #
    Диапазон: 0..20
    """


@dataclass(eq=False, repr=False)
class BannerSavingError(betterproto.Message):
    """
    Ошибка сохранения. Эти проверки выполняются при работе с базой данных и
    сторонними сервисами
    """

    conflict: "BannerSavingErrorConflict" = betterproto.message_field(1, group="reason")
    """Конфликт версий"""


@dataclass(eq=False, repr=False)
class BannerSavingErrorConflict(betterproto.Message):
    """
    Конфликт версий. Причины: - В базе хранится другая версия строки, значения
    changed_at отличаются
    """

    pass


@dataclass(eq=False, repr=False)
class BannerLite(betterproto.Message):
    """Облегчённый баннер"""

    id: str = betterproto.string_field(1)
    """Идентификатор. # Тип: Guid"""

    repeat_after_days: Optional[int] = betterproto.message_field(
        2, wraps=betterproto.TYPE_INT32
    )
    """
    Количество дней через которое можно повторно показать баннер. Если Значение
    не указано то повторного показа баннера не будет
    """

    images: List["BannerLiteImageLite"] = betterproto.message_field(3)
    """Картинки"""

    links: List["BannerLiteLinkLite"] = betterproto.message_field(4)
    """Ссылки для переходов. Возвращаются отфильтрованные по платформе"""


@dataclass(eq=False, repr=False)
class BannerLiteImageLite(betterproto.Message):
    """Упрощённый объект картинки"""

    type: "BannerImageType" = betterproto.enum_field(1)
    """Тип картинки. Обязательное"""

    url: str = betterproto.string_field(2)
    """Значение ссылки на картинку. Обязательное"""


@dataclass(eq=False, repr=False)
class BannerLiteLinkLite(betterproto.Message):
    """Упрощённая ссылка"""

    type: "BannerLinkType" = betterproto.enum_field(1)
    """Тип ссылки. Обязательное"""

    url: str = betterproto.string_field(2)
    """Значение ссылки. Обязательное"""

    packages: List[str] = betterproto.string_field(3)
    """
    Список пакетов. Если пусто попытка перехода осуществляется безусловно. Если
    заполнено, то переход осуществляется только в случае если хоть один пакет
    есть на устройстве иначе обработка переходит к следующей ссылке
    """

    platform_type: "BannerPlatformType" = betterproto.enum_field(4)
    """Тип платформы. Обязательное"""


@dataclass(eq=False, repr=False)
class BannerFilter(betterproto.Message):
    """Фильтр баннеров"""

    text: Optional[str] = betterproto.message_field(1, wraps=betterproto.TYPE_STRING)
    """
    По тексту. Если значение не передано то поиск по нему не производится. #
    Диапазон: 3..64. # Поиск производится по полям: # - Название; # -
    Заголовок; # - Подзаголовок; # - Список тегов пользователей; # - Список
    тегов приложений
    """

    types: List["BannerType"] = betterproto.enum_field(2)
    """По типам баннеров"""

    begin_priority: Optional[int] = betterproto.message_field(
        3, wraps=betterproto.TYPE_INT32
    )
    """От приоритета включительно (больше или равно)"""

    end_priority: Optional[int] = betterproto.message_field(
        4, wraps=betterproto.TYPE_INT32
    )
    """До приоритета (меньше)"""

    priority_types: List["BannerPriorityType"] = betterproto.enum_field(5)
    """
    По типам приоритетов. Переписывает значения фильтров по приоритету. Если
    переданы все типы, то фильтр игнорируется(так как нужно вернуть всё)
    """

    begin_show_start_at: datetime = betterproto.message_field(6)
    """От даты начала показа включительно (больше или равно)"""

    end_show_start_at: datetime = betterproto.message_field(7)
    """До даты начала показа (меньше)"""

    begin_show_ended_at: datetime = betterproto.message_field(8)
    """От даты конца показа включительно (больше или равно)"""

    end_show_ended_at: datetime = betterproto.message_field(9)
    """До даты конца показа (меньше)"""

    status_types: List["BannerStatusType"] = betterproto.enum_field(10)
    """
    По статусам баннеров. Переписывает значения фильтров по датам. Если
    переданы все типы, то фильтр игнорируется(так как нужно вернуть всё)
    """

    user_tags: List[str] = betterproto.string_field(11)
    """
    По пользовательским тегам. Тэг - максимум 5 символов, значение - максимум
    19 символов, количество сегментов - максимум 10. # Диапазон: 0..20. #
    Паттерн:
    /^[A-Z-]{1,5}_[0-9A-Z-]{1,19}(?:\.[A-Z-]{1,5}_[0-9A-Z-]{1,19}){0,9}$/
    """

    app_tags: List[str] = betterproto.string_field(12)
    """
    По тегам приложений. Тэг - максимум 5 символов, значение - максимум 19
    символов, количество сегментов - максимум 10. # Диапазон: 0..20. # Паттерн:
    /^[A-Z-]{1,5}_[0-9A-Z-]{1,19}(?:\.[A-Z-]{1,5}_[0-9A-Z-]{1,19}){0,9}$/
    """


@dataclass(eq=False, repr=False)
class BannerLiteFilter(betterproto.Message):
    """Упрощённый фильтр по баннерам"""

    types: List["BannerType"] = betterproto.enum_field(1)
    """По типам баннеров"""

    app_name: Optional[str] = betterproto.message_field(
        2, wraps=betterproto.TYPE_STRING
    )
    """
    Название приложения. # Диапазон: 1..19. # Паттерн: /^[0-9A-Z-]{1,19}$/
    """

    platform_type: "BannerPlatformType" = betterproto.enum_field(3)
    """Тип платформы"""

    version: Optional[str] = betterproto.message_field(4, wraps=betterproto.TYPE_STRING)
    """Версия приложения. # Диапазон: 1..19. # Паттерн: /^[0-9A-Z-]{1,19}$/"""

    user_tags: List[str] = betterproto.string_field(5)
    """
    По тегам пользователя. Тэг - максимум 5 символов, значение - максимум 19
    символов, количество сегментов - максимум 10. # Диапазон: 1..20. # Паттерн:
    /^[A-Z-]{1,5}_[0-9A-Z-]{1,19}(?:\.[A-Z-]{1,5}_[0-9A-Z-]{1,19}){0,9}$/
    """


@dataclass(eq=False, repr=False)
class BannerPaging(betterproto.Message):
    """Пагинация баннеров"""

    order_by_type: "BannerPagingOrderByType" = betterproto.enum_field(1)
    """
    Тип значения сортировки. Если значение не передано, то будет взято значение
    по умолчанию. # По умолчанию: CHANGED_AT
    """

    direction_type: "BannerPagingDirectionType" = betterproto.enum_field(2)
    """Тип направления сортировки. # По умолчанию: DESC"""

    limit: int = betterproto.int32_field(3)
    """
    Количество записей на страницу. Если значение 0 (не передано), то будет
    взято значение по умолчанию. # Диапазон: 0..100. # По умолчанию: 20
    """

    offset: int = betterproto.int32_field(4)
    """Сдвиг. # Диапазон: 0..2147483647"""


@dataclass(eq=False, repr=False)
class PostBannerRequest(betterproto.Message):
    """Запрос сохранения баннера"""

    data: "Banner" = betterproto.message_field(1)
    """Баннер"""


@dataclass(eq=False, repr=False)
class PostBannerResponse(betterproto.Message):
    """Ответ на запрос сохранения баннера"""

    data: "Banner" = betterproto.message_field(1, group="type")
    """Баннер"""

    error: "PostBannerResponseError" = betterproto.message_field(2, group="type")
    """Ошибка"""


@dataclass(eq=False, repr=False)
class PostBannerResponseError(betterproto.Message):
    """Ошибка запроса сохранения баннера"""

    validation: "ValidationError" = betterproto.message_field(1, group="reason")
    """Ошибка валидации"""

    saving: "BannerSavingError" = betterproto.message_field(2, group="reason")
    """Ошибка сохранения"""


@dataclass(eq=False, repr=False)
class GetBannerRequest(betterproto.Message):
    """Запрос получения баннера"""

    id: str = betterproto.string_field(1)
    """Идентификатор баннера. # Тип: Guid"""


@dataclass(eq=False, repr=False)
class GetBannerResponse(betterproto.Message):
    """Ответ на запрос получения баннера"""

    data: "Banner" = betterproto.message_field(1, group="type")
    """Баннер"""

    error: "GetBannerResponseError" = betterproto.message_field(2, group="type")
    """Ошибка"""


@dataclass(eq=False, repr=False)
class GetBannerResponseError(betterproto.Message):
    """Ошибка запроса получения баннера"""

    validation: "ValidationError" = betterproto.message_field(1, group="reason")
    """Ошибка валидации"""


@dataclass(eq=False, repr=False)
class GetBannerLiteRequest(betterproto.Message):
    """Запрос получения упрощённого баннера"""

    id: str = betterproto.string_field(1)
    """Идентификатор баннера. # Тип: Guid"""


@dataclass(eq=False, repr=False)
class GetBannerLiteResponse(betterproto.Message):
    """Ответ на запрос получения упрощённого баннера"""

    data: "BannerLite" = betterproto.message_field(1, group="type")
    """Упрощённый баннер"""

    error: "GetBannerLiteResponseError" = betterproto.message_field(2, group="type")
    """Ошибка"""


@dataclass(eq=False, repr=False)
class GetBannerLiteResponseError(betterproto.Message):
    """Ошибка запроса получения упрощённого баннера"""

    validation: "ValidationError" = betterproto.message_field(1, group="reason")
    """Ошибка валидации"""


@dataclass(eq=False, repr=False)
class GetBannerListRequest(betterproto.Message):
    """Запрос получения списка баннеров"""

    filter: "BannerFilter" = betterproto.message_field(1)
    """Фильтр"""

    paging: "BannerPaging" = betterproto.message_field(2, group="pagination")
    """Пагинация"""


@dataclass(eq=False, repr=False)
class GetBannerListResponse(betterproto.Message):
    """Ответ на запрос получения списка баннеров"""

    data: "Banner" = betterproto.message_field(1, group="type")
    """Баннер"""

    error: "GetBannerListResponseError" = betterproto.message_field(2, group="type")
    """Ошибка"""


@dataclass(eq=False, repr=False)
class GetBannerListResponseError(betterproto.Message):
    """Ошибка запроса получения списка баннеров"""

    validation: "ValidationError" = betterproto.message_field(1, group="reason")
    """Ошибка валидации"""


@dataclass(eq=False, repr=False)
class GetBannerLiteListRequest(betterproto.Message):
    """Запрос получения списка упрощённого баннеров"""

    filter: "BannerLiteFilter" = betterproto.message_field(1)
    """Упрощённый фильтр"""

    is_link_filter_disabled: bool = betterproto.bool_field(2)
    """Признак отключения фильтрации по типу платформы"""


@dataclass(eq=False, repr=False)
class GetBannerLiteListResponse(betterproto.Message):
    """Ответ на запрос получения списка упрощённых баннеров"""

    data: "BannerLite" = betterproto.message_field(1, group="type")
    """Упрощённый баннер"""

    error: "GetBannerLiteListResponseError" = betterproto.message_field(2, group="type")
    """Ошибка"""


@dataclass(eq=False, repr=False)
class GetBannerLiteListResponseError(betterproto.Message):
    """Ошибка запроса получения списка баннеров"""

    validation: "ValidationError" = betterproto.message_field(1, group="reason")
    """Ошибка валидации"""


@dataclass(eq=False, repr=False)
class GetBannerCountRequest(betterproto.Message):
    """Запрос получения количества баннеров"""

    filter: "BannerFilter" = betterproto.message_field(1)
    """Фильтр"""


@dataclass(eq=False, repr=False)
class GetBannerCountResponse(betterproto.Message):
    """Ответ на запрос получения количества баннеров"""

    data: int = betterproto.int32_field(1, group="type")
    """Всего баннеров"""

    error: "GetBannerCountResponseError" = betterproto.message_field(2, group="type")
    """Ошибка"""


@dataclass(eq=False, repr=False)
class GetBannerCountResponseError(betterproto.Message):
    """Ошибка запроса получения количества баннеров"""

    validation: "ValidationError" = betterproto.message_field(1, group="reason")
    """Ошибка валидации"""


@dataclass(eq=False, repr=False)
class UploadImage(betterproto.Message):
    """Объект загружаемой картинки"""

    base64: str = betterproto.string_field(1)
    """
    Картинка в формате инлайн base64. Обязательное. Пример:
    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...". # Паттерн:
    /^data:\s*image\/(png|jpeg|jpg);\s*base64/
    """


@dataclass(eq=False, repr=False)
class PostBannerUploadImageRequest(betterproto.Message):
    """Запрос загрузки картинки баннера"""

    banner_id: str = betterproto.string_field(1)
    """
    Идентификатор баннера. Используется для складывания картинок баннера в
    папку баннера в бакете. Название картинки в папке создаётся из случайного
    Guid. # Тип: Guid
    """

    upload_image: "UploadImage" = betterproto.message_field(2)
    """Загружаемая картинка"""


@dataclass(eq=False, repr=False)
class PostBannerUploadImageResponse(betterproto.Message):
    """Ответ на запрос загрузки картинки баннера"""

    data: str = betterproto.string_field(1, group="type")
    """Ссылка на баннер на imageproxy cdn сервер. Общедоступна в интернете"""

    error: "PostBannerUploadImageResponseError" = betterproto.message_field(
        2, group="type"
    )
    """Ошибка"""


@dataclass(eq=False, repr=False)
class PostBannerUploadImageResponseError(betterproto.Message):
    """Ошибка запроса загрузки картинки баннера"""

    validation: "ValidationError" = betterproto.message_field(1, group="reason")
    """Ошибка валидации"""


@dataclass(eq=False, repr=False)
class ValidationError(betterproto.Message):
    """
    Ошибки валидации. Эти проверки выполняются до обращения в базу данных
    """

    path: str = betterproto.string_field(1)
    """Путь к полю в формате наименования прото"""

    message: str = betterproto.string_field(2)
    """Валидационное сообщение"""


@dataclass(eq=False, repr=False)
class GetSystemStatusRequest(betterproto.Message):
    """Запрос проверки доступности сервиса"""

    pass


@dataclass(eq=False, repr=False)
class GetSystemStatusResponse(betterproto.Message):
    """Ответ на запрос проверки доступности сервиса"""

    pass


class BannerServiceStub(betterproto.ServiceStub):
    async def post_banner(
        self,
        post_banner_request: "PostBannerRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "PostBannerResponse":
        return await self._unary_unary(
            "/keyapis.banner.v1.BannerService/PostBanner",
            post_banner_request,
            PostBannerResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_banner(
        self,
        get_banner_request: "GetBannerRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetBannerResponse":
        return await self._unary_unary(
            "/keyapis.banner.v1.BannerService/GetBanner",
            get_banner_request,
            GetBannerResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_banner_lite(
        self,
        get_banner_lite_request: "GetBannerLiteRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetBannerLiteResponse":
        return await self._unary_unary(
            "/keyapis.banner.v1.BannerService/GetBannerLite",
            get_banner_lite_request,
            GetBannerLiteResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_banner_list(
        self,
        get_banner_list_request: "GetBannerListRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["GetBannerListResponse"]:
        async for response in self._unary_stream(
            "/keyapis.banner.v1.BannerService/GetBannerList",
            get_banner_list_request,
            GetBannerListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_banner_lite_list(
        self,
        get_banner_lite_list_request: "GetBannerLiteListRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["GetBannerLiteListResponse"]:
        async for response in self._unary_stream(
            "/keyapis.banner.v1.BannerService/GetBannerLiteList",
            get_banner_lite_list_request,
            GetBannerLiteListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_banner_count(
        self,
        get_banner_count_request: "GetBannerCountRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetBannerCountResponse":
        return await self._unary_unary(
            "/keyapis.banner.v1.BannerService/GetBannerCount",
            get_banner_count_request,
            GetBannerCountResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def post_banner_upload_image(
        self,
        post_banner_upload_image_request: "PostBannerUploadImageRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "PostBannerUploadImageResponse":
        return await self._unary_unary(
            "/keyapis.banner.v1.BannerService/PostBannerUploadImage",
            post_banner_upload_image_request,
            PostBannerUploadImageResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class SystemServiceStub(betterproto.ServiceStub):
    async def get_system_status(
        self,
        get_system_status_request: "GetSystemStatusRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetSystemStatusResponse":
        return await self._unary_unary(
            "/keyapis.banner.v1.SystemService/GetSystemStatus",
            get_system_status_request,
            GetSystemStatusResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class BannerServiceBase(ServiceBase):

    async def post_banner(
        self, post_banner_request: "PostBannerRequest"
    ) -> "PostBannerResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_banner(
        self, get_banner_request: "GetBannerRequest"
    ) -> "GetBannerResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_banner_lite(
        self, get_banner_lite_request: "GetBannerLiteRequest"
    ) -> "GetBannerLiteResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_banner_list(
        self, get_banner_list_request: "GetBannerListRequest"
    ) -> AsyncIterator["GetBannerListResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_banner_lite_list(
        self, get_banner_lite_list_request: "GetBannerLiteListRequest"
    ) -> AsyncIterator["GetBannerLiteListResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_banner_count(
        self, get_banner_count_request: "GetBannerCountRequest"
    ) -> "GetBannerCountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def post_banner_upload_image(
        self, post_banner_upload_image_request: "PostBannerUploadImageRequest"
    ) -> "PostBannerUploadImageResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_post_banner(
        self, stream: "grpclib.server.Stream[PostBannerRequest, PostBannerResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_banner(request)
        await stream.send_message(response)

    async def __rpc_get_banner(
        self, stream: "grpclib.server.Stream[GetBannerRequest, GetBannerResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_banner(request)
        await stream.send_message(response)

    async def __rpc_get_banner_lite(
        self,
        stream: "grpclib.server.Stream[GetBannerLiteRequest, GetBannerLiteResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_banner_lite(request)
        await stream.send_message(response)

    async def __rpc_get_banner_list(
        self,
        stream: "grpclib.server.Stream[GetBannerListRequest, GetBannerListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_banner_list,
            stream,
            request,
        )

    async def __rpc_get_banner_lite_list(
        self,
        stream: "grpclib.server.Stream[GetBannerLiteListRequest, GetBannerLiteListResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_banner_lite_list,
            stream,
            request,
        )

    async def __rpc_get_banner_count(
        self,
        stream: "grpclib.server.Stream[GetBannerCountRequest, GetBannerCountResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_banner_count(request)
        await stream.send_message(response)

    async def __rpc_post_banner_upload_image(
        self,
        stream: "grpclib.server.Stream[PostBannerUploadImageRequest, PostBannerUploadImageResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.post_banner_upload_image(request)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/keyapis.banner.v1.BannerService/PostBanner": grpclib.const.Handler(
                self.__rpc_post_banner,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostBannerRequest,
                PostBannerResponse,
            ),
            "/keyapis.banner.v1.BannerService/GetBanner": grpclib.const.Handler(
                self.__rpc_get_banner,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetBannerRequest,
                GetBannerResponse,
            ),
            "/keyapis.banner.v1.BannerService/GetBannerLite": grpclib.const.Handler(
                self.__rpc_get_banner_lite,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetBannerLiteRequest,
                GetBannerLiteResponse,
            ),
            "/keyapis.banner.v1.BannerService/GetBannerList": grpclib.const.Handler(
                self.__rpc_get_banner_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetBannerListRequest,
                GetBannerListResponse,
            ),
            "/keyapis.banner.v1.BannerService/GetBannerLiteList": grpclib.const.Handler(
                self.__rpc_get_banner_lite_list,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetBannerLiteListRequest,
                GetBannerLiteListResponse,
            ),
            "/keyapis.banner.v1.BannerService/GetBannerCount": grpclib.const.Handler(
                self.__rpc_get_banner_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetBannerCountRequest,
                GetBannerCountResponse,
            ),
            "/keyapis.banner.v1.BannerService/PostBannerUploadImage": grpclib.const.Handler(
                self.__rpc_post_banner_upload_image,
                grpclib.const.Cardinality.UNARY_UNARY,
                PostBannerUploadImageRequest,
                PostBannerUploadImageResponse,
            ),
        }


class SystemServiceBase(ServiceBase):

    async def get_system_status(
        self, get_system_status_request: "GetSystemStatusRequest"
    ) -> "GetSystemStatusResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get_system_status(
        self,
        stream: "grpclib.server.Stream[GetSystemStatusRequest, GetSystemStatusResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_system_status(request)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/keyapis.banner.v1.SystemService/GetSystemStatus": grpclib.const.Handler(
                self.__rpc_get_system_status,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetSystemStatusRequest,
                GetSystemStatusResponse,
            ),
        }
