# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: sp_bus.proto, sp_command.proto, sp_common.proto, sp_external.proto, sp_info.proto, sp_internal.proto, sp_kv.proto, sp_notify.proto, sp_pipeline.proto, sp_uibff.proto, sp_wsm.proto
# plugin: python-betterproto
# This file has been @generated
import builtins
from dataclasses import dataclass
from typing import (
    TYPE_CHECKING,
    AsyncIterable,
    AsyncIterator,
    Dict,
    Iterable,
    List,
    Optional,
    Union,
)

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

from . import (
    shared,
    steps,
)


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


class ResponseCode(betterproto.Enum):
    """Common status codes used in gRPC method responses"""

    RESPONSE_CODE_UNSET = 0
    RESPONSE_CODE_OK = 1
    RESPONSE_CODE_BAD_REQUEST = 2
    RESPONSE_CODE_NOT_FOUND = 3
    RESPONSE_CODE_INTERNAL_SERVER_ERROR = 4
    RESPONSE_CODE_GENERIC_ERROR = 5


class OperationType(betterproto.Enum):
    """Each SDK client is a $service + $component + $operation_type"""

    OPERATION_TYPE_UNSET = 0
    OPERATION_TYPE_CONSUMER = 1
    OPERATION_TYPE_PRODUCER = 2


class TailResponseType(betterproto.Enum):
    TAIL_RESPONSE_TYPE_UNSET = 0
    TAIL_RESPONSE_TYPE_PAYLOAD = 1
    TAIL_RESPONSE_TYPE_ERROR = 2


class TailRequestType(betterproto.Enum):
    TAIL_REQUEST_TYPE_UNSET = 0
    TAIL_REQUEST_TYPE_START = 1
    TAIL_REQUEST_TYPE_STOP = 2


class PipelineStepCondition(betterproto.Enum):
    """
    A condition defines how the SDK should handle a step response -- should it
    continue executing the pipeline, should it abort, should it notify the
    server? Each step can have multiple conditions.
    """

    PIPELINE_STEP_CONDITION_UNSET = 0
    PIPELINE_STEP_CONDITION_ABORT = 1
    PIPELINE_STEP_CONDITION_NOTIFY = 2


class ClientType(betterproto.Enum):
    CLIENT_TYPE_UNSET = 0
    CLIENT_TYPE_SDK = 1
    CLIENT_TYPE_SHIM = 2


class NotificationType(betterproto.Enum):
    NOTIFICATION_TYPE_UNSET = 0
    NOTIFICATION_TYPE_SLACK = 1
    NOTIFICATION_TYPE_EMAIL = 2
    NOTIFICATION_TYPE_PAGERDUTY = 3


class NotificationEmailType(betterproto.Enum):
    TYPE_UNSET = 0
    TYPE_SMTP = 1
    TYPE_SES = 2


class NotificationPagerDutyUrgency(betterproto.Enum):
    URGENCY_UNSET = 0
    URGENCY_LOW = 1
    URGENCY_HIGH = 2


class RegistrationStatusStatus(betterproto.Enum):
    STATUS_UNSET = 0
    STATUS_SUBMIT = 1
    """Submit means the user is not registered yet"""

    STATUS_VERIFY = 2
    """Verify means the user is registered but not verified yet"""

    STATUS_DONE = 3
    """Done means the user is registered and verified"""


class WasmExitCode(betterproto.Enum):
    """
    Included in WASM response; the SDK should use the WASMExitCode to determine
    what to do next - should it execute next step, should it notify or should
    it stop executing/abort the rest of the steps in the pipeline. Example: a.
    WASM func returns WASM_EXIT_CODE_FAILURE - read PipelineStep.on_failure
    conditions to determine what to do next. b. WASM func returns
    WASM_EXIT_CODE_SUCCESS - read PipelineStep.on_success conditions to
    determine what to do next. .. and so on. protolint:disable:next
    ENUM_FIELD_NAMES_PREFIX
    """

    WASM_EXIT_CODE_UNSET = 0
    WASM_EXIT_CODE_SUCCESS = 1
    WASM_EXIT_CODE_FAILURE = 2
    WASM_EXIT_CODE_INTERNAL_ERROR = 3


@dataclass(eq=False, repr=False)
class StandardResponse(betterproto.Message):
    """Common response message for many gRPC methods"""

    id: str = betterproto.string_field(1)
    """Co-relation ID for the request / response"""

    code: "ResponseCode" = betterproto.enum_field(2)
    message: str = betterproto.string_field(3)


@dataclass(eq=False, repr=False)
class Audience(betterproto.Message):
    """Used to indicate who a command is intended for"""

    service_name: str = betterproto.string_field(1)
    """
    Name of the service -- let's include the service name on all calls, we can
    optimize later ~DS
    """

    component_name: str = betterproto.string_field(2)
    """
    Name of the component the SDK is interacting with (ie. kafka-$topic-name)
    """

    operation_type: "OperationType" = betterproto.enum_field(3)
    """Consumer or Producer"""

    operation_name: str = betterproto.string_field(4)
    """Name for the consumer or producer"""


@dataclass(eq=False, repr=False)
class Metric(betterproto.Message):
    name: str = betterproto.string_field(1)
    labels: Dict[str, str] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )
    value: float = betterproto.double_field(3)
    audience: "Audience" = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class TailRequest(betterproto.Message):
    type: "TailRequestType" = betterproto.enum_field(1)
    id: Optional[str] = betterproto.string_field(2, optional=True, group="X_id")
    audience: "Audience" = betterproto.message_field(3)
    pipeline_id: Optional[str] = betterproto.string_field(
        4, optional=True, group="_pipeline_id"
    )
    metadata: Dict[str, str] = betterproto.map_field(
        1000, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )


@dataclass(eq=False, repr=False)
class TailResponse(betterproto.Message):
    """
    TailResponse originates in the SDK and then is sent to snitch servers where
    it is forwarded to the correct frontend streaming gRPC connection
    """

    type: "TailResponseType" = betterproto.enum_field(1)
    tail_request_id: str = betterproto.string_field(2)
    audience: "Audience" = betterproto.message_field(3)
    pipeline_id: str = betterproto.string_field(4)
    session_id: str = betterproto.string_field(5)
    timestamp_ns: int = betterproto.int64_field(6)
    """Timestamp in nanoseconds"""

    original_data: bytes = betterproto.bytes_field(7)
    """
    Payload data. For errors, this will be the error message For payloads, this
    will be JSON of the payload data, post processing
    """

    new_data: bytes = betterproto.bytes_field(8)
    """For payloads, this will be the new data, post processing"""

    metadata: Dict[str, str] = betterproto.map_field(
        1000, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )


