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
11 changes: 9 additions & 2 deletions mock_tests/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
WeaviateStartUpError,
BackupCanceledError,
InsufficientPermissionsError,
UnexpectedStatusCodeError,
)

ACCESS_TOKEN = "HELLO!IamAnAccessToken"
Expand All @@ -54,9 +55,15 @@ def test_insufficient_permissions(
port=MOCK_PORT, host=MOCK_IP, grpc_port=MOCK_PORT_GRPC, skip_init_checks=True
)
collection = client.collections.get("Test")
with pytest.raises(InsufficientPermissionsError) as e:

with pytest.raises(InsufficientPermissionsError) as e1:
collection.config.get()
assert "this is an error" in e1.value.message

with pytest.raises(UnexpectedStatusCodeError) as e2:
collection.config.get()
assert "this is an error" in e.value.message
assert e2.value.status_code == 403

weaviate_mock.check_assertions()


Expand Down
1 change: 0 additions & 1 deletion requirements-devel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ mypy==1.13.0
mypy-extensions==1.0.0
tomli==2.2.1
types-protobuf==5.28.3.20241203
types-requests==2.32.0.20241016
types-urllib3==1.26.25.14
typing_extensions==4.12.2

Expand Down
154 changes: 0 additions & 154 deletions weaviate/connect/authentication.py

This file was deleted.

6 changes: 2 additions & 4 deletions weaviate/embedded.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from pathlib import Path
from typing import Dict, Optional, Tuple

import requests
import httpx
import validators

from weaviate import exceptions
Expand Down Expand Up @@ -88,9 +88,7 @@ def __init__(self, options: EmbeddedOptions) -> None:
self._parsed_weaviate_version = version_tag
self._set_download_url_from_version_tag(version_tag)
elif self.options.version == "latest":
response = requests.get(
"https://api.github.com/repos/weaviate/weaviate/releases/latest"
)
response = httpx.get("https://api.github.com/repos/weaviate/weaviate/releases/latest")
latest = _decode_json_response_dict(response, "get tag of latest weaviate release")
assert latest is not None
self._set_download_url_from_version_tag(latest["tag_name"])
Expand Down
50 changes: 27 additions & 23 deletions weaviate/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from json.decoder import JSONDecodeError
from typing import Union, Tuple

from grpc.aio import AioRpcError # type: ignore
import httpx
import requests

ERROR_CODE_EXPLANATION = {
413: """Payload Too Large. Try to decrease the batch size or increase the maximum request size on your weaviate
Expand Down Expand Up @@ -40,7 +40,7 @@ class UnexpectedStatusCodeError(WeaviateBaseError):
not handled in the client implementation and suggests an error.
"""

def __init__(self, message: str, response: Union[httpx.Response, requests.Response]):
def __init__(self, message: str, response: Union[httpx.Response, AioRpcError]):
"""
Is raised in case the status code returned from Weaviate is
not handled in the client implementation and suggests an error.
Expand All @@ -55,21 +55,27 @@ def __init__(self, message: str, response: Union[httpx.Response, requests.Respon
`response`:
The request response of which the status code was unexpected.
"""
self._status_code: int = response.status_code
# Set error message

try:
body = response.json()
except (requests.exceptions.JSONDecodeError, httpx.DecodingError, JSONDecodeError):
body = None

msg = (
message
+ f"! Unexpected status code: {response.status_code}, with response body: {body}."
)
if response.status_code in ERROR_CODE_EXPLANATION:
msg += " " + ERROR_CODE_EXPLANATION[response.status_code]

if isinstance(response, httpx.Response):
self._status_code: int = response.status_code
# Set error message

try:
body = response.json()
except (httpx.DecodingError, JSONDecodeError):
body = None

msg = (
message
+ f"! Unexpected status code: {response.status_code}, with response body: {body}."
)
if response.status_code in ERROR_CODE_EXPLANATION:
msg += " " + ERROR_CODE_EXPLANATION[response.status_code]
elif isinstance(response, AioRpcError):
self._status_code = int(response.code().value[0])
msg = (
message
+ f"! Unexpected status code: {response.code().value[1]}, with response body: {response.details()}."
)
super().__init__(msg)

@property
Expand All @@ -81,7 +87,7 @@ def status_code(self) -> int:


class ResponseCannotBeDecodedError(WeaviateBaseError):
def __init__(self, location: str, response: Union[httpx.Response, requests.Response]):
def __init__(self, location: str, response: httpx.Response):
"""Raised when a weaviate response cannot be decoded to json

Arguments:
Expand Down Expand Up @@ -360,10 +366,8 @@ def __init__(self, message: str, count: int) -> None:
super().__init__(msg)


class InsufficientPermissionsError(WeaviateBaseError):
class InsufficientPermissionsError(UnexpectedStatusCodeError):
"""Is raised when a request to Weaviate fails due to insufficient permissions."""

def __init__(self, res: httpx.Response) -> None:
err = res.json()["error"][0]["message"]
msg = f"""The request to Weaviate failed due to insufficient permissions. Details: {err}"""
super().__init__(msg)
def __init__(self, res: Union[httpx.Response, AioRpcError]) -> None:
super().__init__("forbidden", res)
12 changes: 4 additions & 8 deletions weaviate/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
from typing import Union, Sequence, Any, Optional, List, Dict, Generator, Tuple, cast

import httpx
import requests
import validators
from requests.exceptions import JSONDecodeError

from weaviate.exceptions import (
SchemaValidationError,
Expand Down Expand Up @@ -817,24 +815,22 @@ def _to_beacons(uuids: UUIDS, to_class: str = "") -> List[Dict[str, str]]:
return [{"beacon": f"weaviate://localhost/{to_class}{uuid_to}"} for uuid_to in uuids]


def _decode_json_response_dict(
response: Union[httpx.Response, requests.Response], location: str
) -> Optional[Dict[str, Any]]:
def _decode_json_response_dict(response: httpx.Response, location: str) -> Optional[Dict[str, Any]]:
if response is None:
return None

if 200 <= response.status_code < 300:
try:
json_response = cast(Dict[str, Any], response.json())
return json_response
except JSONDecodeError:
except httpx.DecodingError:
raise ResponseCannotBeDecodedError(location, response)

raise UnexpectedStatusCodeError(location, response)


def _decode_json_response_list(
response: Union[httpx.Response, requests.Response], location: str
response: httpx.Response, location: str
) -> Optional[List[Dict[str, Any]]]:
if response is None:
return None
Expand All @@ -843,7 +839,7 @@ def _decode_json_response_list(
try:
json_response = response.json()
return cast(list, json_response)
except JSONDecodeError:
except httpx.DecodingError:
raise ResponseCannotBeDecodedError(location, response)
raise UnexpectedStatusCodeError(location, response)

Expand Down
Loading