Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Refactored the way of warnings #864

Merged
merged 16 commits into from
Jan 6, 2025
Merged
1 change: 1 addition & 0 deletions qdrant_client/async_qdrant_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,7 @@ async def upsert(
message="\n Usage of `grpc.PointStruct` is deprecated. Please use `models.PointStruct` instead.\n ",
category=DeprecationWarning,
idx="grpc-input",
stacklevel=4,
)
requires_inference = self._inference_inspector.inspect(points)
if requires_inference and (not self.cloud_inference):
Expand Down
10 changes: 5 additions & 5 deletions qdrant_client/async_qdrant_fastembed.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
# ****** WARNING: THIS FILE IS AUTOGENERATED ******

import uuid
import warnings
from itertools import tee
from typing import Any, Iterable, Optional, Sequence, Union, get_args
from copy import deepcopy
Expand All @@ -29,6 +28,7 @@
from qdrant_client.http import models
from qdrant_client.hybrid.fusion import reciprocal_rank_fusion
from qdrant_client import grpc
from qdrant_client.common.client_warnings import show_warning

try:
from fastembed import (
Expand Down Expand Up @@ -151,10 +151,10 @@ def set_model(
None
"""
if max_length is not None:
warnings.warn(
"max_length parameter is deprecated and will be removed in the future. It's not used by fastembed models.",
DeprecationWarning,
stacklevel=2,
show_warning(
message="max_length parameter is deprecated and will be removed in the future. It's not used by fastembed models.",
category=DeprecationWarning,
stacklevel=3,
)
self._get_or_init_model(
model_name=embedding_model_name,
Expand Down
60 changes: 44 additions & 16 deletions qdrant_client/async_qdrant_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
# ****** WARNING: THIS FILE IS AUTOGENERATED ******

import importlib.metadata
import logging
import math
import platform
import warnings
from multiprocessing import get_all_start_methods
from typing import (
Any,
Expand All @@ -31,6 +29,7 @@
import numpy as np
from grpc import Compression
from urllib3.util import Url, parse_url
from qdrant_client.common.client_warnings import show_warning, show_warning_once
from qdrant_client import grpc as grpc
from qdrant_client._pydantic_compat import construct
from qdrant_client.auth import BearerAuth
Expand Down Expand Up @@ -117,7 +116,11 @@ def __init__(
self._rest_headers = kwargs.pop("metadata", {})
if api_key is not None:
if self._scheme == "http":
warnings.warn("Api key is used with an insecure connection.")
show_warning(
message="Api key is used with an insecure connection.",
category=UserWarning,
stacklevel=4,
)
self._rest_headers["api-key"] = api_key
self._grpc_headers.append(("api-key", api_key))
client_version = importlib.metadata.version("qdrant-client")
Expand Down Expand Up @@ -147,7 +150,11 @@ def __init__(
self._timeout = self.DEFAULT_GRPC_TIMEOUT
if self._auth_token_provider is not None:
if self._scheme == "http":
warnings.warn("Auth token provider is used with an insecure connection.")
show_warning(
message="Auth token provider is used with an insecure connection.",
category=UserWarning,
stacklevel=4,
)
bearer_auth = BearerAuth(self._auth_token_provider)
self._rest_args["auth"] = bearer_auth
self.openapi_client: AsyncApis[AsyncApiClient] = AsyncApis(
Expand All @@ -165,12 +172,16 @@ def __init__(
self.rest_uri, self._rest_headers, self._rest_args.get("auth")
)
if not server_version:
warnings.warn(
f"Failed to obtain server version. Unable to check client-server compatibility. Set check_version=False to skip version check."
show_warning(
message=f"Failed to obtain server version. Unable to check client-server compatibility. Set check_version=False to skip version check.",
category=UserWarning,
stacklevel=4,
)
elif not is_compatible(client_version, server_version):
warnings.warn(
f"Qdrant client version {client_version} is incompatible with server version {server_version}. Major versions should match and minor version difference must not exceed 1. Set check_version=False to skip version check."
show_warning(
message=f"Qdrant client version {client_version} is incompatible with server version {server_version}. Major versions should match and minor version difference must not exceed 1. Set check_version=False to skip version check.",
category=UserWarning,
stacklevel=4,
)

@property
Expand All @@ -182,16 +193,20 @@ async def close(self, grpc_grace: Optional[float] = None, **kwargs: Any) -> None
try:
await self._grpc_channel.close(grace=grpc_grace)
except AttributeError:
logging.warning(
"Unable to close grpc_channel. Connection was interrupted on the server side"
show_warning(
message="Unable to close grpc_channel. Connection was interrupted on the server side",
category=UserWarning,
stacklevel=4,
)
except RuntimeError:
pass
try:
await self.http.aclose()
except Exception:
logging.warning(
"Unable to close http connection. Connection was interrupted on the server side"
show_warning(
message="Unable to close http connection. Connection was interrupted on the server side",
category=UserWarning,
stacklevel=4,
)
self._closed = True

Expand Down Expand Up @@ -367,8 +382,11 @@ async def search(
**kwargs: Any,
) -> list[types.ScoredPoint]:
if not append_payload:
logging.warning(
"Usage of `append_payload` is deprecated. Please consider using `with_payload` instead"
show_warning_once(
message="Usage of `append_payload` is deprecated. Please consider using `with_payload` instead",
category=DeprecationWarning,
stacklevel=5,
idx="search-append-payload",
)
with_payload = append_payload
if isinstance(query_vector, np.ndarray):
Expand Down Expand Up @@ -2429,7 +2447,12 @@ async def create_collection(
**kwargs: Any,
) -> bool:
if init_from is not None:
logging.warning("init_from is deprecated")
show_warning_once(
message="init_from is deprecated",
category=DeprecationWarning,
stacklevel=5,
idx="create-collection-init-from",
)
if self._prefer_grpc:
if isinstance(vectors_config, (models.VectorParams, dict)):
vectors_config = RestToGrpc.convert_vectors_config(vectors_config)
Expand Down Expand Up @@ -2685,7 +2708,12 @@ async def create_payload_index(
**kwargs: Any,
) -> types.UpdateResult:
if field_type is not None:
warnings.warn("field_type is deprecated, use field_schema instead", DeprecationWarning)
show_warning_once(
message="field_type is deprecated, use field_schema instead",
category=DeprecationWarning,
stacklevel=5,
idx="payload-index-field-type",
)
field_schema = field_type
if self._prefer_grpc:
field_index_params = None
Expand Down
11 changes: 7 additions & 4 deletions qdrant_client/common/client_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
SEEN_MESSAGES = set()


def show_warning(message: str, category: type[Warning] = UserWarning) -> None:
warnings.warn(message, category, stacklevel=4)
def show_warning(message: str, category: type[Warning] = UserWarning, stacklevel: int = 2) -> None:
warnings.warn(message, category, stacklevel=stacklevel)


def show_warning_once(
message: str, category: type[Warning] = UserWarning, idx: Optional[str] = None
message: str,
category: type[Warning] = UserWarning,
idx: Optional[str] = None,
stacklevel: int = 1,
) -> None:
"""
Show a warning of the specified category only once per program run.
Expand All @@ -18,4 +21,4 @@ def show_warning_once(

if key not in SEEN_MESSAGES:
SEEN_MESSAGES.add(key)
show_warning(message, category)
show_warning(message, category, stacklevel)
27 changes: 17 additions & 10 deletions qdrant_client/local/async_qdrant_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import importlib.metadata
import itertools
import json
import logging
import os
import shutil
from copy import deepcopy
Expand All @@ -21,7 +20,7 @@
from uuid import uuid4
import numpy as np
import portalocker
from qdrant_client.common.client_warnings import show_warning_once
from qdrant_client.common.client_warnings import show_warning, show_warning_once
from qdrant_client._pydantic_compat import to_dict
from qdrant_client.async_client_base import AsyncQdrantBase
from qdrant_client.conversions import common_types as types
Expand Down Expand Up @@ -77,8 +76,10 @@ async def close(self, **kwargs: Any) -> None:
if collection is not None:
collection.close()
else:
logging.warning(
f"Collection appears to be None before closing. The existing collections are: {list(self.collections.keys())}"
show_warning(
message=f"Collection appears to be None before closing. The existing collections are: {list(self.collections.keys())}",
category=UserWarning,
stacklevel=4,
)
try:
if self._flock_file is not None and (not self._flock_file.closed):
Expand Down Expand Up @@ -108,10 +109,10 @@ def _load(self) -> None:
)
self.collections[collection_name] = collection
if len(collection.ids) > self.LARGE_DATA_THRESHOLD:
show_warning_once(
show_warning(
f"Local mode is not recommended for collections with more than {self.LARGE_DATA_THRESHOLD:,} points. Collection <{collection_name}> contains {len(collection.ids)} points. Consider using Qdrant in Docker or Qdrant Cloud for better performance with large datasets.",
category=UserWarning,
idx="large-local-collection",
stacklevel=5,
)
self.aliases = meta["aliases"]
lock_file_path = os.path.join(self.location, ".lock")
Expand Down Expand Up @@ -1044,16 +1045,22 @@ async def create_payload_index(
field_type: Optional[types.PayloadSchemaType] = None,
**kwargs: Any,
) -> types.UpdateResult:
logging.warning(
"Payload indexes have no effect in the local Qdrant. Please use server Qdrant if you need payload indexes."
show_warning_once(
message="Payload indexes have no effect in the local Qdrant. Please use server Qdrant if you need payload indexes.",
category=UserWarning,
idx="create-local-payload-indexes",
stacklevel=5,
)
return self._default_update_result()

async def delete_payload_index(
self, collection_name: str, field_name: str, **kwargs: Any
) -> types.UpdateResult:
logging.warning(
"Payload indexes have no effect in the local Qdrant. Please use server Qdrant if you need payload indexes."
show_warning_once(
message="Payload indexes have no effect in the local Qdrant. Please use server Qdrant if you need payload indexes.",
category=UserWarning,
idx="delete-local-payload-indexes",
stacklevel=5,
)
return self._default_update_result()

Expand Down
1 change: 1 addition & 0 deletions qdrant_client/local/local_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -2195,6 +2195,7 @@ def upsert(self, points: Union[Sequence[models.PointStruct], models.Batch]) -> N
"Consider using Qdrant in Docker or Qdrant Cloud for better performance with large datasets.",
category=UserWarning,
idx="large-local-collection",
stacklevel=6,
)

def _update_named_vectors(
Expand Down
28 changes: 18 additions & 10 deletions qdrant_client/local/qdrant_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import numpy as np
import portalocker

from qdrant_client.common.client_warnings import show_warning_once
from qdrant_client.common.client_warnings import show_warning, show_warning_once
from qdrant_client._pydantic_compat import to_dict
from qdrant_client.client_base import QdrantBase
from qdrant_client.conversions import common_types as types
Expand Down Expand Up @@ -77,9 +77,11 @@ def close(self, **kwargs: Any) -> None:
if collection is not None:
collection.close()
else:
logging.warning(
f"Collection appears to be None before closing. The existing collections are: "
f"{list(self.collections.keys())}"
show_warning(
message=f"Collection appears to be None before closing. The existing collections are: "
f"{list(self.collections.keys())}",
category=UserWarning,
stacklevel=4,
)

try:
Expand Down Expand Up @@ -111,14 +113,14 @@ def _load(self) -> None:
)
self.collections[collection_name] = collection
if len(collection.ids) > self.LARGE_DATA_THRESHOLD:
show_warning_once(
show_warning(
f"Local mode is not recommended for collections with more than "
f"{self.LARGE_DATA_THRESHOLD:,} points. "
f"Collection <{collection_name}> contains {len(collection.ids)} points. "
"Consider using Qdrant in Docker or Qdrant Cloud for better performance "
"with large datasets.",
category=UserWarning,
idx="large-local-collection",
stacklevel=5,
)
self.aliases = meta["aliases"]

Expand Down Expand Up @@ -1133,16 +1135,22 @@ def create_payload_index(
field_type: Optional[types.PayloadSchemaType] = None,
**kwargs: Any,
) -> types.UpdateResult:
logging.warning(
"Payload indexes have no effect in the local Qdrant. Please use server Qdrant if you need payload indexes."
show_warning_once(
message="Payload indexes have no effect in the local Qdrant. Please use server Qdrant if you need payload indexes.",
category=UserWarning,
idx="create-local-payload-indexes",
stacklevel=5,
)
return self._default_update_result()

def delete_payload_index(
self, collection_name: str, field_name: str, **kwargs: Any
) -> types.UpdateResult:
logging.warning(
"Payload indexes have no effect in the local Qdrant. Please use server Qdrant if you need payload indexes."
show_warning_once(
message="Payload indexes have no effect in the local Qdrant. Please use server Qdrant if you need payload indexes.",
category=UserWarning,
idx="delete-local-payload-indexes",
stacklevel=5,
)
return self._default_update_result()

Expand Down
1 change: 1 addition & 0 deletions qdrant_client/qdrant_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,7 @@ def upsert(
""",
category=DeprecationWarning,
idx="grpc-input",
stacklevel=4,
)

requires_inference = self._inference_inspector.inspect(points)
Expand Down
10 changes: 5 additions & 5 deletions qdrant_client/qdrant_fastembed.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import uuid
import warnings
from itertools import tee
from typing import Any, Iterable, Optional, Sequence, Union, get_args
from copy import deepcopy
Expand All @@ -21,6 +20,7 @@
from qdrant_client.http import models
from qdrant_client.hybrid.fusion import reciprocal_rank_fusion
from qdrant_client import grpc
from qdrant_client.common.client_warnings import show_warning

try:
from fastembed import (
Expand Down Expand Up @@ -153,11 +153,11 @@ def set_model(
"""

if max_length is not None:
warnings.warn(
"max_length parameter is deprecated and will be removed in the future. "
show_warning(
message="max_length parameter is deprecated and will be removed in the future. "
"It's not used by fastembed models.",
DeprecationWarning,
stacklevel=2,
category=DeprecationWarning,
stacklevel=3,
)

self._get_or_init_model(
Expand Down
Loading
Loading