# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: collections.proto, collections_service.proto, json_with_int.proto, points.proto, points_service.proto, nnext.proto, snapshots_service.proto
# plugin: python-betterproto
import warnings
from dataclasses import dataclass
from datetime import datetime
from typing import Dict, List, Optional

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


class Distance(betterproto.Enum):
    UnknownDistance = 0
    Cosine = 1
    Euclid = 2
    Dot = 3


class CollectionStatus(betterproto.Enum):
    UnknownCollectionStatus = 0
    Green = 1
    Yellow = 2
    Red = 3


class PayloadSchemaType(betterproto.Enum):
    UnknownType = 0
    Keyword = 1
    Integer = 2
    Float = 3
    Geo = 4


class NullValue(betterproto.Enum):
    """
    `NullValue` is a singleton enumeration to represent the null value for the
    `Value` type union.  The JSON representation for `NullValue` is JSON
    `null`.
    """

    # Null value.
    NULL_VALUE = 0


class FieldType(betterproto.Enum):
    FieldTypeKeyword = 0
    FieldTypeInteger = 1
    FieldTypeFloat = 2
    FieldTypeGeo = 3


class UpdateStatus(betterproto.Enum):
    UnknownUpdateStatus = 0
    Acknowledged = 1
    Completed = 2


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


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


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


@dataclass(eq=False, repr=False)
class GetCollectionInfoResponse(betterproto.Message):
    result: "CollectionInfo" = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class ListCollectionsResponse(betterproto.Message):
    collections: List["CollectionDescription"] = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class OptimizerStatus(betterproto.Message):
    ok: bool = betterproto.bool_field(1)
    error: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class HnswConfigDiff(betterproto.Message):
    # Number of edges per node in the index graph. Larger the value - more
    # accurate the search, more space required.
    m: Optional[int] = betterproto.uint64_field(1, optional=True, group="_m")
    # Number of neighbours to consider during the index building. Larger the
    # value - more accurate the search, more time required to build index.
    ef_construct: Optional[int] = betterproto.uint64_field(
        2, optional=True, group="_ef_construct"
    )
    # Minimal size (in KiloBytes) of vectors for additional payload-based
    # indexing.If payload chunk is smaller than `full_scan_threshold` additional
    # indexing won't be used -in this case full-scan search should be preferred
    # by query planner and additional indexing is not required.Note: 1Kb = 1
    # vector of size 256
    full_scan_threshold: Optional[int] = betterproto.uint64_field(
        3, optional=True, group="_full_scan_threshold"
    )
    # Number of parallel threads used for background index building. If 0 - auto
    # selection.
    max_indexing_threads: Optional[int] = betterproto.uint64_field(
        4, optional=True, group="_max_indexing_threads"
    )


@dataclass(eq=False, repr=False)
class WalConfigDiff(betterproto.Message):
    wal_capacity_mb: Optional[int] = betterproto.uint64_field(
        1, optional=True, group="_wal_capacity_mb"
    )
    wal_segments_ahead: Optional[int] = betterproto.uint64_field(
        2, optional=True, group="_wal_segments_ahead"
    )


@dataclass(eq=False, repr=False)
class OptimizersConfigDiff(betterproto.Message):
    # The minimal fraction of deleted vectors in a segment, required to perform
    # segment optimization
    deleted_threshold: Optional[float] = betterproto.double_field(
        1, optional=True, group="_deleted_threshold"
    )
    # The minimal number of vectors in a segment, required to perform segment
    # optimization
    vacuum_min_vector_number: Optional[int] = betterproto.uint64_field(
        2, optional=True, group="_vacuum_min_vector_number"
    )
    # Target amount of segments optimizer will try to keep.Real amount of
    # segments may vary depending on multiple parameters:- Amount of stored
    # points.- Current write RPS.It is recommended to select default number of
    # segments as a factor of the number of search threads,so that each segment
    # would be handled evenly by one of the threads.
    default_segment_number: Optional[int] = betterproto.uint64_field(
        3, optional=True, group="_default_segment_number"
    )
    # Do not create segments larger this size (in KiloBytes).Large segments might
    # require disproportionately long indexation times,therefore it makes sense
    # to limit the size of segments.If indexation speed have more priority for
    # your - make this parameter lower.If search speed is more important - make
    # this parameter higher.Note: 1Kb = 1 vector of size 256
    max_segment_size: Optional[int] = betterproto.uint64_field(
        4, optional=True, group="_max_segment_size"
    )
    # Maximum size (in KiloBytes) of vectors to store in-memory per
    # segment.Segments larger than this threshold will be stored as read-only
    # memmaped file.To enable memmap storage, lower the thresholdNote: 1Kb = 1
    # vector of size 256
    memmap_threshold: Optional[int] = betterproto.uint64_field(
        5, optional=True, group="_memmap_threshold"
    )
    # Maximum size (in KiloBytes) of vectors allowed for plain index.Default
    # value based on https://github.com/google-research/google-
    # research/blob/master/scann/docs/algorithms.mdNote: 1Kb = 1 vector of size
    # 256
    indexing_threshold: Optional[int] = betterproto.uint64_field(
        6, optional=True, group="_indexing_threshold"
    )
    # Interval between forced flushes.
    flush_interval_sec: Optional[int] = betterproto.uint64_field(
        7, optional=True, group="_flush_interval_sec"
    )
    # Max number of threads, which can be used for optimization. If 0 - `NUM_CPU
    # - 1` will be used
    max_optimization_threads: Optional[int] = betterproto.uint64_field(
        8, optional=True, group="_max_optimization_threads"
    )


