Skip to content
Open
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
6 changes: 6 additions & 0 deletions HTTPXODUS_RECON.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# HTTPXodus Recon — weaviate-python-client
Target: weaviate/weaviate-python-client (python-weaviate)
Author: xic <xiechen@cls.cn>
Status: recon complete; zero competitors; import OK; branch httpxodus/weaviate-recon
Network: HTTPS_PROXY=http://127.0.0.1:7890
Constraints: no AI co-author signature; no force-push; dual import verified
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ packages =
platforms = any
include_package_data = True
install_requires =
httpx>=0.26.0,<0.29.0
httpx2>=2.12.0
validators>=0.34.0,<1.0.0
authlib>=1.6.7,<2.0.0
# When bumping authlib to >=2.0.0, remove the `authlib.jose` deprecation
Expand Down
2 changes: 1 addition & 1 deletion weaviate/aliases/executor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Dict, Generic, List, Optional, cast

from httpx import Response
from httpx2 import Response

from weaviate.aliases.alias import AliasReturn, _WeaviateAlias
from weaviate.connect import executor
Expand Down
2 changes: 1 addition & 1 deletion weaviate/backup/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import time
from typing import Dict, Generic, List, Literal, Optional, Tuple, Union

from httpx import Response
from httpx2 import Response

from weaviate.backup.backup import (
STORAGE_NAMES,
Expand Down
2 changes: 1 addition & 1 deletion weaviate/client_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
cast,
)

from httpx import Response
from httpx2 import Response

from weaviate.collections.classes.internal import _GQLEntryReturnType, _RawGQLReturn
from weaviate.integrations import _Integrations
Expand Down
2 changes: 1 addition & 1 deletion weaviate/cluster/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import uuid
from typing import Generic, List, Optional, Union

from httpx import Response
from httpx2 import Response

