Skip to content

Commit

Permalink
chore(recommendation): rename RecommendationClient to `Personalizat…
Browse files Browse the repository at this point in the history
…ionClient`
  • Loading branch information
shortcuts committed Sep 28, 2021
1 parent 91c60a3 commit e83269b
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 3 deletions.
16 changes: 16 additions & 0 deletions algoliasearch/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,19 @@ def build_hosts(self):
return HostsCollection(
[Host("{}.{}.{}".format("recommendation", self._region, "algolia.com"))]
)


class PersonalizationConfig(Config):
def __init__(self, app_id=None, api_key=None, region=None):
# type: (Optional[str], Optional[str], Optional[str]) -> None

self._region = "us" if region is None else region

super(PersonalizationConfig, self).__init__(app_id, api_key)

def build_hosts(self):
# type: () -> HostsCollection

return HostsCollection(
[Host("{}.{}.{}".format("personalization", self._region, "algolia.com"))]
)
70 changes: 70 additions & 0 deletions algoliasearch/personalization_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from typing import Optional, Union

from algoliasearch.configs import PersonalizationConfig
from algoliasearch.helpers import is_async_available
from algoliasearch.http.request_options import RequestOptions
from algoliasearch.http.requester import Requester
from algoliasearch.http.transporter import Transporter
from algoliasearch.http.verb import Verb


class PersonalizationClient(object):
def __init__(self, transporter, config):
# type: (Transporter, PersonalizationConfig) -> None

self._transporter = transporter
self._config = config

@staticmethod
def create(app_id=None, api_key=None, region=None):
# type: (Optional[str], Optional[str], Optional[str]) -> PersonalizationClient # noqa: E501

config = PersonalizationConfig(app_id, api_key, region)

return PersonalizationClient.create_with_config(config)

@staticmethod
def create_with_config(config):
# type: (PersonalizationConfig) -> PersonalizationClient

requester = Requester()
transporter = Transporter(requester, config)

client = PersonalizationClient(transporter, config)

if is_async_available():
from algoliasearch.personalization_client_async import (
PersonalizationClientAsync,
)
from algoliasearch.http.transporter_async import TransporterAsync
from algoliasearch.http.requester_async import RequesterAsync

return PersonalizationClientAsync(
client, TransporterAsync(RequesterAsync(), config), config
)

return client

def set_personalization_strategy(
self, personalization_strategy, request_options=None
): # noqa: E501
# type: (dict, Optional[Union[dict, RequestOptions]]) -> dict

return self._transporter.write(
Verb.POST,
"1/strategies/personalization",
personalization_strategy,
request_options,
)

def get_personalization_strategy(self, request_options=None):
# type: (Optional[Union[dict, RequestOptions]]) -> dict

return self._transporter.read(
Verb.GET, "1/strategies/personalization", None, request_options
)

def close(self):
# type: () -> None

return self._transporter.close() # type: ignore
43 changes: 43 additions & 0 deletions algoliasearch/personalization_client_async.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import types
import asyncio
from typing import Optional, Type

from algoliasearch.personalization_client import PersonalizationClient
from algoliasearch.configs import PersonalizationConfig
from algoliasearch.helpers_async import _create_async_methods_in
from algoliasearch.http.transporter_async import TransporterAsync


class PersonalizationClientAsync(PersonalizationClient):
def __init__(self, personalization_client, transporter, search_config):
# type: (PersonalizationClient, TransporterAsync, PersonalizationConfig) -> None # noqa: E501

self._transporter_async = transporter

super(PersonalizationClientAsync, self).__init__(
personalization_client._transporter, search_config
)

client = PersonalizationClient(transporter, search_config)

_create_async_methods_in(self, client)

@asyncio.coroutine
def __aenter__(self):
# type: () -> PersonalizationClientAsync # type: ignore

return self # type: ignore

@asyncio.coroutine
def __aexit__(self, exc_type, exc, tb): # type: ignore
# type: (Optional[Type[BaseException]], Optional[BaseException],Optional[types.TracebackType]) -> None # noqa: E501

yield from self.close_async() # type: ignore

@asyncio.coroutine
def close_async(self): # type: ignore
# type: () -> None

super().close()

yield from self._transporter_async.close() # type: ignore
54 changes: 53 additions & 1 deletion algoliasearch/recommendation_client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Optional, Union, Dict, Any
import warnings
from typing import Optional, Union

from algoliasearch.configs import RecommendationConfig
from algoliasearch.helpers import is_async_available
Expand All @@ -12,13 +13,25 @@ class RecommendationClient(object):
def __init__(self, transporter, config):
# type: (Transporter, RecommendationConfig) -> None

warnings.warn(
"`%s.%s` is deprecated, use `%s.%s` instead."
% ("RecommendationClient", "init", "PersonalizationClient", "init",),
DeprecationWarning,
)

self._transporter = transporter
self._config = config

@staticmethod
def create(app_id=None, api_key=None, region=None):
# type: (Optional[str], Optional[str], Optional[str]) -> RecommendationClient # noqa: E501

warnings.warn(
"`%s.%s` is deprecated, use `%s.%s` instead."
% ("RecommendationClient", "create", "PersonalizationClient", "create",),
DeprecationWarning,
)

