Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions pymilvus/client/grpc_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from .prepare import Prepare
from .search_reasult import SearchResult
from .types import (
AnalyzeResult,
BulkInsertState,
CompactionPlans,
CompactionState,
Expand Down Expand Up @@ -2243,3 +2244,24 @@ def remove_privileges_from_group(
)
resp = self._stub.OperatePrivilegeGroup(req, wait_for_ready=True, timeout=timeout)
check_status(resp)

@retry_on_rpc_failure()
def run_analyzer(
self,
texts: Union[str, List[str]],
analyzer_params: Union[str, Dict],
with_hash: bool = False,
with_detail: bool = False,
timeout: Optional[float] = None,
**kwargs,
):
check_pass_param(timeout=timeout)
req = Prepare.run_analyzer(
texts, analyzer_params, with_hash=with_hash, with_detail=with_detail
)
resp = self._stub.RunAnalyzer(req, timeout=timeout)
check_status(resp.status)

if isinstance(texts, str):
return AnalyzeResult(resp.results[0], with_hash, with_detail)
return [AnalyzeResult(result, with_hash, with_detail) for result in resp.results]
21 changes: 21 additions & 0 deletions pymilvus/client/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -1724,3 +1724,24 @@ def operate_privilege_group_req(
privileges=[milvus_types.PrivilegeEntity(name=p) for p in privileges],
type=operate_privilege_group_type,
)

@classmethod
def run_analyzer(
cls,
texts: Union[str, List[str]],
analyzer_params: Union[str, Dict],
with_hash: bool = False,
with_detail: bool = False,
):
req = milvus_types.RunAnalyzerRequest(with_hash=with_hash, with_detail=with_detail)
if isinstance(texts, str):
req.placeholder.append(texts.encode("utf-8"))
else:
req.placeholder.extend([text.encode("utf-8") for text in texts])

if isinstance(analyzer_params, dict):
req.analyzer_params = ujson.dumps(analyzer_params)
else:
req.analyzer_params = analyzer_params

return req
61 changes: 61 additions & 0 deletions pymilvus/client/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -1081,3 +1081,64 @@ def to_dict(self) -> Dict[str, Any]:
result = {"name": self.name}
result.update(self.properties)
return result


class AnalyzeToken:
def __init__(
self, token: milvus_types.AnalyzerToken, with_hash: bool = False, with_detail: bool = False
):
self.dict = {"token": token.token}
if with_detail:
self.dict["start_offset"] = token.start_offset
self.dict["end_offset"] = token.end_offset
self.dict["position"] = token.position
self.dict["position_length"] = token.position_length
if with_hash:
self.dict["hash"] = token.hash

@property
def token(self):
return self.dict["token"]

@property
def start_offset(self):
return self.dict["start_offset"]

@property
def end_offset(self):
return self.dict["end_offset"]

@property
def position(self):
return self.dict["position"]

@property
def position_length(self):
return self.dict["position_length"]

@property
def hash(self):
return self.dict["hash"]

def __getitem__(self, key: str):
return self.dict[key]

def __str__(self):
return str(self.dict)

__repr__ = __str__


class AnalyzeResult:
def __init__(
self, info: milvus_types.AnalyzerResult, with_hash: bool = False, with_detail: bool = False
) -> None:
if not with_detail and not with_hash:
self.tokens = [token.token for token in info.tokens]
else:
self.tokens = [AnalyzeToken(token, with_hash, with_detail) for token in info.tokens]

def __str__(self) -> str:
return str(self.tokens)

__repr__ = __str__
42 changes: 25 additions & 17 deletions pymilvus/grpc_gen/milvus_pb2.py

Large diffs are not rendered by default.

44 changes: 44 additions & 0 deletions pymilvus/grpc_gen/milvus_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2219,3 +2219,47 @@ class ListImportsAuthPlaceholder(_message.Message):
db_name: str
collection_name: str
def __init__(self, db_name: _Optional[str] = ..., collection_name: _Optional[str] = ...) -> None: ...

class RunAnalyzerRequest(_message.Message):
__slots__ = ("base", "analyzer_params", "placeholder", "with_detail", "with_hash")
BASE_FIELD_NUMBER: _ClassVar[int]
ANALYZER_PARAMS_FIELD_NUMBER: _ClassVar[int]
PLACEHOLDER_FIELD_NUMBER: _ClassVar[int]
WITH_DETAIL_FIELD_NUMBER: _ClassVar[int]
WITH_HASH_FIELD_NUMBER: _ClassVar[int]
base: _common_pb2.MsgBase
analyzer_params: str
placeholder: _containers.RepeatedScalarFieldContainer[bytes]
with_detail: bool
with_hash: bool
def __init__(self, base: _Optional[_Union[_common_pb2.MsgBase, _Mapping]] = ..., analyzer_params: _Optional[str] = ..., placeholder: _Optional[_Iterable[bytes]] = ..., with_detail: bool = ..., with_hash: bool = ...) -> None: ...

class AnalyzerToken(_message.Message):
__slots__ = ("token", "start_offset", "end_offset", "position", "position_length", "hash")
TOKEN_FIELD_NUMBER: _ClassVar[int]
START_OFFSET_FIELD_NUMBER: _ClassVar[int]
END_OFFSET_FIELD_NUMBER: _ClassVar[int]
POSITION_FIELD_NUMBER: _ClassVar[int]
POSITION_LENGTH_FIELD_NUMBER: _ClassVar[int]
HASH_FIELD_NUMBER: _ClassVar[int]
token: str
start_offset: int
end_offset: int
position: int
position_length: int
hash: int
def __init__(self, token: _Optional[str] = ..., start_offset: _Optional[int] = ..., end_offset: _Optional[int] = ..., position: _Optional[int] = ..., position_length: _Optional[int] = ..., hash: _Optional[int] = ...) -> None: ...

class AnalyzerResult(_message.Message):
__slots__ = ("tokens",)
TOKENS_FIELD_NUMBER: _ClassVar[int]
tokens: _containers.RepeatedCompositeFieldContainer[AnalyzerToken]
def __init__(self, tokens: _Optional[_Iterable[_Union[AnalyzerToken, _Mapping]]] = ...) -> None: ...

class RunAnalyzerResponse(_message.Message):
__slots__ = ("status", "results")
STATUS_FIELD_NUMBER: _ClassVar[int]
RESULTS_FIELD_NUMBER: _ClassVar[int]
status: _common_pb2.Status
results: _containers.RepeatedCompositeFieldContainer[AnalyzerResult]
def __init__(self, status: _Optional[_Union[_common_pb2.Status, _Mapping]] = ..., results: _Optional[_Iterable[_Union[AnalyzerResult, _Mapping]]] = ...) -> None: ...
33 changes: 33 additions & 0 deletions pymilvus/grpc_gen/milvus_pb2_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,11 @@ def __init__(self, channel):
request_serializer=milvus__pb2.OperatePrivilegeGroupRequest.SerializeToString,
response_deserializer=common__pb2.Status.FromString,
)
self.RunAnalyzer = channel.unary_unary(
'/milvus.proto.milvus.MilvusService/RunAnalyzer',
request_serializer=milvus__pb2.RunAnalyzerRequest.SerializeToString,
response_deserializer=milvus__pb2.RunAnalyzerResponse.FromString,
)