from weaviate.cluster.models import (
ClusterStatistics,
Expand Down
2 changes: 1 addition & 1 deletion weaviate/cluster/replicate/executor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Generic, Literal, Optional, overload

from httpx import Response
from httpx2 import Response

from weaviate.cluster.models import (
ReplicateOperation,
Expand Down
2 changes: 1 addition & 1 deletion weaviate/collections/aggregations/base_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pathlib
from typing import Generic, List, Optional, TypeVar, Union, cast

from httpx import Response
from httpx2 import Response
from typing_extensions import ParamSpec

from weaviate.collections.classes.aggregate import (
Expand Down
2 changes: 1 addition & 1 deletion weaviate/collections/batch/rest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Dict, List, Optional

from httpx import Response
from httpx2 import Response

from weaviate.collections.classes.batch import (
BatchReference,
Expand Down
2 changes: 1 addition & 1 deletion weaviate/collections/collections/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
Union,
)

from httpx import Response
from httpx2 import Response
from pydantic import ValidationError

from weaviate.collections.classes.config import (
Expand Down
2 changes: 1 addition & 1 deletion weaviate/collections/config/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
overload,
)

from httpx import Response
from httpx2 import Response
from pydantic_core import ValidationError
from typing_extensions import deprecated

Expand Down
2 changes: 1 addition & 1 deletion weaviate/collections/data/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
overload,
)

from httpx import Response
from httpx2 import Response

from weaviate.collections.batch.base import _BatchDataWrapper
from weaviate.collections.batch.collection import (
Expand Down
2 changes: 1 addition & 1 deletion weaviate/collections/tenants/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from math import ceil
from typing import Any, Dict, Generic, List, Optional, Sequence, Union

from httpx import Response
from httpx2 import Response

from weaviate.collections.classes.tenants import (
Tenant,
Expand Down
20 changes: 10 additions & 10 deletions weaviate/connect/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from typing import Awaitable, Callable, Dict, List, Optional, Union

import httpx
import httpx2
from authlib.integrations.httpx_client import ( # type: ignore
AsyncOAuth2Client,
OAuth2Client,
Expand All @@ -25,8 +25,8 @@

Result = Union[OAuth2Client, Awaitable[AsyncOAuth2Client]]
MountsMaker = Union[
Callable[[], Dict[str, httpx.AsyncHTTPTransport]],
Callable[[], Dict[str, httpx.HTTPTransport]],
Callable[[], Dict[str, httpx2.AsyncHTTPTransport]],
Callable[[], Dict[str, httpx2.HTTPTransport]],
]


Expand Down Expand Up @@ -111,7 +111,7 @@ def _get_token_endpoint(self) -> executor.Result[str]:
if self._token_endpoint is not None:
return executor.return_(self._token_endpoint, self.__colour)

def resp(res: httpx.Response) -> str:
def resp(res: httpx2.Response) -> str:
data = _decode_json_response_dict(res, "Get token endpoint")
assert data is not None
token_endpoint = data["token_endpoint"]
Expand All @@ -121,19 +121,19 @@ def resp(res: httpx.Response) -> str:
if self.__colour == "async":

async def _execute() -> str:
mounts: Dict[str, httpx.AsyncBaseTransport] = {}
mounts: Dict[str, httpx2.AsyncBaseTransport] = {}
for key, mount in self.__make_mounts().items():
assert isinstance(mount, httpx.AsyncHTTPTransport)
assert isinstance(mount, httpx2.AsyncHTTPTransport)
mounts[key] = mount
async with httpx.AsyncClient(mounts=mounts) as client:
async with httpx2.AsyncClient(mounts=mounts) as client:
return resp(await client.get(self._open_id_config_url))

return _execute()
mounts: Dict[str, httpx.BaseTransport] = {}
mounts: Dict[str, httpx2.BaseTransport] = {}
for key, mount in self.__make_mounts().items():
assert isinstance(mount, httpx.BaseTransport)
assert isinstance(mount, httpx2.BaseTransport)
mounts[key] = mount
with httpx.Client(mounts=mounts) as client:
with httpx2.Client(mounts=mounts) as client:
return resp(client.get(self._open_id_config_url))

def get_auth_session(self) -> Result:
Expand Down
6 changes: 3 additions & 3 deletions weaviate/connect/v4.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from grpc.aio import Channel as AsyncChannel # type: ignore

# from grpclib.client import Channel
from httpx import (
from httpx2 import (
AsyncClient,
AsyncHTTPTransport,
Client,
Expand Down Expand Up @@ -624,14 +624,14 @@ def __get_timeout(
) -> Timeout:
"""Get the timeout for the request.

In this way, the client waits the `httpx` default of 5s when connecting to a socket (connect), writing chunks (write), and
In this way, the client waits the `httpx2` default of 5s when connecting to a socket (connect), writing chunks (write), and
acquiring a connection from the pool (pool), but a custom amount as specified for reading the response (read).

From the PoV of the user, a request is considered to be timed out if no response is received within the specified time.
They specify the times depending on how they expect Weaviate to behave. For example, a query might take longer than an insert or vice versa
but, in either case, the user only cares about how long it takes for a response to be received.

https://www.python-httpx.org/advanced/timeouts/
https://www.python-httpx2.org/advanced/timeouts/
"""
timeout = None
if method == "DELETE" or method == "PATCH" or method == "PUT":
Expand Down
2 changes: 1 addition & 1 deletion weaviate/debug/executor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Dict, Generic, Optional

from httpx import Response
from httpx2 import Response

from weaviate.classes.config import ConsistencyLevel
from weaviate.connect import executor
Expand Down
4 changes: 2 additions & 2 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 httpx
import httpx2
import validators

from weaviate import exceptions
Expand Down Expand Up @@ -88,7 +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 = httpx.get("https://api.github.com/repos/weaviate/weaviate/releases/latest")
response = httpx2.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
version_tag = latest["tag_name"]
Expand Down
12 changes: 6 additions & 6 deletions weaviate/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from json.decoder import JSONDecodeError
from typing import Optional, Tuple, Union, cast

import httpx
import httpx2
from grpc import Call, StatusCode # type: ignore
from grpc.aio import AioRpcError # type: ignore
from packaging import version
Expand Down Expand Up @@ -31,7 +31,7 @@ def __init__(self, message: str = ""):


class UnexpectedStatusCodeError(WeaviateBaseError):
def __init__(self, message: str, response: Union[httpx.Response, AioRpcError, Call]):
def __init__(self, message: str, response: Union[httpx2.Response, AioRpcError, Call]):
"""Is raised in case the status code returned from Weaviate is not handled in the client implementation and suggests an error.

Custom code can act on the attributes:
Expand All @@ -42,13 +42,13 @@ def __init__(self, message: str, response: Union[httpx.Response, AioRpcError, Ca
message: An error message specific to the context, in which the error occurred.
response: The request response of which the status code was unexpected.
"""
if isinstance(response, httpx.Response):
if isinstance(response, httpx2.Response):
self._status_code: int = response.status_code
# Set error message

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

msg = (
Expand Down Expand Up @@ -90,7 +90,7 @@ def error(self) -> Optional[str]:


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

Args:
Expand Down Expand Up @@ -398,7 +398,7 @@ def __init__(self, message: str, count: int) -> None:
class InsufficientPermissionsError(UnexpectedStatusCodeError):
"""Is raised when a request to Weaviate fails due to insufficient permissions."""

def __init__(self, res: Union[httpx.Response, AioRpcError, Call]) -> None:
def __init__(self, res: Union[httpx2.Response, AioRpcError, Call]) -> None:
super().__init__("forbidden", res)


Expand Down
2 changes: 1 addition & 1 deletion weaviate/export/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import time
from typing import Generic, List, Literal, Tuple, Union, overload

from httpx import Response
from httpx2 import Response

from weaviate.backup.backup import STORAGE_NAMES
from weaviate.connect import executor
Expand Down
2 changes: 1 addition & 1 deletion weaviate/groups/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Dict, Generic, List, Literal, Union, overload

from httpx import Response
from httpx2 import Response

from weaviate.connect import executor
from weaviate.connect.v4 import ConnectionType, _ExpectedStatusCodes
Expand Down
2 changes: 1 addition & 1 deletion weaviate/rbac/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import json
from typing import Dict, Generic, List, Optional, Sequence, Union, cast

from httpx import Response
from httpx2 import Response
from typing_extensions import deprecated

from weaviate.connect import executor
Expand Down
2 changes: 1 addition & 1 deletion weaviate/tokenization/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from typing import Any, Dict, Generic, List, Optional, Union, overload

from httpx import Response
from httpx2 import Response

from weaviate.collections.classes.config import (
StopwordsConfig,
Expand Down
2 changes: 1 addition & 1 deletion weaviate/users/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import datetime, timezone
from typing import Any, Dict, Generic, List, Literal, Optional, Union, cast, overload

from httpx import Response
from httpx2 import Response
from typing_extensions import deprecated

from weaviate.connect import executor
Expand Down
10 changes: 5 additions & 5 deletions weaviate/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from typing import Any, Callable, Dict, Generator, List, Optional, Sequence, Tuple, Union, cast
from urllib.parse import quote

import httpx
import httpx2
import validators

from weaviate.exceptions import (
Expand Down Expand Up @@ -725,22 +725,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: httpx.Response, location: str) -> Optional[Dict[str, Any]]:
def _decode_json_response_dict(response: httpx2.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 (httpx.DecodingError, json.decoder.JSONDecodeError):
except (httpx2.DecodingError, json.decoder.JSONDecodeError):
raise ResponseCannotBeDecodedError(location, response)

raise UnexpectedStatusCodeError(location, response)


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

Expand Down