Skip to content

Commit

Permalink
refactor: Refactored the way of warnings (#864)
Browse files Browse the repository at this point in the history
* refactor: Refactored the way of warnings

* remove unused imports

* fix: Fix stacklevel in warnings

* regenerated async

* nit

* Updated some warnings with show once

* fix: Fix stack levels

* Updated async

* Update qdrant_client/qdrant_remote.py

Co-authored-by: George <[email protected]>

* Update async client

* Updated warnings

* Updated warnings

* Updated warnings

* fix: fix warning level

* fix: fix warning level in async

* fix: revert append payload condition

---------

Co-authored-by: George <[email protected]>
  • Loading branch information
hh-space-invader and joein committed Jan 16, 2025
1 parent a0d6c4b commit 908977e
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 70 deletions.
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 @@ -2435,7 +2453,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 @@ -2697,7 +2720,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 @@ -2196,6 +2196,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

0 comments on commit 908977e

Please sign in to comment.