@dataclass(eq=False, repr=False)
class CreateCollection(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    vector_size: int = betterproto.uint64_field(2)
    distance: "Distance" = betterproto.enum_field(3)
    hnsw_config: Optional["HnswConfigDiff"] = betterproto.message_field(
        4, optional=True, group="_hnsw_config"
    )
    wal_config: Optional["WalConfigDiff"] = betterproto.message_field(
        5, optional=True, group="_wal_config"
    )
    optimizers_config: Optional["OptimizersConfigDiff"] = betterproto.message_field(
        6, optional=True, group="_optimizers_config"
    )
    shard_number: Optional[int] = betterproto.uint32_field(
        7, optional=True, group="_shard_number"
    )
    on_disk_payload: Optional[bool] = betterproto.bool_field(
        8, optional=True, group="_on_disk_payload"
    )
    timeout: Optional[int] = betterproto.uint64_field(
        9, optional=True, group="_timeout"
    )


@dataclass(eq=False, repr=False)
class UpdateCollection(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    optimizers_config: Optional["OptimizersConfigDiff"] = betterproto.message_field(
        2, optional=True, group="_optimizers_config"
    )
    timeout: Optional[int] = betterproto.uint64_field(
        3, optional=True, group="_timeout"
    )


@dataclass(eq=False, repr=False)
class DeleteCollection(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    timeout: Optional[int] = betterproto.uint64_field(
        2, optional=True, group="_timeout"
    )


@dataclass(eq=False, repr=False)
class CollectionOperationResponse(betterproto.Message):
    result: bool = betterproto.bool_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class CollectionParams(betterproto.Message):
    vector_size: int = betterproto.uint64_field(1)
    distance: "Distance" = betterproto.enum_field(2)
    shard_number: int = betterproto.uint32_field(3)
    on_disk_payload: bool = betterproto.bool_field(4)


@dataclass(eq=False, repr=False)
class CollectionConfig(betterproto.Message):
    params: "CollectionParams" = betterproto.message_field(1)
    hnsw_config: "HnswConfigDiff" = betterproto.message_field(2)
    optimizer_config: "OptimizersConfigDiff" = betterproto.message_field(3)
    wal_config: "WalConfigDiff" = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class PayloadSchemaInfo(betterproto.Message):
    data_type: "PayloadSchemaType" = betterproto.enum_field(1)


@dataclass(eq=False, repr=False)
class CollectionInfo(betterproto.Message):
    status: "CollectionStatus" = betterproto.enum_field(1)
    optimizer_status: "OptimizerStatus" = betterproto.message_field(2)
    vectors_count: int = betterproto.uint64_field(3)
    segments_count: int = betterproto.uint64_field(4)
    disk_data_size: int = betterproto.uint64_field(5)
    ram_data_size: int = betterproto.uint64_field(6)
    config: "CollectionConfig" = betterproto.message_field(7)
    payload_schema: Dict[str, "PayloadSchemaInfo"] = betterproto.map_field(
        8, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    points_count: int = betterproto.uint64_field(9)
    indexed_vectors_count: Optional[int] = betterproto.uint64_field(
        10, optional=True, group="_indexed_vectors_count"
    )

    def __post_init__(self) -> None:
        super().__post_init__()
        if self.disk_data_size:
            warnings.warn(
                "CollectionInfo.disk_data_size is deprecated", DeprecationWarning
            )
        if self.ram_data_size:
            warnings.warn(
                "CollectionInfo.ram_data_size is deprecated", DeprecationWarning
            )


@dataclass(eq=False, repr=False)
class ChangeAliases(betterproto.Message):
    actions: List["AliasOperations"] = betterproto.message_field(1)
    timeout: Optional[int] = betterproto.uint64_field(
        2, optional=True, group="_timeout"
    )


@dataclass(eq=False, repr=False)
class AliasOperations(betterproto.Message):
    create_alias: "CreateAlias" = betterproto.message_field(1, group="action")
    rename_alias: "RenameAlias" = betterproto.message_field(2, group="action")
    delete_alias: "DeleteAlias" = betterproto.message_field(3, group="action")


@dataclass(eq=False, repr=False)
class CreateAlias(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    alias_name: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class RenameAlias(betterproto.Message):
    old_alias_name: str = betterproto.string_field(1)
    new_alias_name: str = betterproto.string_field(2)


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


@dataclass(eq=False, repr=False)
class Struct(betterproto.Message):
    """
    `Struct` represents a structured data value, consisting of fields which map
    to dynamically typed values. In some languages, `Struct` might be supported
    by a native representation. For example, in scripting languages like JS a
    struct is represented as an object. The details of that representation are
    described together with the proto support for the language. The JSON
    representation for `Struct` is JSON object.
    """

    # Unordered map of dynamically typed values.
    fields: Dict[str, "Value"] = betterproto.map_field(
        1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )


@dataclass(eq=False, repr=False)
class Value(betterproto.Message):
    """
    `Value` represents a dynamically typed value which can be either null, a
    number, a string, a boolean, a recursive struct value, or a list of values.
    A producer of value is expected to set one of that variants, absence of any
    variant indicates an error. The JSON representation for `Value` is JSON
    value.
    """

    # Represents a null value.
    null_value: "NullValue" = betterproto.enum_field(1, group="kind")
    # Represents a double value.
    double_value: float = betterproto.double_field(2, group="kind")
    # Represents an integer value
    integer_value: int = betterproto.int64_field(3, group="kind")
    # Represents a string value.
    string_value: str = betterproto.string_field(4, group="kind")
    # Represents a boolean value.
    bool_value: bool = betterproto.bool_field(5, group="kind")
    # Represents a structured value.
    struct_value: "Struct" = betterproto.message_field(6, group="kind")
    # Represents a repeated `Value`.
    list_value: "ListValue" = betterproto.message_field(7, group="kind")


@dataclass(eq=False, repr=False)
class ListValue(betterproto.Message):
    """
    `ListValue` is a wrapper around a repeated field of values. The JSON
    representation for `ListValue` is JSON array.
    """

    # Repeated field of dynamically typed values.
    values: List["Value"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class PointId(betterproto.Message):
    num: int = betterproto.uint64_field(1, group="point_id_options")
    uuid: str = betterproto.string_field(2, group="point_id_options")


@dataclass(eq=False, repr=False)
class UpsertPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    wait: Optional[bool] = betterproto.bool_field(2, optional=True, group="_wait")
    points: List["PointStruct"] = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class DeletePoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    wait: Optional[bool] = betterproto.bool_field(2, optional=True, group="_wait")
    points: "PointsSelector" = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class GetPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    ids: List["PointId"] = betterproto.message_field(2)
    with_vector: Optional[bool] = betterproto.bool_field(
        3, optional=True, group="_with_vector"
    )
    with_payload: "WithPayloadSelector" = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class SetPayloadPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    wait: Optional[bool] = betterproto.bool_field(2, optional=True, group="_wait")
    payload: Dict[str, "Value"] = betterproto.map_field(
        3, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    points: List["PointId"] = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class DeletePayloadPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    wait: Optional[bool] = betterproto.bool_field(2, optional=True, group="_wait")
    keys: List[str] = betterproto.string_field(3)
    points: List["PointId"] = betterproto.message_field(4)


@dataclass(eq=False, repr=False)
class ClearPayloadPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    wait: Optional[bool] = betterproto.bool_field(2, optional=True, group="_wait")
    points: "PointsSelector" = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class CreateFieldIndexCollection(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    wait: Optional[bool] = betterproto.bool_field(2, optional=True, group="_wait")
    field_name: str = betterproto.string_field(3)
    field_type: Optional["FieldType"] = betterproto.enum_field(
        4, optional=True, group="_field_type"
    )


@dataclass(eq=False, repr=False)
class DeleteFieldIndexCollection(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    wait: Optional[bool] = betterproto.bool_field(2, optional=True, group="_wait")
    field_name: str = betterproto.string_field(3)


@dataclass(eq=False, repr=False)
class PayloadIncludeSelector(betterproto.Message):
    fields: List[str] = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class PayloadExcludeSelector(betterproto.Message):
    fields: List[str] = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class WithPayloadSelector(betterproto.Message):
    enable: bool = betterproto.bool_field(1, group="selector_options")
    include: "PayloadIncludeSelector" = betterproto.message_field(
        2, group="selector_options"
    )
    exclude: "PayloadExcludeSelector" = betterproto.message_field(
        3, group="selector_options"
    )


@dataclass(eq=False, repr=False)
class SearchParams(betterproto.Message):
    # Params relevant to HNSW index. Size of the beam in a beam-search.Larger the
    # value - more accurate the result, more time required for search.
    hnsw_ef: Optional[int] = betterproto.uint64_field(
        1, optional=True, group="_hnsw_ef"
    )


@dataclass(eq=False, repr=False)
class SearchPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    vector: List[float] = betterproto.float_field(2)
    filter: "Filter" = betterproto.message_field(3)
    limit: int = betterproto.uint64_field(4)
    with_vector: Optional[bool] = betterproto.bool_field(
        5, optional=True, group="_with_vector"
    )
    with_payload: "WithPayloadSelector" = betterproto.message_field(6)
    params: "SearchParams" = betterproto.message_field(7)
    score_threshold: Optional[float] = betterproto.float_field(
        8, optional=True, group="_score_threshold"
    )
    offset: Optional[int] = betterproto.uint64_field(9, optional=True, group="_offset")


@dataclass(eq=False, repr=False)
class ScrollPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    filter: "Filter" = betterproto.message_field(2)
    offset: Optional["PointId"] = betterproto.message_field(
        3, optional=True, group="_offset"
    )
    limit: Optional[int] = betterproto.uint32_field(4, optional=True, group="_limit")
    with_vector: Optional[bool] = betterproto.bool_field(
        5, optional=True, group="_with_vector"
    )
    with_payload: "WithPayloadSelector" = betterproto.message_field(6)


@dataclass(eq=False, repr=False)
class RecommendPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    positive: List["PointId"] = betterproto.message_field(2)
    negative: List["PointId"] = betterproto.message_field(3)
    filter: "Filter" = betterproto.message_field(4)
    limit: int = betterproto.uint64_field(5)
    with_vector: Optional[bool] = betterproto.bool_field(
        6, optional=True, group="_with_vector"
    )
    with_payload: "WithPayloadSelector" = betterproto.message_field(7)
    params: "SearchParams" = betterproto.message_field(8)
    score_threshold: Optional[float] = betterproto.float_field(
        9, optional=True, group="_score_threshold"
    )
    offset: Optional[int] = betterproto.uint64_field(10, optional=True, group="_offset")


@dataclass(eq=False, repr=False)
class CountPoints(betterproto.Message):
    collection_name: str = betterproto.string_field(1)
    filter: "Filter" = betterproto.message_field(2)
    exact: Optional[bool] = betterproto.bool_field(3, optional=True, group="_exact")


@dataclass(eq=False, repr=False)
class PointsOperationResponse(betterproto.Message):
    result: "UpdateResult" = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class UpdateResult(betterproto.Message):
    operation_id: int = betterproto.uint64_field(1)
    status: "UpdateStatus" = betterproto.enum_field(2)


@dataclass(eq=False, repr=False)
class ScoredPoint(betterproto.Message):
    id: "PointId" = betterproto.message_field(1)
    payload: Dict[str, "Value"] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    score: float = betterproto.float_field(3)
    vector: List[float] = betterproto.float_field(4)
    version: int = betterproto.uint64_field(5)


@dataclass(eq=False, repr=False)
class SearchResponse(betterproto.Message):
    result: List["ScoredPoint"] = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class CountResponse(betterproto.Message):
    result: "CountResult" = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class ScrollResponse(betterproto.Message):
    next_page_offset: Optional["PointId"] = betterproto.message_field(
        1, optional=True, group="_next_page_offset"
    )
    result: List["RetrievedPoint"] = betterproto.message_field(2)
    time: float = betterproto.double_field(3)


@dataclass(eq=False, repr=False)
class CountResult(betterproto.Message):
    count: int = betterproto.uint64_field(1)


@dataclass(eq=False, repr=False)
class RetrievedPoint(betterproto.Message):
    id: "PointId" = betterproto.message_field(1)
    payload: Dict[str, "Value"] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    vector: List[float] = betterproto.float_field(3)


@dataclass(eq=False, repr=False)
class GetResponse(betterproto.Message):
    result: List["RetrievedPoint"] = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class RecommendResponse(betterproto.Message):
    result: List["ScoredPoint"] = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class Filter(betterproto.Message):
    should: List["Condition"] = betterproto.message_field(1)
    must: List["Condition"] = betterproto.message_field(2)
    must_not: List["Condition"] = betterproto.message_field(3)


@dataclass(eq=False, repr=False)
class Condition(betterproto.Message):
    field: "FieldCondition" = betterproto.message_field(1, group="condition_one_of")
    is_empty: "IsEmptyCondition" = betterproto.message_field(
        2, group="condition_one_of"
    )
    has_id: "HasIdCondition" = betterproto.message_field(3, group="condition_one_of")
    filter: "Filter" = betterproto.message_field(4, group="condition_one_of")


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


@dataclass(eq=False, repr=False)
class HasIdCondition(betterproto.Message):
    has_id: List["PointId"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class FieldCondition(betterproto.Message):
    key: str = betterproto.string_field(1)
    match: "Match" = betterproto.message_field(2)
    range: "Range" = betterproto.message_field(3)
    geo_bounding_box: "GeoBoundingBox" = betterproto.message_field(4)
    geo_radius: "GeoRadius" = betterproto.message_field(5)
    values_count: "ValuesCount" = betterproto.message_field(6)


@dataclass(eq=False, repr=False)
class Match(betterproto.Message):
    keyword: str = betterproto.string_field(1, group="match_value")
    integer: int = betterproto.int64_field(2, group="match_value")
    boolean: bool = betterproto.bool_field(3, group="match_value")


@dataclass(eq=False, repr=False)
class Range(betterproto.Message):
    lt: Optional[float] = betterproto.double_field(1, optional=True, group="_lt")
    gt: Optional[float] = betterproto.double_field(2, optional=True, group="_gt")
    gte: Optional[float] = betterproto.double_field(3, optional=True, group="_gte")
    lte: Optional[float] = betterproto.double_field(4, optional=True, group="_lte")


@dataclass(eq=False, repr=False)
class GeoBoundingBox(betterproto.Message):
    top_left: "GeoPoint" = betterproto.message_field(1)
    bottom_right: "GeoPoint" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class GeoRadius(betterproto.Message):
    center: "GeoPoint" = betterproto.message_field(1)
    radius: float = betterproto.float_field(2)


@dataclass(eq=False, repr=False)
class ValuesCount(betterproto.Message):
    lt: Optional[int] = betterproto.uint64_field(1, optional=True, group="_lt")
    gt: Optional[int] = betterproto.uint64_field(2, optional=True, group="_gt")
    gte: Optional[int] = betterproto.uint64_field(3, optional=True, group="_gte")
    lte: Optional[int] = betterproto.uint64_field(4, optional=True, group="_lte")


@dataclass(eq=False, repr=False)
class PointsSelector(betterproto.Message):
    points: "PointsIdsList" = betterproto.message_field(
        1, group="points_selector_one_of"
    )
    filter: "Filter" = betterproto.message_field(2, group="points_selector_one_of")


@dataclass(eq=False, repr=False)
class PointsIdsList(betterproto.Message):
    ids: List["PointId"] = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class PointStruct(betterproto.Message):
    id: "PointId" = betterproto.message_field(1)
    vector: List[float] = betterproto.float_field(2)
    payload: Dict[str, "Value"] = betterproto.map_field(
        3, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )


@dataclass(eq=False, repr=False)
class GeoPoint(betterproto.Message):
    lon: float = betterproto.double_field(1)
    lat: float = betterproto.double_field(2)


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


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


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


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


@dataclass(eq=False, repr=False)
class SnapshotDescription(betterproto.Message):
    name: str = betterproto.string_field(1)
    creation_time: datetime = betterproto.message_field(2)
    size: int = betterproto.int64_field(3)


@dataclass(eq=False, repr=False)
class CreateSnapshotResponse(betterproto.Message):
    snapshot_description: "SnapshotDescription" = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


@dataclass(eq=False, repr=False)
class ListSnapshotsResponse(betterproto.Message):
    snapshot_descriptions: List["SnapshotDescription"] = betterproto.message_field(1)
    time: float = betterproto.double_field(2)


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


@dataclass(eq=False, repr=False)
class HealthCheckReply(betterproto.Message):
    title: str = betterproto.string_field(1)
    version: str = betterproto.string_field(2)


class CollectionsStub(betterproto.ServiceStub):
    async def get(self, *, collection_name: str = "") -> "GetCollectionInfoResponse":

        request = GetCollectionInfoRequest()
        request.collection_name = collection_name

        return await self._unary_unary(
            "/nnext.Collections/Get", request, GetCollectionInfoResponse
        )

    async def list(self) -> "ListCollectionsResponse":

        request = ListCollectionsRequest()

        return await self._unary_unary(
            "/nnext.Collections/List", request, ListCollectionsResponse
        )

    async def create(
        self,
        *,
        collection_name: str = "",
        vector_size: int = 0,
        distance: "Distance" = 0,
        hnsw_config: Optional["HnswConfigDiff"] = None,
        wal_config: Optional["WalConfigDiff"] = None,
        optimizers_config: Optional["OptimizersConfigDiff"] = None,
        shard_number: Optional[int] = None,
        on_disk_payload: Optional[bool] = None,
        timeout: Optional[int] = None
    ) -> "CollectionOperationResponse":

        request = CreateCollection()
        request.collection_name = collection_name
        request.vector_size = vector_size
        request.distance = distance
        if hnsw_config is not None:
            request.hnsw_config = hnsw_config
        if wal_config is not None:
            request.wal_config = wal_config
        if optimizers_config is not None:
            request.optimizers_config = optimizers_config
        request.shard_number = shard_number
        request.on_disk_payload = on_disk_payload
        request.timeout = timeout

        return await self._unary_unary(
            "/nnext.Collections/Create", request, CollectionOperationResponse
        )

    async def update(
        self,
        *,
        collection_name: str = "",
        optimizers_config: Optional["OptimizersConfigDiff"] = None,
        timeout: Optional[int] = None
    ) -> "CollectionOperationResponse":

        request = UpdateCollection()
        request.collection_name = collection_name
        if optimizers_config is not None:
            request.optimizers_config = optimizers_config
        request.timeout = timeout

        return await self._unary_unary(
            "/nnext.Collections/Update", request, CollectionOperationResponse
        )

    async def delete(
        self, *, collection_name: str = "", timeout: Optional[int] = None
    ) -> "CollectionOperationResponse":

        request = DeleteCollection()
        request.collection_name = collection_name
        request.timeout = timeout

        return await self._unary_unary(
            "/nnext.Collections/Delete", request, CollectionOperationResponse
        )

    async def update_aliases(
        self,
        *,
        actions: Optional[List["AliasOperations"]] = None,
        timeout: Optional[int] = None
    ) -> "CollectionOperationResponse":
        actions = actions or []

        request = ChangeAliases()
        if actions is not None:
            request.actions = actions
        request.timeout = timeout

        return await self._unary_unary(
            "/nnext.Collections/UpdateAliases", request, CollectionOperationResponse
        )


class PointsStub(betterproto.ServiceStub):
    async def upsert(
        self,
        *,
        collection_name: str = "",
        wait: Optional[bool] = None,
        points: Optional[List["PointStruct"]] = None
    ) -> "PointsOperationResponse":
        points = points or []

        request = UpsertPoints()
        request.collection_name = collection_name
        request.wait = wait
        if points is not None:
            request.points = points

        return await self._unary_unary(
            "/nnext.Points/Upsert", request, PointsOperationResponse
        )

    async def delete(
        self,
        *,
        collection_name: str = "",
        wait: Optional[bool] = None,
        points: "PointsSelector" = None
    ) -> "PointsOperationResponse":

        request = DeletePoints()
        request.collection_name = collection_name
        request.wait = wait
        if points is not None:
            request.points = points

        return await self._unary_unary(
            "/nnext.Points/Delete", request, PointsOperationResponse
        )

    async def get(
        self,
        *,
        collection_name: str = "",
        ids: Optional[List["PointId"]] = None,
        with_vector: Optional[bool] = None,
        with_payload: "WithPayloadSelector" = None
    ) -> "GetResponse":
        ids = ids or []

        request = GetPoints()
        request.collection_name = collection_name
        if ids is not None:
            request.ids = ids
        request.with_vector = with_vector
        if with_payload is not None:
            request.with_payload = with_payload

        return await self._unary_unary("/nnext.Points/Get", request, GetResponse)

    async def set_payload(
        self,
        *,
        collection_name: str = "",
        wait: Optional[bool] = None,
        payload: Dict[str, "Value"] = None,
        points: Optional[List["PointId"]] = None
    ) -> "PointsOperationResponse":
        points = points or []

        request = SetPayloadPoints()
        request.collection_name = collection_name
        request.wait = wait
        request.payload = payload
        if points is not None:
            request.points = points

        return await self._unary_unary(
            "/nnext.Points/SetPayload", request, PointsOperationResponse
        )

    async def delete_payload(
        self,
        *,
        collection_name: str = "",
        wait: Optional[bool] = None,
        keys: Optional[List[str]] = None,
        points: Optional[List["PointId"]] = None
    ) -> "PointsOperationResponse":
        keys = keys or []
        points = points or []

        request = DeletePayloadPoints()
        request.collection_name = collection_name
        request.wait = wait
        request.keys = keys
        if points is not None:
            request.points = points

        return await self._unary_unary(
            "/nnext.Points/DeletePayload", request, PointsOperationResponse
        )

    async def clear_payload(
        self,
        *,
        collection_name: str = "",
        wait: Optional[bool] = None,
        points: "PointsSelector" = None
    ) -> "PointsOperationResponse":

        request = ClearPayloadPoints()
        request.collection_name = collection_name
        request.wait = wait
        if points is not None:
            request.points = points

        return await self._unary_unary(
            "/nnext.Points/ClearPayload", request, PointsOperationResponse
        )

    async def create_field_index(
        self,
        *,
        collection_name: str = "",
        wait: Optional[bool] = None,
        field_name: str = "",
        field_type: Optional["FieldType"] = None
    ) -> "PointsOperationResponse":

        request = CreateFieldIndexCollection()
        request.collection_name = collection_name
        request.wait = wait
        request.field_name = field_name
        request.field_type = field_type

        return await self._unary_unary(
            "/nnext.Points/CreateFieldIndex", request, PointsOperationResponse
        )

    async def delete_field_index(
        self,
        *,
        collection_name: str = "",
        wait: Optional[bool] = None,
        field_name: str = ""
    ) -> "PointsOperationResponse":

        request = DeleteFieldIndexCollection()
        request.collection_name = collection_name
        request.wait = wait
        request.field_name = field_name

        return await self._unary_unary(
            "/nnext.Points/DeleteFieldIndex", request, PointsOperationResponse
        )

    async def search(
        self,
        *,
        collection_name: str = "",
        vector: Optional[List[float]] = None,
        filter: "Filter" = None,
        limit: int = 0,
        with_vector: Optional[bool] = None,
        with_payload: "WithPayloadSelector" = None,
        params: "SearchParams" = None,
        score_threshold: Optional[float] = None,
        offset: Optional[int] = None
    ) -> "SearchResponse":
        vector = vector or []

        request = SearchPoints()
        request.collection_name = collection_name
        request.vector = vector
        if filter is not None:
            request.filter = filter
        request.limit = limit
        request.with_vector = with_vector
        if with_payload is not None:
            request.with_payload = with_payload
        if params is not None:
            request.params = params
        request.score_threshold = score_threshold
        request.offset = offset

        return await self._unary_unary("/nnext.Points/Search", request, SearchResponse)

    async def scroll(
        self,
        *,
        collection_name: str = "",
        filter: "Filter" = None,
        offset: Optional["PointId"] = None,
        limit: Optional[int] = None,
        with_vector: Optional[bool] = None,
        with_payload: "WithPayloadSelector" = None
    ) -> "ScrollResponse":

        request = ScrollPoints()
        request.collection_name = collection_name
        if filter is not None:
            request.filter = filter
        if offset is not None:
            request.offset = offset
        request.limit = limit
        request.with_vector = with_vector
        if with_payload is not None:
            request.with_payload = with_payload

        return await self._unary_unary("/nnext.Points/Scroll", request, ScrollResponse)

    async def recommend(
        self,
        *,
        collection_name: str = "",
        positive: Optional[List["PointId"]] = None,
        negative: Optional[List["PointId"]] = None,
        filter: "Filter" = None,
        limit: int = 0,
        with_vector: Optional[bool] = None,
        with_payload: "WithPayloadSelector" = None,
        params: "SearchParams" = None,
        score_threshold: Optional[float] = None,
        offset: Optional[int] = None
    ) -> "RecommendResponse":
        positive = positive or []
        negative = negative or []

        request = RecommendPoints()
        request.collection_name = collection_name
        if positive is not None:
            request.positive = positive
        if negative is not None:
            request.negative = negative
        if filter is not None:
            request.filter = filter
        request.limit = limit
        request.with_vector = with_vector
        if with_payload is not None:
            request.with_payload = with_payload
        if params is not None:
            request.params = params
        request.score_threshold = score_threshold
        request.offset = offset

        return await self._unary_unary(
            "/nnext.Points/Recommend", request, RecommendResponse
        )

    async def count(
        self,
        *,
        collection_name: str = "",
        filter: "Filter" = None,
        exact: Optional[bool] = None
    ) -> "CountResponse":

        request = CountPoints()
        request.collection_name = collection_name
        if filter is not None:
            request.filter = filter
        request.exact = exact

        return await self._unary_unary("/nnext.Points/Count", request, CountResponse)


class SnapshotsStub(betterproto.ServiceStub):
    async def create(self, *, collection_name: str = "") -> "CreateSnapshotResponse":

        request = CreateSnapshotRequest()
        request.collection_name = collection_name

        return await self._unary_unary(
            "/nnext.Snapshots/Create", request, CreateSnapshotResponse
        )

    async def list(self, *, collection_name: str = "") -> "ListSnapshotsResponse":

        request = ListSnapshotsRequest()
        request.collection_name = collection_name

        return await self._unary_unary(
            "/nnext.Snapshots/List", request, ListSnapshotsResponse
        )

    async def create_full(self) -> "CreateSnapshotResponse":

        request = CreateFullSnapshotRequest()

        return await self._unary_unary(
            "/nnext.Snapshots/CreateFull", request, CreateSnapshotResponse
        )

    async def list_full(self) -> "ListSnapshotsResponse":

        request = ListFullSnapshotsRequest()

        return await self._unary_unary(
            "/nnext.Snapshots/ListFull", request, ListSnapshotsResponse
        )


class NNextStub(betterproto.ServiceStub):
    async def health_check(self) -> "HealthCheckReply":

        request = HealthCheckRequest()

        return await self._unary_unary(
            "/nnext.NNext/HealthCheck", request, HealthCheckReply
        )


class CollectionsBase(ServiceBase):
    async def get(self, collection_name: str) -> "GetCollectionInfoResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def list(self) -> "ListCollectionsResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def create(
        self,
        collection_name: str,
        vector_size: int,
        distance: "Distance",
        hnsw_config: Optional["HnswConfigDiff"],
        wal_config: Optional["WalConfigDiff"],
        optimizers_config: Optional["OptimizersConfigDiff"],
        shard_number: Optional[int],
        on_disk_payload: Optional[bool],
        timeout: Optional[int],
    ) -> "CollectionOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def update(
        self,
        collection_name: str,
        optimizers_config: Optional["OptimizersConfigDiff"],
        timeout: Optional[int],
    ) -> "CollectionOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete(
        self, collection_name: str, timeout: Optional[int]
    ) -> "CollectionOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def update_aliases(
        self, actions: Optional[List["AliasOperations"]], timeout: Optional[int]
    ) -> "CollectionOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
        }

        response = await self.get(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_list(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.list(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_create(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "vector_size": request.vector_size,
            "distance": request.distance,
            "hnsw_config": request.hnsw_config,
            "wal_config": request.wal_config,
            "optimizers_config": request.optimizers_config,
            "shard_number": request.shard_number,
            "on_disk_payload": request.on_disk_payload,
            "timeout": request.timeout,
        }

        response = await self.create(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_update(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "optimizers_config": request.optimizers_config,
            "timeout": request.timeout,
        }

        response = await self.update(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_delete(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "timeout": request.timeout,
        }

        response = await self.delete(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_update_aliases(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "actions": request.actions,
            "timeout": request.timeout,
        }

        response = await self.update_aliases(**request_kwargs)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/nnext.Collections/Get": grpclib.const.Handler(
                self.__rpc_get,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetCollectionInfoRequest,
                GetCollectionInfoResponse,
            ),
            "/nnext.Collections/List": grpclib.const.Handler(
                self.__rpc_list,
                grpclib.const.Cardinality.UNARY_UNARY,
                ListCollectionsRequest,
                ListCollectionsResponse,
            ),
            "/nnext.Collections/Create": grpclib.const.Handler(
                self.__rpc_create,
                grpclib.const.Cardinality.UNARY_UNARY,
                CreateCollection,
                CollectionOperationResponse,
            ),
            "/nnext.Collections/Update": grpclib.const.Handler(
                self.__rpc_update,
                grpclib.const.Cardinality.UNARY_UNARY,
                UpdateCollection,
                CollectionOperationResponse,
            ),
            "/nnext.Collections/Delete": grpclib.const.Handler(
                self.__rpc_delete,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteCollection,
                CollectionOperationResponse,
            ),
            "/nnext.Collections/UpdateAliases": grpclib.const.Handler(
                self.__rpc_update_aliases,
                grpclib.const.Cardinality.UNARY_UNARY,
                ChangeAliases,
                CollectionOperationResponse,
            ),
        }


class PointsBase(ServiceBase):
    async def upsert(
        self,
        collection_name: str,
        wait: Optional[bool],
        points: Optional[List["PointStruct"]],
    ) -> "PointsOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete(
        self, collection_name: str, wait: Optional[bool], points: "PointsSelector"
    ) -> "PointsOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def get(
        self,
        collection_name: str,
        ids: Optional[List["PointId"]],
        with_vector: Optional[bool],
        with_payload: "WithPayloadSelector",
    ) -> "GetResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def set_payload(
        self,
        collection_name: str,
        wait: Optional[bool],
        payload: Dict[str, "Value"],
        points: Optional[List["PointId"]],
    ) -> "PointsOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_payload(
        self,
        collection_name: str,
        wait: Optional[bool],
        keys: Optional[List[str]],
        points: Optional[List["PointId"]],
    ) -> "PointsOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def clear_payload(
        self, collection_name: str, wait: Optional[bool], points: "PointsSelector"
    ) -> "PointsOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def create_field_index(
        self,
        collection_name: str,
        wait: Optional[bool],
        field_name: str,
        field_type: Optional["FieldType"],
    ) -> "PointsOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_field_index(
        self, collection_name: str, wait: Optional[bool], field_name: str
    ) -> "PointsOperationResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def search(
        self,
        collection_name: str,
        vector: Optional[List[float]],
        filter: "Filter",
        limit: int,
        with_vector: Optional[bool],
        with_payload: "WithPayloadSelector",
        params: "SearchParams",
        score_threshold: Optional[float],
        offset: Optional[int],
    ) -> "SearchResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def scroll(
        self,
        collection_name: str,
        filter: "Filter",
        offset: Optional["PointId"],
        limit: Optional[int],
        with_vector: Optional[bool],
        with_payload: "WithPayloadSelector",
    ) -> "ScrollResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def recommend(
        self,
        collection_name: str,
        positive: Optional[List["PointId"]],
        negative: Optional[List["PointId"]],
        filter: "Filter",
        limit: int,
        with_vector: Optional[bool],
        with_payload: "WithPayloadSelector",
        params: "SearchParams",
        score_threshold: Optional[float],
        offset: Optional[int],
    ) -> "RecommendResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def count(
        self, collection_name: str, filter: "Filter", exact: Optional[bool]
    ) -> "CountResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_upsert(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "wait": request.wait,
            "points": request.points,
        }

        response = await self.upsert(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_delete(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "wait": request.wait,
            "points": request.points,
        }

        response = await self.delete(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_get(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "ids": request.ids,
            "with_vector": request.with_vector,
            "with_payload": request.with_payload,
        }

        response = await self.get(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_set_payload(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "wait": request.wait,
            "payload": request.payload,
            "points": request.points,
        }

        response = await self.set_payload(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_delete_payload(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "wait": request.wait,
            "keys": request.keys,
            "points": request.points,
        }

        response = await self.delete_payload(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_clear_payload(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "wait": request.wait,
            "points": request.points,
        }

        response = await self.clear_payload(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_create_field_index(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "wait": request.wait,
            "field_name": request.field_name,
            "field_type": request.field_type,
        }

        response = await self.create_field_index(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_delete_field_index(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "wait": request.wait,
            "field_name": request.field_name,
        }

        response = await self.delete_field_index(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_search(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "vector": request.vector,
            "filter": request.filter,
            "limit": request.limit,
            "with_vector": request.with_vector,
            "with_payload": request.with_payload,
            "params": request.params,
            "score_threshold": request.score_threshold,
            "offset": request.offset,
        }

        response = await self.search(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_scroll(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "filter": request.filter,
            "offset": request.offset,
            "limit": request.limit,
            "with_vector": request.with_vector,
            "with_payload": request.with_payload,
        }

        response = await self.scroll(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_recommend(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "positive": request.positive,
            "negative": request.negative,
            "filter": request.filter,
            "limit": request.limit,
            "with_vector": request.with_vector,
            "with_payload": request.with_payload,
            "params": request.params,
            "score_threshold": request.score_threshold,
            "offset": request.offset,
        }

        response = await self.recommend(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_count(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
            "filter": request.filter,
            "exact": request.exact,
        }

        response = await self.count(**request_kwargs)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/nnext.Points/Upsert": grpclib.const.Handler(
                self.__rpc_upsert,
                grpclib.const.Cardinality.UNARY_UNARY,
                UpsertPoints,
                PointsOperationResponse,
            ),
            "/nnext.Points/Delete": grpclib.const.Handler(
                self.__rpc_delete,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeletePoints,
                PointsOperationResponse,
            ),
            "/nnext.Points/Get": grpclib.const.Handler(
                self.__rpc_get,
                grpclib.const.Cardinality.UNARY_UNARY,
                GetPoints,
                GetResponse,
            ),
            "/nnext.Points/SetPayload": grpclib.const.Handler(
                self.__rpc_set_payload,
                grpclib.const.Cardinality.UNARY_UNARY,
                SetPayloadPoints,
                PointsOperationResponse,
            ),
            "/nnext.Points/DeletePayload": grpclib.const.Handler(
                self.__rpc_delete_payload,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeletePayloadPoints,
                PointsOperationResponse,
            ),
            "/nnext.Points/ClearPayload": grpclib.const.Handler(
                self.__rpc_clear_payload,
                grpclib.const.Cardinality.UNARY_UNARY,
                ClearPayloadPoints,
                PointsOperationResponse,
            ),
            "/nnext.Points/CreateFieldIndex": grpclib.const.Handler(
                self.__rpc_create_field_index,
                grpclib.const.Cardinality.UNARY_UNARY,
                CreateFieldIndexCollection,
                PointsOperationResponse,
            ),
            "/nnext.Points/DeleteFieldIndex": grpclib.const.Handler(
                self.__rpc_delete_field_index,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteFieldIndexCollection,
                PointsOperationResponse,
            ),
            "/nnext.Points/Search": grpclib.const.Handler(
                self.__rpc_search,
                grpclib.const.Cardinality.UNARY_UNARY,
                SearchPoints,
                SearchResponse,
            ),
            "/nnext.Points/Scroll": grpclib.const.Handler(
                self.__rpc_scroll,
                grpclib.const.Cardinality.UNARY_UNARY,
                ScrollPoints,
                ScrollResponse,
            ),
            "/nnext.Points/Recommend": grpclib.const.Handler(
                self.__rpc_recommend,
                grpclib.const.Cardinality.UNARY_UNARY,
                RecommendPoints,
                RecommendResponse,
            ),
            "/nnext.Points/Count": grpclib.const.Handler(
                self.__rpc_count,
                grpclib.const.Cardinality.UNARY_UNARY,
                CountPoints,
                CountResponse,
            ),
        }


class SnapshotsBase(ServiceBase):
    async def create(self, collection_name: str) -> "CreateSnapshotResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def list(self, collection_name: str) -> "ListSnapshotsResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def create_full(self) -> "CreateSnapshotResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def list_full(self) -> "ListSnapshotsResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_create(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
        }

        response = await self.create(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_list(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection_name": request.collection_name,
        }

        response = await self.list(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_create_full(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.create_full(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_list_full(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.list_full(**request_kwargs)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/nnext.Snapshots/Create": grpclib.const.Handler(
                self.__rpc_create,
                grpclib.const.Cardinality.UNARY_UNARY,
                CreateSnapshotRequest,
                CreateSnapshotResponse,
            ),
            "/nnext.Snapshots/List": grpclib.const.Handler(
                self.__rpc_list,
                grpclib.const.Cardinality.UNARY_UNARY,
                ListSnapshotsRequest,
                ListSnapshotsResponse,
            ),
            "/nnext.Snapshots/CreateFull": grpclib.const.Handler(
                self.__rpc_create_full,
                grpclib.const.Cardinality.UNARY_UNARY,
                CreateFullSnapshotRequest,
                CreateSnapshotResponse,
            ),
            "/nnext.Snapshots/ListFull": grpclib.const.Handler(
                self.__rpc_list_full,
                grpclib.const.Cardinality.UNARY_UNARY,
                ListFullSnapshotsRequest,
                ListSnapshotsResponse,
            ),
        }


class NNextBase(ServiceBase):
    async def health_check(self) -> "HealthCheckReply":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_health_check(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {}

        response = await self.health_check(**request_kwargs)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/nnext.NNext/HealthCheck": grpclib.const.Handler(
                self.__rpc_health_check,
                grpclib.const.Cardinality.UNARY_UNARY,
                HealthCheckRequest,
                HealthCheckReply,
            ),
        }