@dataclass(eq=False, repr=False)
class AudienceRate(betterproto.Message):
    bytes: int = betterproto.int64_field(1)
    processed: int = betterproto.int64_field(2)


@dataclass(eq=False, repr=False)
class Schema(betterproto.Message):
    json_schema: bytes = betterproto.bytes_field(1)
    version: int = betterproto.int32_field(100)
    metadata: Dict[str, str] = betterproto.map_field(
        1000, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )


@dataclass(eq=False, repr=False)
class Pipeline(betterproto.Message):
    """
    Pipeline is a structure that holds one or more pipeline steps. This
    structure is intended to be immutable; clients are expected to generate
    WASMRequest's that contain a pipeline step.
    """

    id: str = betterproto.string_field(1)
    """
    ID should NOT be set by external gRPC client on CreatePipelineRequest - it
    will be ignored; it _does_ need to be set on UpdatePipelineRequest.
    """

    name: str = betterproto.string_field(2)
    """Friendly name for the pipeline"""

    steps: List["PipelineStep"] = betterproto.message_field(3)
    """One or more steps to execute"""


@dataclass(eq=False, repr=False)
class PipelineStep(betterproto.Message):
    """A pipeline step is a single step in a pipeline."""

    name: str = betterproto.string_field(1)
    """Friendly name for the step"""

    on_success: List["PipelineStepCondition"] = betterproto.enum_field(2)
    """
    SDKs should read this when WASM returns success to determine what to do
    next
    """

    on_failure: List["PipelineStepCondition"] = betterproto.enum_field(3)
    """
    SDKs should read this when WASM returns failure to determine what to do
    next
    """

    detective: "steps.DetectiveStep" = betterproto.message_field(1000, group="step")
    transform: "steps.TransformStep" = betterproto.message_field(1001, group="step")
    encode: "steps.EncodeStep" = betterproto.message_field(1002, group="step")
    decode: "steps.DecodeStep" = betterproto.message_field(1003, group="step")
    custom: "steps.CustomStep" = betterproto.message_field(1004, group="step")
    http_request: "steps.HttpRequestStep" = betterproto.message_field(
        1005, group="step"
    )
    kv: "steps.KvStep" = betterproto.message_field(1006, group="step")
    infer_schema: "steps.InferSchemaStep" = betterproto.message_field(
        1007, group="step"
    )
    wasm_id: Optional[str] = betterproto.string_field(
        10000, optional=True, group="X_wasm_id"
    )
    """ID is a uuid(sha256(_wasm_bytes)) that is set by snitch-server"""

    wasm_bytes: Optional[bytes] = betterproto.bytes_field(
        10001, optional=True, group="X_wasm_bytes"
    )
    """WASM module bytes (set by snitch-server)"""

    wasm_function: Optional[str] = betterproto.string_field(
        10002, optional=True, group="X_wasm_function"
    )
    """WASM function name to execute (set by snitch-server)"""


@dataclass(eq=False, repr=False)
class LiveInfo(betterproto.Message):
    audiences: List["Audience"] = betterproto.message_field(1)
    """If empty, client has not announced any audiences"""

    client: "ClientInfo" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class PipelineInfo(betterproto.Message):
    audiences: List["Audience"] = betterproto.message_field(1)
    """What audience(s) this pipeline is attached to (none if empty)"""

    pipeline: "Pipeline" = betterproto.message_field(2)
    """Pipeline config"""

    paused: List["Audience"] = betterproto.message_field(3)
    """For what audiences this pipeline is paused (none if empty)"""


@dataclass(eq=False, repr=False)
class ClientInfo(betterproto.Message):
    """
    Most of this is constructed by client SDKs and provided during Register
    call
    """

    client_type: "ClientType" = betterproto.enum_field(1)
    library_name: str = betterproto.string_field(2)
    library_version: str = betterproto.string_field(3)
    language: str = betterproto.string_field(4)
    arch: str = betterproto.string_field(5)
    os: str = betterproto.string_field(6)
    session_id: Optional[str] = betterproto.string_field(
        7, optional=True, group="X_session_id"
    )
    """Filled out by snitch_server on GetAll()"""

    service_name: Optional[str] = betterproto.string_field(
        8, optional=True, group="X_service_name"
    )
    node_name: Optional[str] = betterproto.string_field(
        9, optional=True, group="X_node_name"
    )


@dataclass(eq=False, repr=False)
class NotificationConfig(betterproto.Message):
    id: Optional[str] = betterproto.string_field(1, optional=True, group="_id")
    name: str = betterproto.string_field(2)
    type: "NotificationType" = betterproto.enum_field(3)
    slack: "NotificationSlack" = betterproto.message_field(1000, group="config")
    email: "NotificationEmail" = betterproto.message_field(1001, group="config")
    pagerduty: "NotificationPagerDuty" = betterproto.message_field(1002, group="config")


@dataclass(eq=False, repr=False)
class NotificationSlack(betterproto.Message):
    bot_token: str = betterproto.string_field(1)
    channel: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class NotificationEmail(betterproto.Message):
    type: "NotificationEmailType" = betterproto.enum_field(1)
    recipients: List[str] = betterproto.string_field(2)
    from_address: str = betterproto.string_field(3)
    smtp: "NotificationEmailSmtp" = betterproto.message_field(1000, group="config")
    ses: "NotificationEmailSes" = betterproto.message_field(1001, group="config")


@dataclass(eq=False, repr=False)
class NotificationEmailSmtp(betterproto.Message):
    host: str = betterproto.string_field(1)
    port: int = betterproto.int32_field(2)
    user: str = betterproto.string_field(3)
    password: str = betterproto.string_field(4)
    use_tls: bool = betterproto.bool_field(5)


@dataclass(eq=False, repr=False)
class NotificationEmailSes(betterproto.Message):
    ses_region: str = betterproto.string_field(1)
    ses_access_key_id: str = betterproto.string_field(2)
    ses_secret_access_key: str = betterproto.string_field(3)