class MilvusServiceServicer(object):
Expand Down Expand Up @@ -1062,6 +1067,12 @@ def OperatePrivilegeGroup(self, request, context):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')

def RunAnalyzer(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')


def add_MilvusServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
Expand Down Expand Up @@ -1535,6 +1546,11 @@ def add_MilvusServiceServicer_to_server(servicer, server):
request_deserializer=milvus__pb2.OperatePrivilegeGroupRequest.FromString,
response_serializer=common__pb2.Status.SerializeToString,
),
'RunAnalyzer': grpc.unary_unary_rpc_method_handler(
servicer.RunAnalyzer,
request_deserializer=milvus__pb2.RunAnalyzerRequest.FromString,
response_serializer=milvus__pb2.RunAnalyzerResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'milvus.proto.milvus.MilvusService', rpc_method_handlers)
Expand Down Expand Up @@ -3143,6 +3159,23 @@ def OperatePrivilegeGroup(request,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)

@staticmethod
def RunAnalyzer(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/milvus.proto.milvus.MilvusService/RunAnalyzer',
milvus__pb2.RunAnalyzerRequest.SerializeToString,
milvus__pb2.RunAnalyzerResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)


class ProxyServiceStub(object):
"""Missing associated documentation comment in .proto file."""
Expand Down
23 changes: 23 additions & 0 deletions pymilvus/milvus_client/milvus_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1716,3 +1716,26 @@ def describe_replica(
"""
conn = self._get_connection()
return conn.describe_replica(collection_name, timeout=timeout, **kwargs)

def run_analyzer(
self,
texts: Union[str, List[str]],
analyzer_params: Union[str, Dict, None] = None,
with_hash: bool = False,
with_detail: bool = False,
timeout: Optional[float] = None,
):
"""Run analyzer. Return result tokens of analysis.
Args:
text(``str``,``List[str]``): The input text (string or string list).
analyzer_params(``str``,``Dict``,``None``): The parameters of analyzer.
timeout(``float``, optional): The timeout value in seconds. Defaults to None.
Returns:
(``List[str]``,``List[List[str]]``): The result tokens of analysis.
"""
if analyzer_params is None:
analyzer_params = {}

return self._get_connection().run_analyzer(
texts, analyzer_params, with_hash=with_hash, with_detail=with_detail, timeout=timeout
)