Skip to content

Add Or Update Networks #1097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
39 changes: 39 additions & 0 deletions meilisearch/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ def multi_search(
queries:
List of dictionaries containing the specified indexes and their search queries
https://www.meilisearch.com/docs/reference/api/search#search-in-an-index
It can also include remote options in federationOptions for each query
https://www.meilisearch.com/docs/reference/api/network
federation: (optional):
Dictionary containing offset and limit
https://www.meilisearch.com/docs/reference/api/multi_search
Expand Down Expand Up @@ -756,6 +758,43 @@ def generate_tenant_token(

return jwt_token

def add_or_update_networks(self, body: Union[MutableMapping[str, Any], None]) -> Dict[str, str]:
"""Set all the Remote Networks

Parameters
----------
body:
Remote networks that are allowed

Returns
-------
remote networks:
Remote Networks containing information about the networks allowed/present.
https://www.meilisearch.com/docs/reference/api/network

Raises
------
MeilisearchApiError
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://www.meilisearch.com/docs/reference/errors/error_codes#meilisearch-errors
"""

return self.http.patch(path=f"{self.config.paths.network}", body=body)

def get_all_networks(self) -> Dict[str, str]:
"""Fetches all the remote-networks present

Returns
-------
remote networks:
All remote networks containing information about each remote and their respective remote-name and searchApi key

Raises
------
MeilisearchApiError
An error containing details about why Meilisearch can't process your request. Meilisearch error codes are described here: https://www.meilisearch.com/docs/reference/errors/error_codes#meilisearch-errors
"""
return self.http.get(path=f"{self.config.paths.network}")

@staticmethod
def _base64url_encode(data: bytes) -> str:
return base64.urlsafe_b64encode(data).decode("utf-8").replace("=", "")
Expand Down
1 change: 1 addition & 0 deletions meilisearch/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Paths:
proximity_precision = "proximity-precision"
localized_attributes = "localized-attributes"
edit = "edit"
network = "network"

def __init__(
self,
Expand Down
35 changes: 34 additions & 1 deletion tests/client/test_client_multi_search_meilisearch.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest

from meilisearch.errors import MeilisearchApiError
from tests.common import INDEX_UID
from tests.common import INDEX_UID, REMOTE_MS_1, REMOTE_MS_2


def test_basic_multi_search(client, empty_index):
Expand Down Expand Up @@ -75,3 +75,36 @@ def test_multi_search_with_federation_options(client, index_with_documents):
assert response["hits"][0]["_federation"]["weightedRankingScore"] >= 0.99
assert response["limit"] == 2
assert response["offset"] == 0


@pytest.mark.usefixtures("enable_network_options")
def test_multi_search_with_network(client, index_with_documents):
"""Tests multi-search with network, with federation options."""
index_with_documents()
resp = client.add_or_update_networks(
{
"self": REMOTE_MS_1,
"remotes": {
REMOTE_MS_1: {
"url": "http://ms-1235.example.meilisearch.io",
"searchApiKey": "xxxxxxxx",
},
REMOTE_MS_2: {
"url": "http://ms-1255.example.meilisearch.io",
"searchApiKey": "xxxxxxxx",
},
},
}
)
response = client.multi_search(
[{"indexUid": INDEX_UID, "q": "", "federationOptions": {"remote": REMOTE_MS_1}}],
federation={},
)

assert "results" not in resp
assert "results" not in response
assert isinstance(response["hits"], list)
assert len(response["hits"]) >= 0
assert response["hits"][0]["_federation"]["indexUid"] == INDEX_UID
assert response["hits"][0]["_federation"]["remote"] == REMOTE_MS_1
assert response["remoteErrors"] == {}
30 changes: 30 additions & 0 deletions tests/client/test_client_network.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest

from tests.common import REMOTE_MS_1, REMOTE_MS_2


@pytest.mark.usefixtures("enable_network_options")
def test_get_all_networks(client):
"""Tests get all network in MS"""
response = client.get_all_networks()

assert isinstance(response, dict)


@pytest.mark.usefixtures("enable_network_options")
def test_add_or_update_networks(client):
"""Tests upsert network remote instance."""
body = {
"self": REMOTE_MS_1,
"remotes": {
REMOTE_MS_1: {"url": "http://localhost:7700", "searchApiKey": "xxxxxxxxxxxxxx"},
REMOTE_MS_2: {"url": "http://localhost:7720", "searchApiKey": "xxxxxxxxxxxxxxx"},
},
}
response = client.add_or_update_networks(body=body)

assert isinstance(response, dict)
assert response["self"] == REMOTE_MS_1
assert len(response["remotes"]) >= 2
assert REMOTE_MS_2 in response["remotes"]
assert REMOTE_MS_1 in response["remotes"]
3 changes: 3 additions & 0 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
{"uid": INDEX_UID2, "options": {"primaryKey": "book_id"}},
{"uid": INDEX_UID3, "options": {"uid": "wrong", "primaryKey": "book_id"}},
]

REMOTE_MS_1 = "ms_001"
REMOTE_MS_2 = "ms_002"
17 changes: 17 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,3 +274,20 @@ def new_embedders():
"default": UserProvidedEmbedder(dimensions=1).model_dump(by_alias=True),
"open_ai": OpenAiEmbedder().model_dump(by_alias=True),
}


@fixture
def enable_network_options():
requests.patch(
f"{common.BASE_URL}/experimental-features",
headers={"Authorization": f"Bearer {common.MASTER_KEY}"},
json={"network": True},
timeout=10,
)
yield
requests.patch(
f"{common.BASE_URL}/experimental-features",
headers={"Authorization": f"Bearer {common.MASTER_KEY}"},
json={"network": False},
timeout=10,
)