@dataclass(eq=False, repr=False)
class NotificationPagerDuty(betterproto.Message):
    token: str = betterproto.string_field(1)
    """Auth token"""

    email: str = betterproto.string_field(2)
    """Must be a valid email for a PagerDuty user"""

    service_id: str = betterproto.string_field(3)
    """Must be a valid PagerDuty service"""

    urgency: "NotificationPagerDutyUrgency" = betterproto.enum_field(4)


@dataclass(eq=False, repr=False)
class GetAllRequest(betterproto.Message):
    pass


@dataclass(eq=False, repr=False)
class GetAllResponse(betterproto.Message):
    live: List["LiveInfo"] = betterproto.message_field(1)
    """Clients currently connected to the server"""

    audiences: List["Audience"] = betterproto.message_field(2)
    """All of the audiences that are known to the server"""

    pipelines: Dict[str, "PipelineInfo"] = betterproto.map_field(
        3, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    """
    All of the pipelines known to the server + pipeline <-> audience mappings
    key == pipeline_id; if "Audience" is not filled out - pipeline is not
    attached to any audience.
    """

    config: Dict[str, str] = betterproto.map_field(
        4, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )
    """
    Audience to pipeline ID config/mapping. key == $audience_as_string, value =
    $pipeline_id
    """

    generated_at_unix_ts_ns_utc: int = betterproto.int64_field(100)
    """
    When was this response generated. This is useful for determining what is
    the latest update when using GetAllStream().
    """


@dataclass(eq=False, repr=False)
class GetPipelinesRequest(betterproto.Message):
    pass


@dataclass(eq=False, repr=False)
class GetPipelinesResponse(betterproto.Message):
    pipelines: List["Pipeline"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class GetPipelineRequest(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class GetPipelineResponse(betterproto.Message):
    pipeline: "Pipeline" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class CreatePipelineRequest(betterproto.Message):
    pipeline: "Pipeline" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class CreatePipelineResponse(betterproto.Message):
    message: str = betterproto.string_field(1)
    pipeline_id: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class UpdatePipelineRequest(betterproto.Message):
    pipeline: "Pipeline" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class DeletePipelineRequest(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class AttachPipelineRequest(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)
    audience: "Audience" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class DetachPipelineRequest(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)
    audience: "Audience" = betterproto.message_field(2)
    session_ids: List[str] = betterproto.string_field(3)
    """
    Filled out by detach gRPC handler so that broadcast handlers can avoid
    performing a lookup in NATS.
    """


@dataclass(eq=False, repr=False)
class PausePipelineRequest(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)
    audience: "Audience" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class ResumePipelineRequest(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)
    audience: "Audience" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class CreateNotificationRequest(betterproto.Message):
    """Notifications"""

    notification: "NotificationConfig" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class UpdateNotificationRequest(betterproto.Message):
    notification: "NotificationConfig" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class DeleteNotificationRequest(betterproto.Message):
    notification_id: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class GetNotificationsRequest(betterproto.Message):
    pass


@dataclass(eq=False, repr=False)
class GetNotificationsResponse(betterproto.Message):
    notifications: Dict[str, "NotificationConfig"] = betterproto.map_field(
        1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    """Key == id of the notification config"""


@dataclass(eq=False, repr=False)
class GetNotificationRequest(betterproto.Message):
    notification_id: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class GetNotificationResponse(betterproto.Message):
    notification: "NotificationConfig" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class AttachNotificationRequest(betterproto.Message):
    notification_id: str = betterproto.string_field(1)
    pipeline_id: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class DetachNotificationRequest(betterproto.Message):
    notification_id: str = betterproto.string_field(1)
    pipeline_id: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class DeleteAudienceRequest(betterproto.Message):
    audience: "Audience" = betterproto.message_field(1)
    force: Optional[bool] = betterproto.bool_field(2, optional=True, group="_force")
    """
    If true, will also detach all pipelines from the audience (if it has any)
    """


@dataclass(eq=False, repr=False)
class DeleteServiceRequest(betterproto.Message):
    service_name: str = betterproto.string_field(1)
    force: Optional[bool] = betterproto.bool_field(2, optional=True, group="_force")


@dataclass(eq=False, repr=False)
class GetMetricsRequest(betterproto.Message):
    pass


@dataclass(eq=False, repr=False)
class GetMetricsResponse(betterproto.Message):
    metrics: Dict[str, "Metric"] = betterproto.map_field(
        1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )


@dataclass(eq=False, repr=False)
class GetAudienceRatesRequest(betterproto.Message):
    pass


@dataclass(eq=False, repr=False)
class GetAudienceRatesResponse(betterproto.Message):
    rates: Dict[str, "AudienceRate"] = betterproto.map_field(
        1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )


@dataclass(eq=False, repr=False)
class GetSchemaRequest(betterproto.Message):
    audience: "Audience" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class GetSchemaResponse(betterproto.Message):
    schema: "Schema" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class TestRequest(betterproto.Message):
    input: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class TestResponse(betterproto.Message):
    output: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class KvObject(betterproto.Message):
    """
    KVObject represents a single KV object used in protos.KVInstruction; this
    is constructed by snitch-server and broadcasted out to other snitch-server
    nodes.
    """

    key: str = betterproto.string_field(1)
    """Valid key regex: /^[a-zA-Z0-9_-:]+$/)"""

    value: bytes = betterproto.bytes_field(2)
    """KV value"""

    created_at_unix_ts_nano_utc: int = betterproto.int64_field(3)
    """When was this object created"""

    updated_at_unix_ts_nano_utc: int = betterproto.int64_field(4)
    """Last time the object was updated"""


@dataclass(eq=False, repr=False)
class KvInstruction(betterproto.Message):
    """
    Container for one or more KVObject's; snitch-server broadcasts KVCommand
    that contains one or more of these instructions when a "POST /api/v1/kv"
    request is made.
    """

    id: str = betterproto.string_field(1)
    """Unique ID for this instruction"""

    action: "shared.KvAction" = betterproto.enum_field(2)
    """What kind of an action is this?"""

    object: "KvObject" = betterproto.message_field(3)
    """KV object"""

    requested_at_unix_ts_nano_utc: int = betterproto.int64_field(4)
    """
    When this instruction was requested (usually will be the HTTP API request
    time)
    """


@dataclass(eq=False, repr=False)
class KvRequest(betterproto.Message):
    """
    Used for broadcasting KV instructions to other snitch-server nodes. NOTE:
    While this data structure is similar to KVCommand it makes sense to keep
    them separate. It would cause more confusion if we tried to re-use
    KVCommand for the purpose of broadcasting AND for sending SDK commands. ~DS
    This request structure is used for including all updates -
    create/update/delete.
    """

    instructions: List["KvInstruction"] = betterproto.message_field(1)
    overwrite: bool = betterproto.bool_field(2)


@dataclass(eq=False, repr=False)
class KvCreateHttpRequest(betterproto.Message):
    """
    "POST /api/v1/kv" accepts JSON of this type for it's request payload. This
    is converted by BroadcastKV() to a KVCommand
    """

    kvs: List["KvObject"] = betterproto.message_field(1)
    overwrite: bool = betterproto.bool_field(2)
    """
    Whether to treat create as upsert -- ie. do not error if key already exists
    """


@dataclass(eq=False, repr=False)
class KvUpdateHttpRequest(betterproto.Message):
    kvs: List["KvObject"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class Command(betterproto.Message):
    """Command is used by snitch-server for sending commands to SDKs"""

    audience: "Audience" = betterproto.message_field(1)
    """
    Who is this command intended for? NOTE: Some commands (such as
    KeepAliveCommand, KVCommand) do NOT use audience and will ignore it
    """

    attach_pipeline: "AttachPipelineCommand" = betterproto.message_field(
        100, group="command"
    )
    detach_pipeline: "DetachPipelineCommand" = betterproto.message_field(
        101, group="command"
    )
    pause_pipeline: "PausePipelineCommand" = betterproto.message_field(
        102, group="command"
    )
    resume_pipeline: "ResumePipelineCommand" = betterproto.message_field(
        103, group="command"
    )
    keep_alive: "KeepAliveCommand" = betterproto.message_field(104, group="command")
    kv: "KvCommand" = betterproto.message_field(105, group="command")
    """
    snitch-server will emit this when a user makes changes to the KV store via
    the KV HTTP API.
    """

    tail: "TailCommand" = betterproto.message_field(106, group="command")
    """
    Emitted by snitch-server when a user makes a Tail() call Consumed by all
    snitch-server instances and by SDKs
    """


@dataclass(eq=False, repr=False)
class AttachPipelineCommand(betterproto.Message):
    pipeline: "Pipeline" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class DetachPipelineCommand(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class PausePipelineCommand(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class ResumePipelineCommand(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class KeepAliveCommand(betterproto.Message):
    pass


@dataclass(eq=False, repr=False)
class KvCommand(betterproto.Message):
    """Sent by snitch-server on Register channel(s) to live SDKs"""

    instructions: List["KvInstruction"] = betterproto.message_field(1)
    overwrite: bool = betterproto.bool_field(2)
    """
    Create & Update specific setting that will cause the Create or Update to
    work as an upsert.
    """


@dataclass(eq=False, repr=False)
class TailCommand(betterproto.Message):
    request: "TailRequest" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class NewAudienceRequest(betterproto.Message):
    session_id: str = betterproto.string_field(1)
    """The session that is performing this call"""

    audience: "Audience" = betterproto.message_field(2)
    """Newly created audience."""


@dataclass(eq=False, repr=False)
class HeartbeatRequest(betterproto.Message):
    """
    Each consumer and producer should send periodic heartbeats to the server to
    let the server know that they are still active.
    """

    session_id: str = betterproto.string_field(1)
    """Session ID for this instance of the SDK."""

    audiences: List["Audience"] = betterproto.message_field(2)
    client_info: "ClientInfo" = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class NotifyRequest(betterproto.Message):
    pipeline_id: str = betterproto.string_field(1)
    step_name: str = betterproto.string_field(2)
    audience: "Audience" = betterproto.message_field(3)
    occurred_at_unix_ts_utc: int = betterproto.int64_field(4)


@dataclass(eq=False, repr=False)
class MetricsRequest(betterproto.Message):
    metrics: List["Metric"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class RegisterRequest(betterproto.Message):
    service_name: str = betterproto.string_field(1)
    """REQUIRED -- Name of the service that is registering."""

    session_id: str = betterproto.string_field(2)
    """
    REQUIRED -- Unique ID for this SDK instance. This should be generated every
    time the SDK is instantiated (oe. every time a NEW registration is
    performed).
    """

    client_info: "ClientInfo" = betterproto.message_field(3)
    """REQUIRED -- Info about the client (lib name, lang, os, arch, etc.)"""

    audiences: List["Audience"] = betterproto.message_field(4)
    """
    OPTIONAL -- if these are defined, these will show up in the UI even if
    there is no active .Process() call from the SDK.
    """

    dry_run: bool = betterproto.bool_field(5)
    """
    OPTIONAL -- If set, we know that any pipelines or steps executed in this
    SDK will NOT modify the input/output data. As in, the SDK will log what it
    _would_ do and always return the original data set.
    """


@dataclass(eq=False, repr=False)
class DeregisterRequest(betterproto.Message):
    """
    Same as RegisterRequest - used for broadcasting a deregistration event
    """

    service_name: str = betterproto.string_field(1)
    session_id: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class GetAttachCommandsByServiceRequest(betterproto.Message):
    service_name: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class GetAttachCommandsByServiceResponse(betterproto.Message):
    active: List["Command"] = betterproto.message_field(1)
    """AttachCommands for all active pipelines"""

    paused: List["Command"] = betterproto.message_field(2)
    """
    AttachCommands, but ones which are paused The SDK still needs to have these
    to support un-pausing
    """

    wasm_modules: Dict[str, "WasmModule"] = betterproto.map_field(
        3, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    """ID = wasm ID"""


@dataclass(eq=False, repr=False)
class WasmModule(betterproto.Message):
    """
    WasmModule is used to ensure we only send the wasm module once per request
    instead of duplicated in every pipeline where it is used. This prevents
    over-sized payloads on SDK startup
    """

    id: str = betterproto.string_field(1)
    """ID is a uuid(sha256(_wasm_bytes)) that is set by snitch-server"""

    bytes: builtins.bytes = betterproto.bytes_field(2)
    """WASM module bytes (set by snitch-server)"""

    function: str = betterproto.string_field(3)
    """WASM function name to execute (set by snitch-server)"""


@dataclass(eq=False, repr=False)
class SendSchemaRequest(betterproto.Message):
    audience: "Audience" = betterproto.message_field(1)
    schema: "Schema" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class BusEvent(betterproto.Message):
    """
    Type used by `snitch-server` for broadcasting events to other snitch nodes
    """

    source: str = betterproto.string_field(1)
    register_request: "RegisterRequest" = betterproto.message_field(100, group="event")
    deregister_request: "DeregisterRequest" = betterproto.message_field(
        101, group="event"
    )
    create_pipeline_request: "CreatePipelineRequest" = betterproto.message_field(
        102, group="event"
    )
    delete_pipeline_request: "DeletePipelineRequest" = betterproto.message_field(
        103, group="event"
    )
    update_pipeline_request: "UpdatePipelineRequest" = betterproto.message_field(
        104, group="event"
    )
    attach_pipeline_request: "AttachPipelineRequest" = betterproto.message_field(
        105, group="event"
    )
    detach_pipeline_request: "DetachPipelineRequest" = betterproto.message_field(
        106, group="event"
    )
    pause_pipeline_request: "PausePipelineRequest" = betterproto.message_field(
        107, group="event"
    )
    resume_pipeline_request: "ResumePipelineRequest" = betterproto.message_field(
        108, group="event"
    )
    metrics_request: "MetricsRequest" = betterproto.message_field(109, group="event")
    kv_request: "KvRequest" = betterproto.message_field(110, group="event")
    delete_audience_request: "DeleteAudienceRequest" = betterproto.message_field(
        111, group="event"
    )
    new_audience_request: "NewAudienceRequest" = betterproto.message_field(
        112, group="event"
    )
    tail_request: "TailRequest" = betterproto.message_field(113, group="event")
    tail_response: "TailResponse" = betterproto.message_field(114, group="event")
    metadata: Dict[str, str] = betterproto.map_field(
        1000, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )
    """
    All gRPC metadata is stored in ctx; when request goes outside of gRPC
    bounds, we will translate ctx metadata into this field. Example: 1. Request
    comes into snitch-server via external gRPC to set new pipeline 2. snitch-
    server has to send SetPipeline cmd to SDK via gRPC - it passes    on
    original metadata in request. 3. snitch-server has to broadcast SetPipeline
    cmd to other services via bus 4. Since this is not a gRPC call, snitch-
    server translates ctx metadata to    this field and includes it in the bus
    event.
    """


@dataclass(eq=False, repr=False)
class RegistrationStatus(betterproto.Message):
    status: "RegistrationStatusStatus" = betterproto.enum_field(1)


@dataclass(eq=False, repr=False)
class Registration(betterproto.Message):
    email: str = betterproto.string_field(1)
    code: str = betterproto.string_field(100)
    """Used for storage on ui-bff backend"""


@dataclass(eq=False, repr=False)
class Verify(betterproto.Message):
    email: str = betterproto.string_field(1)
    code: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class WasmRequest(betterproto.Message):
    """SDK generates a WASM request and passes this to the WASM func"""

    step: "PipelineStep" = betterproto.message_field(1)
    """
    The actual step that the WASM func will operate on. This is the same step
    that is declared in protos.Pipeline.
    """

    input_payload: bytes = betterproto.bytes_field(2)
    """Payload data that WASM func will operate on"""

    input_step: Optional[bytes] = betterproto.bytes_field(
        3, optional=True, group="_input_step"
    )
    """
    Potentially filled out result from previous step. If this is first step in
    the pipeline, it will be empty.
    """


@dataclass(eq=False, repr=False)
class WasmResponse(betterproto.Message):
    """Returned by all WASM functions"""

    output_payload: bytes = betterproto.bytes_field(1)
    """
    Potentially modified input payload. Concept: All WASM funcs accept an
    input_payload in WASMRequest, WASM func reads input payload, modifies it
    and writes the modified output to output_payload.
    """

    exit_code: "WasmExitCode" = betterproto.enum_field(2)
    """
    Exit code that the WASM func exited with; more info in WASMExitCode's
    comment
    """

    exit_msg: str = betterproto.string_field(3)
    """Additional info about the reason a specific exit code was returned"""

    output_step: Optional[bytes] = betterproto.bytes_field(
        4, optional=True, group="_output_step"
    )
    """
    Potential additional step output - ie. if a WASM func is an HTTPGet,
    output_step would contain the HTTP response body; if the WASM func is a
    KVGet, the output_step would be the value of the fetched key.
    """


class ExternalStub(betterproto.ServiceStub):
    async def get_all(
        self,
        get_all_request: "GetAllRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetAllResponse":
        return await self._unary_unary(
            "/protos.External/GetAll",
            get_all_request,
            GetAllResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_all_stream(
        self,
        get_all_request: "GetAllRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["GetAllResponse"]:
        async for response in self._unary_stream(
            "/protos.External/GetAllStream",
            get_all_request,
            GetAllResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_pipelines(
        self,
        get_pipelines_request: "GetPipelinesRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetPipelinesResponse":
        return await self._unary_unary(
            "/protos.External/GetPipelines",
            get_pipelines_request,
            GetPipelinesResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_pipeline(
        self,
        get_pipeline_request: "GetPipelineRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetPipelineResponse":
        return await self._unary_unary(
            "/protos.External/GetPipeline",
            get_pipeline_request,
            GetPipelineResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def create_pipeline(
        self,
        create_pipeline_request: "CreatePipelineRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "CreatePipelineResponse":
        return await self._unary_unary(
            "/protos.External/CreatePipeline",
            create_pipeline_request,
            CreatePipelineResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def update_pipeline(
        self,
        update_pipeline_request: "UpdatePipelineRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/UpdatePipeline",
            update_pipeline_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_pipeline(
        self,
        delete_pipeline_request: "DeletePipelineRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/DeletePipeline",
            delete_pipeline_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def attach_pipeline(
        self,
        attach_pipeline_request: "AttachPipelineRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/AttachPipeline",
            attach_pipeline_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def detach_pipeline(
        self,
        detach_pipeline_request: "DetachPipelineRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/DetachPipeline",
            detach_pipeline_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def pause_pipeline(
        self,
        pause_pipeline_request: "PausePipelineRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/PausePipeline",
            pause_pipeline_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def resume_pipeline(
        self,
        resume_pipeline_request: "ResumePipelineRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/ResumePipeline",
            resume_pipeline_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def create_notification(
        self,
        create_notification_request: "CreateNotificationRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/CreateNotification",
            create_notification_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def update_notification(
        self,
        update_notification_request: "UpdateNotificationRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/UpdateNotification",
            update_notification_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_notification(
        self,
        delete_notification_request: "DeleteNotificationRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/DeleteNotification",
            delete_notification_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_notifications(
        self,
        get_notifications_request: "GetNotificationsRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetNotificationsResponse":
        return await self._unary_unary(
            "/protos.External/GetNotifications",
            get_notifications_request,
            GetNotificationsResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_notification(
        self,
        get_notification_request: "GetNotificationRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetNotificationResponse":
        return await self._unary_unary(
            "/protos.External/GetNotification",
            get_notification_request,
            GetNotificationResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def attach_notification(
        self,
        attach_notification_request: "AttachNotificationRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/AttachNotification",
            attach_notification_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def detach_notification(
        self,
        detach_notification_request: "DetachNotificationRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/DetachNotification",
            detach_notification_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_audience(
        self,
        delete_audience_request: "DeleteAudienceRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/DeleteAudience",
            delete_audience_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_service(
        self,
        delete_service_request: "DeleteServiceRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.External/DeleteService",
            delete_service_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_metrics(
        self,
        get_metrics_request: "GetMetricsRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["GetMetricsResponse"]:
        async for response in self._unary_stream(
            "/protos.External/GetMetrics",
            get_metrics_request,
            GetMetricsResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def tail(
        self,
        tail_request: "TailRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["TailResponse"]:
        async for response in self._unary_stream(
            "/protos.External/Tail",
            tail_request,
            TailResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_audience_rates(
        self,
        get_audience_rates_request: "GetAudienceRatesRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["GetAudienceRatesResponse"]:
        async for response in self._unary_stream(
            "/protos.External/GetAudienceRates",
            get_audience_rates_request,
            GetAudienceRatesResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def get_schema(
        self,
        get_schema_request: "GetSchemaRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetSchemaResponse":
        return await self._unary_unary(
            "/protos.External/GetSchema",
            get_schema_request,
            GetSchemaResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def test(
        self,
        test_request: "TestRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "TestResponse":
        return await self._unary_unary(
            "/protos.External/Test",
            test_request,
            TestResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class InternalStub(betterproto.ServiceStub):
    async def register(
        self,
        register_request: "RegisterRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["Command"]:
        async for response in self._unary_stream(
            "/protos.Internal/Register",
            register_request,
            Command,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def new_audience(
        self,
        new_audience_request: "NewAudienceRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.Internal/NewAudience",
            new_audience_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def heartbeat(
        self,
        heartbeat_request: "HeartbeatRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.Internal/Heartbeat",
            heartbeat_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def notify(
        self,
        notify_request: "NotifyRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.Internal/Notify",
            notify_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def metrics(
        self,
        metrics_request: "MetricsRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.Internal/Metrics",
            metrics_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def get_attach_commands_by_service(
        self,
        get_attach_commands_by_service_request: "GetAttachCommandsByServiceRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "GetAttachCommandsByServiceResponse":
        return await self._unary_unary(
            "/protos.Internal/GetAttachCommandsByService",
            get_attach_commands_by_service_request,
            GetAttachCommandsByServiceResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def send_tail(
        self,
        tail_response_iterator: Union[
            AsyncIterable["TailResponse"], Iterable["TailResponse"]
        ],
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._stream_unary(
            "/protos.Internal/SendTail",
            tail_response_iterator,
            TailResponse,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def send_schema(
        self,
        send_schema_request: "SendSchemaRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "StandardResponse":
        return await self._unary_unary(
            "/protos.Internal/SendSchema",
            send_schema_request,
            StandardResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class ExternalBase(ServiceBase):
    async def get_all(self, get_all_request: "GetAllRequest") -> "GetAllResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_all_stream(
        self, get_all_request: "GetAllRequest"
    ) -> AsyncIterator["GetAllResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetAllResponse()

    async def get_pipelines(
        self, get_pipelines_request: "GetPipelinesRequest"
    ) -> "GetPipelinesResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_pipeline(
        self, get_pipeline_request: "GetPipelineRequest"
    ) -> "GetPipelineResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def create_pipeline(
        self, create_pipeline_request: "CreatePipelineRequest"
    ) -> "CreatePipelineResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def update_pipeline(
        self, update_pipeline_request: "UpdatePipelineRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_pipeline(
        self, delete_pipeline_request: "DeletePipelineRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def attach_pipeline(
        self, attach_pipeline_request: "AttachPipelineRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def detach_pipeline(
        self, detach_pipeline_request: "DetachPipelineRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def pause_pipeline(
        self, pause_pipeline_request: "PausePipelineRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def resume_pipeline(
        self, resume_pipeline_request: "ResumePipelineRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def create_notification(
        self, create_notification_request: "CreateNotificationRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def update_notification(
        self, update_notification_request: "UpdateNotificationRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_notification(
        self, delete_notification_request: "DeleteNotificationRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_notifications(
        self, get_notifications_request: "GetNotificationsRequest"
    ) -> "GetNotificationsResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_notification(
        self, get_notification_request: "GetNotificationRequest"
    ) -> "GetNotificationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def attach_notification(
        self, attach_notification_request: "AttachNotificationRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def detach_notification(
        self, detach_notification_request: "DetachNotificationRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_audience(
        self, delete_audience_request: "DeleteAudienceRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_service(
        self, delete_service_request: "DeleteServiceRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_metrics(
        self, get_metrics_request: "GetMetricsRequest"
    ) -> AsyncIterator["GetMetricsResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetMetricsResponse()

    async def tail(self, tail_request: "TailRequest") -> AsyncIterator["TailResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield TailResponse()

    async def get_audience_rates(
        self, get_audience_rates_request: "GetAudienceRatesRequest"
    ) -> AsyncIterator["GetAudienceRatesResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield GetAudienceRatesResponse()

    async def get_schema(
        self, get_schema_request: "GetSchemaRequest"
    ) -> "GetSchemaResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def test(self, test_request: "TestRequest") -> "TestResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get_all(
        self, stream: "grpclib.server.Stream[GetAllRequest, GetAllResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_all(request)
        await stream.send_message(response)

    async def __rpc_get_all_stream(
        self, stream: "grpclib.server.Stream[GetAllRequest, GetAllResponse]"
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_all_stream,
            stream,
            request,
        )

    async def __rpc_get_pipelines(
        self, stream: "grpclib.server.Stream[GetPipelinesRequest, GetPipelinesResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_pipelines(request)
        await stream.send_message(response)

    async def __rpc_get_pipeline(
        self, stream: "grpclib.server.Stream[GetPipelineRequest, GetPipelineResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_pipeline(request)
        await stream.send_message(response)

    async def __rpc_create_pipeline(
        self,
        stream: "grpclib.server.Stream[CreatePipelineRequest, CreatePipelineResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.create_pipeline(request)
        await stream.send_message(response)

    async def __rpc_update_pipeline(
        self, stream: "grpclib.server.Stream[UpdatePipelineRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.update_pipeline(request)
        await stream.send_message(response)

    async def __rpc_delete_pipeline(
        self, stream: "grpclib.server.Stream[DeletePipelineRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_pipeline(request)
        await stream.send_message(response)

    async def __rpc_attach_pipeline(
        self, stream: "grpclib.server.Stream[AttachPipelineRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.attach_pipeline(request)
        await stream.send_message(response)

    async def __rpc_detach_pipeline(
        self, stream: "grpclib.server.Stream[DetachPipelineRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.detach_pipeline(request)
        await stream.send_message(response)

    async def __rpc_pause_pipeline(
        self, stream: "grpclib.server.Stream[PausePipelineRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.pause_pipeline(request)
        await stream.send_message(response)

    async def __rpc_resume_pipeline(
        self, stream: "grpclib.server.Stream[ResumePipelineRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.resume_pipeline(request)
        await stream.send_message(response)

    async def __rpc_create_notification(
        self,
        stream: "grpclib.server.Stream[CreateNotificationRequest, StandardResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.create_notification(request)
        await stream.send_message(response)

    async def __rpc_update_notification(
        self,
        stream: "grpclib.server.Stream[UpdateNotificationRequest, StandardResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.update_notification(request)
        await stream.send_message(response)

    async def __rpc_delete_notification(
        self,
        stream: "grpclib.server.Stream[DeleteNotificationRequest, StandardResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_notification(request)
        await stream.send_message(response)

    async def __rpc_get_notifications(
        self,
        stream: "grpclib.server.Stream[GetNotificationsRequest, GetNotificationsResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_notifications(request)
        await stream.send_message(response)

    async def __rpc_get_notification(
        self,
        stream: "grpclib.server.Stream[GetNotificationRequest, GetNotificationResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_notification(request)
        await stream.send_message(response)

    async def __rpc_attach_notification(
        self,
        stream: "grpclib.server.Stream[AttachNotificationRequest, StandardResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.attach_notification(request)
        await stream.send_message(response)

    async def __rpc_detach_notification(
        self,
        stream: "grpclib.server.Stream[DetachNotificationRequest, StandardResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.detach_notification(request)
        await stream.send_message(response)

    async def __rpc_delete_audience(
        self, stream: "grpclib.server.Stream[DeleteAudienceRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_audience(request)
        await stream.send_message(response)

    async def __rpc_delete_service(
        self, stream: "grpclib.server.Stream[DeleteServiceRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_service(request)
        await stream.send_message(response)

    async def __rpc_get_metrics(
        self, stream: "grpclib.server.Stream[GetMetricsRequest, GetMetricsResponse]"
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_metrics,
            stream,
            request,
        )

    async def __rpc_tail(
        self, stream: "grpclib.server.Stream[TailRequest, TailResponse]"
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.tail,
            stream,
            request,
        )

    async def __rpc_get_audience_rates(
        self,
        stream: "grpclib.server.Stream[GetAudienceRatesRequest, GetAudienceRatesResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.get_audience_rates,
            stream,
            request,
        )

    async def __rpc_get_schema(
        self, stream: "grpclib.server.Stream[GetSchemaRequest, GetSchemaResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_schema(request)
        await stream.send_message(response)

    async def __rpc_test(
        self, stream: "grpclib.server.Stream[TestRequest, TestResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.test(request)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/protos.External/GetAll": grpclib.const.Handler(
                self.__rpc_get_all,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetAllRequest,
                GetAllResponse,
            ),
            "/protos.External/GetAllStream": grpclib.const.Handler(
                self.__rpc_get_all_stream,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetAllRequest,
                GetAllResponse,
            ),
            "/protos.External/GetPipelines": grpclib.const.Handler(
                self.__rpc_get_pipelines,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetPipelinesRequest,
                GetPipelinesResponse,
            ),
            "/protos.External/GetPipeline": grpclib.const.Handler(
                self.__rpc_get_pipeline,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetPipelineRequest,
                GetPipelineResponse,
            ),
            "/protos.External/CreatePipeline": grpclib.const.Handler(
                self.__rpc_create_pipeline,
                grpclib.const.Cardinality.UNARY_UNARY,
                CreatePipelineRequest,
                CreatePipelineResponse,
            ),
            "/protos.External/UpdatePipeline": grpclib.const.Handler(
                self.__rpc_update_pipeline,
                grpclib.const.Cardinality.UNARY_UNARY,
                UpdatePipelineRequest,
                StandardResponse,
            ),
            "/protos.External/DeletePipeline": grpclib.const.Handler(
                self.__rpc_delete_pipeline,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeletePipelineRequest,
                StandardResponse,
            ),
            "/protos.External/AttachPipeline": grpclib.const.Handler(
                self.__rpc_attach_pipeline,
                grpclib.const.Cardinality.UNARY_UNARY,
                AttachPipelineRequest,
                StandardResponse,
            ),
            "/protos.External/DetachPipeline": grpclib.const.Handler(
                self.__rpc_detach_pipeline,
                grpclib.const.Cardinality.UNARY_UNARY,
                DetachPipelineRequest,
                StandardResponse,
            ),
            "/protos.External/PausePipeline": grpclib.const.Handler(
                self.__rpc_pause_pipeline,
                grpclib.const.Cardinality.UNARY_UNARY,
                PausePipelineRequest,
                StandardResponse,
            ),
            "/protos.External/ResumePipeline": grpclib.const.Handler(
                self.__rpc_resume_pipeline,
                grpclib.const.Cardinality.UNARY_UNARY,
                ResumePipelineRequest,
                StandardResponse,
            ),
            "/protos.External/CreateNotification": grpclib.const.Handler(
                self.__rpc_create_notification,
                grpclib.const.Cardinality.UNARY_UNARY,
                CreateNotificationRequest,
                StandardResponse,
            ),
            "/protos.External/UpdateNotification": grpclib.const.Handler(
                self.__rpc_update_notification,
                grpclib.const.Cardinality.UNARY_UNARY,
                UpdateNotificationRequest,
                StandardResponse,
            ),
            "/protos.External/DeleteNotification": grpclib.const.Handler(
                self.__rpc_delete_notification,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteNotificationRequest,
                StandardResponse,
            ),
            "/protos.External/GetNotifications": grpclib.const.Handler(
                self.__rpc_get_notifications,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetNotificationsRequest,
                GetNotificationsResponse,
            ),
            "/protos.External/GetNotification": grpclib.const.Handler(
                self.__rpc_get_notification,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetNotificationRequest,
                GetNotificationResponse,
            ),
            "/protos.External/AttachNotification": grpclib.const.Handler(
                self.__rpc_attach_notification,
                grpclib.const.Cardinality.UNARY_UNARY,
                AttachNotificationRequest,
                StandardResponse,
            ),
            "/protos.External/DetachNotification": grpclib.const.Handler(
                self.__rpc_detach_notification,
                grpclib.const.Cardinality.UNARY_UNARY,
                DetachNotificationRequest,
                StandardResponse,
            ),
            "/protos.External/DeleteAudience": grpclib.const.Handler(
                self.__rpc_delete_audience,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteAudienceRequest,
                StandardResponse,
            ),
            "/protos.External/DeleteService": grpclib.const.Handler(
                self.__rpc_delete_service,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteServiceRequest,
                StandardResponse,
            ),
            "/protos.External/GetMetrics": grpclib.const.Handler(
                self.__rpc_get_metrics,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetMetricsRequest,
                GetMetricsResponse,
            ),
            "/protos.External/Tail": grpclib.const.Handler(
                self.__rpc_tail,
                grpclib.const.Cardinality.UNARY_STREAM,
                TailRequest,
                TailResponse,
            ),
            "/protos.External/GetAudienceRates": grpclib.const.Handler(
                self.__rpc_get_audience_rates,
                grpclib.const.Cardinality.UNARY_STREAM,
                GetAudienceRatesRequest,
                GetAudienceRatesResponse,
            ),
            "/protos.External/GetSchema": grpclib.const.Handler(
                self.__rpc_get_schema,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetSchemaRequest,
                GetSchemaResponse,
            ),
            "/protos.External/Test": grpclib.const.Handler(
                self.__rpc_test,
                grpclib.const.Cardinality.UNARY_UNARY,
                TestRequest,
                TestResponse,
            ),
        }


class InternalBase(ServiceBase):
    async def register(
        self, register_request: "RegisterRequest"
    ) -> AsyncIterator["Command"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield Command()

    async def new_audience(
        self, new_audience_request: "NewAudienceRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def heartbeat(
        self, heartbeat_request: "HeartbeatRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def notify(self, notify_request: "NotifyRequest") -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def metrics(self, metrics_request: "MetricsRequest") -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get_attach_commands_by_service(
        self,
        get_attach_commands_by_service_request: "GetAttachCommandsByServiceRequest",
    ) -> "GetAttachCommandsByServiceResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def send_tail(
        self, tail_response_iterator: AsyncIterator["TailResponse"]
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def send_schema(
        self, send_schema_request: "SendSchemaRequest"
    ) -> "StandardResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_register(
        self, stream: "grpclib.server.Stream[RegisterRequest, Command]"
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.register,
            stream,
            request,
        )

    async def __rpc_new_audience(
        self, stream: "grpclib.server.Stream[NewAudienceRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.new_audience(request)
        await stream.send_message(response)

    async def __rpc_heartbeat(
        self, stream: "grpclib.server.Stream[HeartbeatRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.heartbeat(request)
        await stream.send_message(response)

    async def __rpc_notify(
        self, stream: "grpclib.server.Stream[NotifyRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.notify(request)
        await stream.send_message(response)

    async def __rpc_metrics(
        self, stream: "grpclib.server.Stream[MetricsRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.metrics(request)
        await stream.send_message(response)

    async def __rpc_get_attach_commands_by_service(
        self,
        stream: "grpclib.server.Stream[GetAttachCommandsByServiceRequest, GetAttachCommandsByServiceResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_attach_commands_by_service(request)
        await stream.send_message(response)

    async def __rpc_send_tail(
        self, stream: "grpclib.server.Stream[TailResponse, StandardResponse]"
    ) -> None:
        request = stream.__aiter__()
        response = await self.send_tail(request)
        await stream.send_message(response)

    async def __rpc_send_schema(
        self, stream: "grpclib.server.Stream[SendSchemaRequest, StandardResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.send_schema(request)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/protos.Internal/Register": grpclib.const.Handler(
                self.__rpc_register,
                grpclib.const.Cardinality.UNARY_STREAM,
                RegisterRequest,
                Command,
            ),
            "/protos.Internal/NewAudience": grpclib.const.Handler(
                self.__rpc_new_audience,
                grpclib.const.Cardinality.UNARY_UNARY,
                NewAudienceRequest,
                StandardResponse,
            ),
            "/protos.Internal/Heartbeat": grpclib.const.Handler(
                self.__rpc_heartbeat,
                grpclib.const.Cardinality.UNARY_UNARY,
                HeartbeatRequest,
                StandardResponse,
            ),
            "/protos.Internal/Notify": grpclib.const.Handler(
                self.__rpc_notify,
                grpclib.const.Cardinality.UNARY_UNARY,
                NotifyRequest,
                StandardResponse,
            ),
            "/protos.Internal/Metrics": grpclib.const.Handler(
                self.__rpc_metrics,
                grpclib.const.Cardinality.UNARY_UNARY,
                MetricsRequest,
                StandardResponse,
            ),
            "/protos.Internal/GetAttachCommandsByService": grpclib.const.Handler(
                self.__rpc_get_attach_commands_by_service,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetAttachCommandsByServiceRequest,
                GetAttachCommandsByServiceResponse,
            ),
            "/protos.Internal/SendTail": grpclib.const.Handler(
                self.__rpc_send_tail,
                grpclib.const.Cardinality.STREAM_UNARY,
                TailResponse,
                StandardResponse,
            ),
            "/protos.Internal/SendSchema": grpclib.const.Handler(
                self.__rpc_send_schema,
                grpclib.const.Cardinality.UNARY_UNARY,
                SendSchemaRequest,
                StandardResponse,
            ),
        }
