Skip to content

Commit

Permalink
Merge branch 'stable/v3' into merge_in_v3_240624
Browse files Browse the repository at this point in the history
  • Loading branch information
dirkkul committed Jun 24, 2024
2 parents b0c89dc + 86b23c1 commit a6d3a34
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 19 deletions.
3 changes: 3 additions & 0 deletions integration_v3/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def test_authentication_user_pw(
"""Test authentication using Resource Owner Password Credentials Grant (User + PW)."""
# testing for warnings can be flaky without this as there are open SSL conections
warnings.filterwarnings(action="ignore", message="unclosed", category=ResourceWarning)
warnings.filterwarnings(action="ignore", message="Dep005", category=DeprecationWarning)

url = f"http://localhost:{port}"
assert is_auth_enabled(url)
Expand Down Expand Up @@ -207,6 +208,7 @@ def test_client_with_authentication_with_anon_weaviate(recwarn):
"""Test that we warn users when their client has auth enabled, but weaviate has only anon access."""
# testing for warnings can be flaky without this as there are open SSL conections
warnings.filterwarnings(action="ignore", message="unclosed", category=ResourceWarning)
warnings.filterwarnings(action="ignore", message="Dep005", category=DeprecationWarning)

url = f"http://localhost:{ANON_PORT}"
assert not is_auth_enabled(url)
Expand All @@ -227,6 +229,7 @@ def test_bearer_token_without_refresh(recwarn):

# testing for warnings can be flaky without this as there are open SSL conections
warnings.filterwarnings(action="ignore", message="unclosed", category=ResourceWarning)
warnings.filterwarnings(action="ignore", message="Dep005", category=DeprecationWarning)

url = f"http://localhost:{WCS_PORT}"
assert is_auth_enabled(url)
Expand Down
20 changes: 9 additions & 11 deletions mock_tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import json
from concurrent import futures

import grpc
import pytest
from grpc import ServicerContext
from grpc_health.v1.health_pb2 import HealthCheckResponse, HealthCheckRequest
from grpc_health.v1.health_pb2_grpc import HealthServicer, add_HealthServicer_to_server
from pytest_httpserver import HTTPServer, HeaderValueMatcher
from werkzeug.wrappers import Response

from weaviate.connect.base import ConnectionParams, ProtocolParams

from concurrent import futures
from grpc import ServicerContext
import grpc

from grpc_health.v1.health_pb2 import HealthCheckResponse, HealthCheckRequest
from grpc_health.v1.health_pb2_grpc import HealthServicer, add_HealthServicer_to_server

MOCK_IP = "127.0.0.1"
MOCK_PORT = 23536
MOCK_PORT_GRPC = 23537
Expand Down Expand Up @@ -53,13 +51,13 @@ def weaviate_mock(ready_mock):


@pytest.fixture(scope="function")
def weaviate_no_auth_mock(ready_mock):
ready_mock.expect_request("/v1/meta").respond_with_json({"version": "1.25"})
ready_mock.expect_request("/v1/.well-known/openid-configuration").respond_with_response(
def weaviate_no_auth_mock(weaviate_mock):
weaviate_mock.expect_request("/v1/meta").respond_with_json({"version": "1.25"})
weaviate_mock.expect_request("/v1/.well-known/openid-configuration").respond_with_response(
Response(json.dumps({}), status=404)
)

yield ready_mock
yield weaviate_mock


@pytest.fixture(scope="function")
Expand Down
32 changes: 31 additions & 1 deletion mock_tests/test_automatic_retries.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import json
import uuid
from typing import Optional

import pytest
import uuid
from werkzeug.wrappers import Request, Response

import weaviate
Expand Down Expand Up @@ -283,3 +283,33 @@ def callback_print_all(results: Optional[BatchResponse]):
# callback output for each object
print_output, err = capfd.readouterr()
assert print_output.count("\n") == n


def test_retries_with_tenant(weaviate_no_auth_mock):
tenant = "tenant"
first_try = True

def handler(request: Request):
nonlocal first_try
objects = request.json["objects"]
for obj in objects:
assert obj["tenant"] == tenant
obj["deprecations"] = None
if first_try == 0:
obj["result"] = {"errors": {"error": [{"message": "I'm an error message"}]}}
first_try = False
else:
obj["result"] = {}
return Response(json.dumps(objects))

weaviate_no_auth_mock.expect_request("/v1/batch/objects").respond_with_handler(handler)

client = weaviate.Client(url=MOCK_SERVER_URL)

n = 10
with client.batch(
weaviate_error_retries=WeaviateErrorRetryConf(number_retries=1),
) as batch:
for i in range(n):
batch.add_data_object({"name": "test" + str(i)}, "test", uuid.uuid4(), tenant=tenant)
weaviate_no_auth_mock.check_assertions()
6 changes: 6 additions & 0 deletions weaviate/batch/crud_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -806,9 +806,13 @@ def _readd_objects_after_timeout(
new_batch = ObjectsBatchRequest()
for obj in batch_request.get_request_body()["objects"]:
class_name = obj["class"]
tenant = obj.get("tenant", None)
uuid = obj["id"]
params = {"tenant": tenant} if tenant is not None else None

response_head = self._connection.head(
path="/objects/" + class_name + "/" + uuid,
params=params,
)

if response_head.status_code == 404:
Expand All @@ -823,6 +827,7 @@ def _readd_objects_after_timeout(
# object might already exist and needs to be overwritten in case of an update
response = self._connection.get(
path="/objects/" + class_name + "/" + uuid,
params=params,
)

obj_weav = _decode_json_response_dict(response, "Re-add objects")
Expand All @@ -835,6 +840,7 @@ def _readd_objects_after_timeout(
data_object=obj["properties"],
uuid=uuid,
vector=obj.get("vector", None),
tenant=tenant,
)
return new_batch

Expand Down
4 changes: 2 additions & 2 deletions weaviate/embedded.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ def wait_till_listening(self) -> None:
def check_supported_platform() -> None:
if platform.system() in ["Windows"]:
raise WeaviateStartUpError(
f"{platform.system()} is not supported with Embedded. Please upvote this feature request if "
f"you want this: https://github.com/weaviate/weaviate/issues/3315"
f"""{platform.system()} is not supported with EmbeddedDB. Please upvote this feature request if you want
this: https://github.com/weaviate/weaviate/issues/3315""" # noqa: E231
)

def stop(self) -> None:
Expand Down
12 changes: 7 additions & 5 deletions weaviate/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
import json
import os
import re
import uuid as uuid_lib
from enum import Enum, EnumMeta
from pathlib import Path
from typing import Union, Sequence, Any, Optional, List, Dict, Generator, Tuple, cast

import requests
import httpx
import uuid as uuid_lib
import requests
import validators
from requests.exceptions import JSONDecodeError

Expand All @@ -25,8 +25,8 @@
WeaviateInvalidInputError,
WeaviateUnsupportedFeatureError,
)
from weaviate.warnings import _Warnings
from weaviate.types import NUMBER, UUIDS, TIME
from weaviate.warnings import _Warnings

PYPI_PACKAGE_URL = "https://pypi.org/pypi/weaviate-client/json"
MAXIMUM_MINOR_VERSION_DELTA = 3 # The maximum delta between minor versions of Weaviate Client that will not trigger an upgrade warning.
Expand Down Expand Up @@ -240,8 +240,10 @@ def generate_local_beacon(
raise TypeError("Expected to_object_uuid of type str or uuid.UUID")

if class_name is None:
return {"beacon": f"weaviate://localhost/{uuid}"}
return {"beacon": f"weaviate://localhost/{_capitalize_first_letter(class_name)}/{uuid}"}
return {"beacon": f"weaviate://localhost/{uuid}"} # noqa: E231
return {
"beacon": f"weaviate://localhost/{_capitalize_first_letter(class_name)}/{uuid}" # noqa: E231
}


def _get_dict_from_object(object_: Union[str, dict]) -> dict:
Expand Down

0 comments on commit a6d3a34

Please sign in to comment.