config = RecommendationConfig(app_id, api_key, region)

return RecommendationClient.create_with_config(config)
Expand All @@ -27,6 +40,17 @@ def create(app_id=None, api_key=None, region=None):
def create_with_config(config):
# type: (RecommendationConfig) -> RecommendationClient

warnings.warn(
"`%s.%s` is deprecated, use `%s.%s` instead."
% (
"RecommendationClient",
"create_with_config",
"PersonalizationClient",
"create_with_config",
),
DeprecationWarning,
)

requester = Requester()
transporter = Transporter(requester, config)

Expand All @@ -50,6 +74,17 @@ def set_personalization_strategy(
): # noqa: E501
# type: (dict, Optional[Union[dict, RequestOptions]]) -> dict

warnings.warn(
"`%s.%s` is deprecated, use `%s.%s` instead."
% (
"RecommendationClient",
"set_personalization_strategy",
"PersonalizationClient",
"set_personalization_strategy",
),
DeprecationWarning,
)

return self._transporter.write(
Verb.POST,
"1/strategies/personalization",
Expand All @@ -60,11 +95,28 @@ def set_personalization_strategy(
def get_personalization_strategy(self, request_options=None):
# type: (Optional[Union[dict, RequestOptions]]) -> dict

warnings.warn(
"`%s.%s` is deprecated, use `%s.%s` instead."
% (
"RecommendationClient",
"get_personalization_strategy",
"PersonalizationClient",
"get_personalization_strategy",
),
DeprecationWarning,
)

return self._transporter.read(
Verb.GET, "1/strategies/personalization", None, request_options
)

def close(self):
# type: () -> None

warnings.warn(
"`%s.%s` is deprecated, use `%s.%s` instead."
% ("RecommendationClient", "close", "PersonalizationClient", "close",),
DeprecationWarning,
)

return self._transporter.close() # type: ignore
4 changes: 2 additions & 2 deletions algoliasearch/search_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def set_personalization_strategy(self, strategy, request_options=None):
% (
"SearchClient",
"set_personalization_strategy",
"RecommendationClient",
"PersonalizationClient",
"set_personalization_strategy",
),
DeprecationWarning,
Expand All @@ -363,7 +363,7 @@ def get_personalization_strategy(self, request_options=None):
% (
"SearchClient",
"get_personalization_strategy",
"RecommendationClient",
"PersonalizationClient",
"get_personalization_strategy",
),
DeprecationWarning,
Expand Down
46 changes: 46 additions & 0 deletions tests/features/test_personalization_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import unittest

from tests.helpers.env import Env
from tests.helpers.factory import Factory as F
from algoliasearch.exceptions import RequestException


class TestPersonalizationClient(unittest.TestCase):
def setUp(self):
self.client = F.personalization_client()

def tearDown(self):
self.client.close()

@unittest.skipIf(
Env.is_community(), "Community can not test personalization operations"
)
def test_personalization(self):
personalization_strategy = {
"eventsScoring": [
{"eventName": "Add to cart", "eventType": "conversion", "score": 50},
{"eventName": "Purchase", "eventType": "conversion", "score": 100},
],
"facetsScoring": [
{"facetName": "brand", "score": 100},
{"facetName": "categories", "score": 10},
],
"personalizationImpact": 0,
}

try:
response = self.client.set_personalization_strategy(
personalization_strategy
)
self.assertEqual(
response,
{"status": 200, "message": "Strategy was successfully updated"},
)
except RequestException as err:
self.assertEqual(
err,
RequestException("Number of strategy saves exceeded for the day", 429),
) # noqa: E501

response = self.client.get_personalization_strategy()
self.assertEqual(response, personalization_strategy)
17 changes: 17 additions & 0 deletions tests/helpers/factory.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
import datetime
import os
import platform
Expand All @@ -11,6 +12,7 @@
from algoliasearch.insights_client import InsightsClient
from algoliasearch.search_client import SearchClient, SearchConfig
from algoliasearch.recommendation_client import RecommendationClient
from algoliasearch.personalization_client import PersonalizationClient
from algoliasearch.http.hosts import HostsCollection, Host
from faker import Faker

Expand Down Expand Up @@ -82,11 +84,26 @@ def analytics_client(app_id=None, api_key=None):
def recommendation_client(app_id=None, api_key=None):
# type: (Optional[str], Optional[str]) -> RecommendationClient

warnings.warn(
"`%s` is deprecated, use `%s` instead."
% ("RecommendationClient", "PersonalizationClient",),
DeprecationWarning,
)

app_id = app_id if app_id is not None else Factory.get_app_id()
api_key = api_key if api_key is not None else Factory.get_api_key()

return Factory.decide(RecommendationClient.create(app_id, api_key))

@staticmethod
def personalization_client(app_id=None, api_key=None):
# type: (Optional[str], Optional[str]) -> PersonalizationClient

app_id = app_id if app_id is not None else Factory.get_app_id()
api_key = api_key if api_key is not None else Factory.get_api_key()

return Factory.decide(PersonalizationClient.create(app_id, api_key))

@staticmethod
def insights_client(app_id=None, api_key=None):
# type: (Optional[str], Optional[str]) -> InsightsClient
Expand Down

0 comments on commit e83269b

Please sign in to comment.