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
6 changes: 6 additions & 0 deletions integration/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,12 @@ def test_authentication_with_bearer_token_no_refresh() -> None:
assert str(recwarn.list[0].message).startswith("Auth002")


def test_api_key_string() -> None:
assert is_auth_enabled(f"localhost:{WCS_PORT}")
with weaviate.connect_to_local(port=WCS_PORT, auth_credentials="my-secret-key") as client:
client.collections.list_all()


def test_api_key() -> None:
assert is_auth_enabled(f"localhost:{WCS_PORT}")
with weaviate.connect_to_local(
Expand Down
15 changes: 13 additions & 2 deletions mock_tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import time
import warnings
from typing import Union

import grpc
import pytest
Expand Down Expand Up @@ -412,8 +413,18 @@ def handler(request: Request):
assert issubclass(w[0].category, UserWarning)


@pytest.mark.parametrize(
"api_key",
[
"Super-secret-key",
weaviate.auth.AuthApiKey(api_key="Super-secret-key"),
],
)
def test_with_simple_auth_no_oidc_via_api_key(
weaviate_mock: HTTPServer, start_grpc_server: grpc.Server, recwarn
weaviate_mock: HTTPServer,
start_grpc_server: grpc.Server,
recwarn,
api_key: Union[str, weaviate.auth.AuthApiKey],
) -> None:
weaviate_mock.expect_request(
"/v1/schema", headers={"Authorization": "Bearer " + "Super-secret-key"}
Expand All @@ -423,7 +434,7 @@ def test_with_simple_auth_no_oidc_via_api_key(
host=MOCK_IP,
port=MOCK_PORT,
grpc_port=MOCK_PORT_GRPC,
auth_credentials=weaviate.auth.AuthApiKey(api_key="Super-secret-key"),
auth_credentials=api_key,
)
client.collections.list_all()

Expand Down
59 changes: 41 additions & 18 deletions weaviate/connect/helpers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
"""Helper functions for creating new WeaviateClient or WeaviateAsyncClient instances in common scenarios."""

from typing import Dict, Optional, Tuple
from typing import Dict, Optional, Tuple, Union
from urllib.parse import urlparse

from deprecation import deprecated as docstring_deprecated
from typing_extensions import deprecated as typing_deprecated

from weaviate.auth import AuthCredentials
from weaviate.auth import (
Auth,
AuthCredentials,
_APIKey,
_BearerToken,
_ClientCredentials,
_ClientPassword,
)
from weaviate.client import WeaviateAsyncClient, WeaviateClient
from weaviate.config import AdditionalConfig
from weaviate.connect.base import ConnectionParams, ProtocolParams
Expand All @@ -27,9 +34,25 @@ def __parse_weaviate_cloud_cluster_url(cluster_url: str) -> Tuple[str, str]:
return cluster_url, grpc_host


def __parse_auth_credentials(creds: Union[str, AuthCredentials, None]) -> Optional[AuthCredentials]:
if isinstance(creds, str):
# If the credentials are a string, assume it's an API key.
return Auth.api_key(creds)
elif isinstance(
creds, (_BearerToken, _ClientPassword, _ClientCredentials, _APIKey)
): # use AuthCredentials after python 3.9 has been removed
# If the credentials are already an AuthCredentials object, return it as is.
return creds
elif creds is None:
# If no credentials are provided, return None.
return None
else:
raise ValueError("Invalid auth credentials provided.")


def connect_to_weaviate_cloud(
cluster_url: str,
auth_credentials: Optional[AuthCredentials],
auth_credentials: Union[str, AuthCredentials],
headers: Optional[Dict[str, str]] = None,
additional_config: Optional[AdditionalConfig] = None,
skip_init_checks: bool = False,
Expand All @@ -42,7 +65,7 @@ def connect_to_weaviate_cloud(

Args:
cluster_url: The WCD cluster URL or hostname to connect to. Usually in the form: rAnD0mD1g1t5.something.weaviate.cloud
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case use
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case pass a string or use
`weaviate.classes.init.Auth.api_key()`, a bearer token, in which case use `weaviate.classes.init.Auth.bearer_token()`, a client secret,
in which case use `weaviate.classes.init.Auth.client_credentials()` or a username and password, in which case use `weaviate.classes.init.Auth.client_password()`.
headers: Additional headers to include in the requests, e.g. API keys for third-party Cloud vectorization.
Expand Down Expand Up @@ -79,7 +102,7 @@ def connect_to_weaviate_cloud(
http=ProtocolParams(host=cluster_url, port=443, secure=True),
grpc=ProtocolParams(host=grpc_host, port=443, secure=True),
),
auth_client_secret=auth_credentials,
auth_client_secret=__parse_auth_credentials(auth_credentials),
additional_headers=headers,
additional_config=additional_config,
skip_init_checks=skip_init_checks,
Expand All @@ -98,7 +121,7 @@ def connect_to_weaviate_cloud(
)
def connect_to_wcs(
cluster_url: str,
auth_credentials: Optional[AuthCredentials],
auth_credentials: Union[str, AuthCredentials],
headers: Optional[Dict[str, str]] = None,
additional_config: Optional[AdditionalConfig] = None,
skip_init_checks: bool = False,
Expand All @@ -115,7 +138,7 @@ def connect_to_local(
headers: Optional[Dict[str, str]] = None,
additional_config: Optional[AdditionalConfig] = None,
skip_init_checks: bool = False,
auth_credentials: Optional[AuthCredentials] = None,
auth_credentials: Union[str, AuthCredentials, None] = None,
) -> WeaviateClient:
"""Connect to a local Weaviate instance deployed using Docker compose with standard port configurations.

Expand All @@ -130,7 +153,7 @@ def connect_to_local(
headers: Additional headers to include in the requests, e.g. API keys for Cloud vectorization.
additional_config: This includes many additional, rarely used config options. use wvc.init.AdditionalConfig() to configure.
skip_init_checks: Whether to skip the initialization checks when connecting to Weaviate.
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case use `weaviate.classes.init.Auth.api_key()`,
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case pass a string or use `weaviate.classes.init.Auth.api_key()`,
a bearer token, in which case use `weaviate.classes.init.Auth.bearer_token()`, a client secret, in which case use `weaviate.classes.init.Auth.client_credentials()`
or a username and password, in which case use `weaviate.classes.init.Auth.client_password()`.

Expand Down Expand Up @@ -168,7 +191,7 @@ def connect_to_local(
additional_headers=headers,
additional_config=additional_config,
skip_init_checks=skip_init_checks,
auth_client_secret=auth_credentials,
auth_client_secret=__parse_auth_credentials(auth_credentials),
)
)

Expand Down Expand Up @@ -277,7 +300,7 @@ def connect_to_custom(
grpc_secure: Whether to use a secure channel for the underlying gRPC API.
headers: Additional headers to include in the requests, e.g. API keys for Cloud vectorization.
additional_config: This includes many additional, rarely used config options. use wvc.init.AdditionalConfig() to configure.
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case use `weaviate.classes.init.Auth.api_key()`,
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case pass a string or use `weaviate.classes.init.Auth.api_key()`,
a bearer token, in which case use `weaviate.classes.init.Auth.bearer_token()`, a client secret, in which case use `weaviate.classes.init.Auth.client_credentials()`
or a username and password, in which case use `weaviate.classes.init.Auth.client_password()`.
skip_init_checks: Whether to skip the initialization checks when connecting to Weaviate.
Expand Down Expand Up @@ -323,7 +346,7 @@ def connect_to_custom(
grpc_port=grpc_port,
grpc_secure=grpc_secure,
),
auth_client_secret=auth_credentials,
auth_client_secret=__parse_auth_credentials(auth_credentials),
additional_headers=headers,
additional_config=additional_config,
skip_init_checks=skip_init_checks,
Expand Down Expand Up @@ -355,7 +378,7 @@ def use_async_with_weaviate_cloud(

Args:
cluster_url: The WCD cluster URL or hostname to connect to. Usually in the form: rAnD0mD1g1t5.something.weaviate.cloud
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case use `weaviate.classes.init.Auth.api_key()`,
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case pass a string or use `weaviate.classes.init.Auth.api_key()`,
a bearer token, in which case use `weaviate.classes.init.Auth.bearer_token()`, a client secret, in which case use `weaviate.classes.init.Auth.client_credentials()`
or a username and password, in which case use `weaviate.classes.init.Auth.client_password()`.
headers: Additional headers to include in the requests, e.g. API keys for third-party Cloud vectorization.
Expand Down Expand Up @@ -393,7 +416,7 @@ def use_async_with_weaviate_cloud(
http=ProtocolParams(host=cluster_url, port=443, secure=True),
grpc=ProtocolParams(host=grpc_host, port=443, secure=True),
),
auth_client_secret=auth_credentials,
auth_client_secret=__parse_auth_credentials(auth_credentials),
additional_headers=headers,
additional_config=additional_config,
skip_init_checks=skip_init_checks,
Expand All @@ -407,7 +430,7 @@ def use_async_with_local(
headers: Optional[Dict[str, str]] = None,
additional_config: Optional[AdditionalConfig] = None,
skip_init_checks: bool = False,
auth_credentials: Optional[AuthCredentials] = None,
auth_credentials: Union[str, AuthCredentials, None] = None,
) -> WeaviateAsyncClient:
"""Create an async client object ready to connect to a local Weaviate instance deployed using Docker compose with standard port configurations.

Expand All @@ -422,7 +445,7 @@ def use_async_with_local(
headers: Additional headers to include in the requests, e.g. API keys for Cloud vectorization.
additional_config: This includes many additional, rarely used config options. use wvc.init.AdditionalConfig() to configure.
skip_init_checks: Whether to skip the initialization checks when connecting to Weaviate.
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case use `weaviate.classes.init.Auth.api_key()`,
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case pass a string or use `weaviate.classes.init.Auth.api_key()`,
a bearer token, in which case use `weaviate.classes.init.Auth.bearer_token()`, a client secret, in which case use `weaviate.classes.init.Auth.client_credentials()`
or a username and password, in which case use `weaviate.classes.init.Auth.client_password()`.

Expand Down Expand Up @@ -462,7 +485,7 @@ def use_async_with_local(
additional_headers=headers,
additional_config=additional_config,
skip_init_checks=skip_init_checks,
auth_client_secret=auth_credentials,
auth_client_secret=__parse_auth_credentials(auth_credentials),
)


Expand Down Expand Up @@ -574,7 +597,7 @@ def use_async_with_custom(
grpc_secure: Whether to use a secure channel for the underlying gRPC API.
headers: Additional headers to include in the requests, e.g. API keys for Cloud vectorization.
additional_config: This includes many additional, rarely used config options. use wvc.init.AdditionalConfig() to configure.
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case use `weaviate.classes.init.Auth.api_key()`,
auth_credentials: The credentials to use for authentication with your Weaviate instance. This can be an API key, in which case pass a string or use `weaviate.classes.init.Auth.api_key()`,
a bearer token, in which case use `weaviate.classes.init.Auth.bearer_token()`, a client secret, in which case use `weaviate.classes.init.Auth.client_credentials()`
or a username and password, in which case use `weaviate.classes.init.Auth.client_password()`.
skip_init_checks: Whether to skip the initialization checks when connecting to Weaviate.
Expand Down Expand Up @@ -622,7 +645,7 @@ def use_async_with_custom(
grpc_port=grpc_port,
grpc_secure=grpc_secure,
),
auth_client_secret=auth_credentials,
auth_client_secret=__parse_auth_credentials(auth_credentials),
additional_headers=headers,
additional_config=additional_config,
skip_init_checks=skip_init_checks,
Expand Down
Loading