Skip to content

Commit 7791229

Browse files
committed
Release: v6.3.0
- Added support for property roles and metadata
1 parent 9451ca6 commit 7791229

12 files changed

Lines changed: 212 additions & 27 deletions

recombee_api_client/api_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def __get_base_uri(options: dict, region: str) -> str:
105105

106106
@staticmethod
107107
def __get_http_headers(additional_headers: dict = None) -> dict:
108-
headers = {"User-Agent": "recombee-python-api-client/6.2.0"}
108+
headers = {"User-Agent": "recombee-python-api-client/6.3.0"}
109109
if additional_headers:
110110
headers.update(additional_headers)
111111
return headers

recombee_api_client/api_requests/add_item_property.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from recombee_api_client.inputs.property_metadata import PropertyMetadata
2+
from recombee_api_client.inputs.property_role import PropertyRole
13
from recombee_api_client.api_requests.request import Request
24
from recombee_api_client.utils.serialize_to_json import serialize_to_json
35
from typing import Union, List
@@ -19,7 +21,7 @@ class AddItemProperty(Request):
1921
:param type: Value type of the item property to be created. One of: `int`, `double`, `string`, `boolean`, `timestamp`, `set`, `image` or `imageList`.
2022
2123
22-
* `int`- Signed integer number.
24+
* `int` - Signed integer number.
2325
2426
2527
* `double` - Floating point number. It uses 64-bit base-2 format (IEEE 754 standard).
@@ -31,7 +33,7 @@ class AddItemProperty(Request):
3133
* `boolean` - *true* / *false*
3234
3335
34-
* `timestamp` - Value representing date and time.
36+
* `timestamp` - Value representing date and time. ISO8601-1 pattern (string) or UTC epoch time (number).
3537
3638
3739
* `set` - Set of strings.
@@ -43,9 +45,23 @@ class AddItemProperty(Request):
4345
* `imageList` - List of URLs that refer to images.
4446
4547
48+
49+
Optional parameters:
50+
51+
:param role: [Role](https://docs.recombee.com/api/property_roles_metadata#roles) to assign to the property.
52+
53+
54+
:param metadata: List of [metadata](https://docs.recombee.com/api/property_roles_metadata#metadata) entries to assign to the property.
55+
4656
"""
4757

48-
def __init__(self, property_name: str, type: str):
58+
def __init__(
59+
self,
60+
property_name: str,
61+
type: str,
62+
role: PropertyRole = DEFAULT,
63+
metadata: List[PropertyMetadata] = DEFAULT,
64+
):
4965
super().__init__(
5066
path="/items/properties/%s" % (property_name),
5167
method="put",
@@ -54,12 +70,19 @@ def __init__(self, property_name: str, type: str):
5470
)
5571
self.property_name = property_name
5672
self.type = type
73+
self.role = role
74+
self.metadata = metadata
5775

5876
def get_body_parameters(self) -> dict:
5977
"""
6078
Values of body parameters as a dictionary (name of parameter: value of the parameter).
6179
"""
6280
p = dict()
81+
p["type"] = serialize_to_json(self.type)
82+
if self.role is not DEFAULT:
83+
p["role"] = serialize_to_json(self.role)
84+
if self.metadata is not DEFAULT:
85+
p["metadata"] = serialize_to_json(self.metadata)
6386

6487
return p
6588

@@ -68,6 +91,5 @@ def get_query_parameters(self) -> dict:
6891
Values of query parameters as a dictionary (name of parameter: value of the parameter).
6992
"""
7093
params = dict()
71-
params["type"] = serialize_to_json(self.type)
7294

7395
return params

recombee_api_client/api_requests/add_user_property.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from recombee_api_client.inputs.property_metadata import PropertyMetadata
2+
from recombee_api_client.inputs.property_role import PropertyRole
13
from recombee_api_client.api_requests.request import Request
24
from recombee_api_client.utils.serialize_to_json import serialize_to_json
35
from typing import Union, List
@@ -31,15 +33,29 @@ class AddUserProperty(Request):
3133
* `boolean` - *true* / *false*
3234
3335
34-
* `timestamp` - Value representing date and time.
36+
* `timestamp` - Value representing date and time. ISO8601-1 pattern (string) or UTC epoch time (number).
3537
3638
3739
* `set` - Set of strings.
3840
3941
42+
43+
Optional parameters:
44+
45+
:param role: [Role](https://docs.recombee.com/api/property_roles_metadata#roles) to assign to the property.
46+
47+
48+
:param metadata: List of [metadata](https://docs.recombee.com/api/property_roles_metadata#metadata) entries to assign to the property.
49+
4050
"""
4151

42-
def __init__(self, property_name: str, type: str):
52+
def __init__(
53+
self,
54+
property_name: str,
55+
type: str,
56+
role: PropertyRole = DEFAULT,
57+
metadata: List[PropertyMetadata] = DEFAULT,
58+
):
4359
super().__init__(
4460
path="/users/properties/%s" % (property_name),
4561
method="put",
@@ -48,12 +64,19 @@ def __init__(self, property_name: str, type: str):
4864
)
4965
self.property_name = property_name
5066
self.type = type
67+
self.role = role
68+
self.metadata = metadata
5169

5270
def get_body_parameters(self) -> dict:
5371
"""
5472
Values of body parameters as a dictionary (name of parameter: value of the parameter).
5573
"""
5674
p = dict()
75+
p["type"] = serialize_to_json(self.type)
76+
if self.role is not DEFAULT:
77+
p["role"] = serialize_to_json(self.role)
78+
if self.metadata is not DEFAULT:
79+
p["metadata"] = serialize_to_json(self.metadata)
5780

5881
return p
5982

@@ -62,6 +85,5 @@ def get_query_parameters(self) -> dict:
6285
Values of query parameters as a dictionary (name of parameter: value of the parameter).
6386
"""
6487
params = dict()
65-
params["type"] = serialize_to_json(self.type)
6688

6789
return params

recombee_api_client/api_requests/recommend_next_item_segments.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,24 @@
99

1010
class RecommendNextItemSegments(Request):
1111
"""
12-
Returns Item segments that shall be shown to a user as next recommendations when the user e.g. scrolls the page down (*infinite scroll*) or goes to the next page.
12+
Returns [Item Segments](https://docs.recombee.com/segmentations) to be shown as the next recommendations when a user scrolls (e.g., within a carousel or feed of Item Segments such as brands, artists, topics, or categories).
13+
14+
The request requires the `recommId` of a base recommendation request and the number of Segments to return (`count`).
1315
14-
It accepts `recommId` of a base recommendation request (e.g., request from the first page) and the number of segments that shall be returned (`count`).
1516
The base request can be one of:
1617
- [Recommend Item Segments to Item](https://docs.recombee.com/api#recommend-item-segments-to-item)
1718
- [Recommend Item Segments to User](https://docs.recombee.com/api#recommend-item-segments-to-user)
1819
- [Recommend Item Segments to Item Segment](https://docs.recombee.com/api#recommend-item-segments-to-item-segment)
1920
- [Search Item Segments](https://docs.recombee.com/api#search-item-segments)
2021
21-
All the other parameters are inherited from the base request.
22+
All other parameters are inherited from the base request associated with the provided `recommId`.
2223
23-
*Recommend next Item segments* can be called many times for a single `recommId` and each call returns different (previously not recommended) segments.
24-
The number of *Recommend next Item segments* calls performed so far is returned in the `numberNextRecommsCalls` field.
24+
This endpoint can be called multiple times for a single `recommId`. Each call returns different Item Segments that have not been recommended in previous calls.
25+
The number of calls made so far is returned in the `numberNextRecommsCalls` field.
2526
26-
*Recommend next Item segments* can be requested up to 30 minutes after the base request or a previous *Recommend next Item segments* call.
27+
Requests can be made up to 30 minutes after the base request or the most recent Recommend Next Item Segments call.
2728
28-
For billing purposes, each call to *Recommend next Item segments* is counted as a separate recommendation request.
29+
For billing purposes, each call to this endpoint is counted as a separate recommendation request.
2930
3031
Required parameters:
3132

recombee_api_client/inputs/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from recombee_api_client.inputs.property_role import PropertyRole
2+
from recombee_api_client.inputs.property_metadata import PropertyMetadata
13
from recombee_api_client.inputs.composite_recommendation_stage_parameters import (
24
CompositeRecommendationStageParameters,
35
)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from recombee_api_client.inputs.input import Input
2+
from recombee_api_client.utils.serialize_to_json import serialize_to_json
3+
4+
from typing import Union, List
5+
from datetime import datetime
6+
import uuid
7+
8+
DEFAULT = uuid.uuid4()
9+
10+
11+
class PropertyMetadata(Input):
12+
"""
13+
Initializes PropertyMetadata input
14+
Required parameters:
15+
16+
:param name: Name of the [metadata](https://docs.recombee.com/api/property_roles_metadata#metadata) assigned to the property.
17+
18+
19+
Optional parameters:
20+
21+
:param settings: Optional configuration for this metadata entry.
22+
23+
"""
24+
25+
def __init__(self, name: str, settings: dict = DEFAULT):
26+
self.name = name
27+
self.settings = settings
28+
29+
def to_dict(self) -> dict:
30+
"""
31+
Serializes the input into a dict for sending to the Recombee API.
32+
"""
33+
res = dict()
34+
res["name"] = serialize_to_json(self.name)
35+
if self.settings is not DEFAULT:
36+
res["settings"] = serialize_to_json(self.settings)
37+
38+
return res
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from recombee_api_client.inputs.input import Input
2+
from recombee_api_client.utils.serialize_to_json import serialize_to_json
3+
4+
from typing import Union, List
5+
from datetime import datetime
6+
import uuid
7+
8+
DEFAULT = uuid.uuid4()
9+
10+
11+
class PropertyRole(Input):
12+
"""
13+
Initializes PropertyRole input
14+
Required parameters:
15+
16+
:param name: Name of the [role](https://docs.recombee.com/api/property_roles_metadata#roles) assigned to the property.
17+
18+
19+
Optional parameters:
20+
21+
:param settings: Optional configuration specific to the selected role.
22+
23+
"""
24+
25+
def __init__(self, name: str, settings: dict = DEFAULT):
26+
self.name = name
27+
self.settings = settings
28+
29+
def to_dict(self) -> dict:
30+
"""
31+
Serializes the input into a dict for sending to the Recombee API.
32+
"""
33+
res = dict()
34+
res["name"] = serialize_to_json(self.name)
35+
if self.settings is not DEFAULT:
36+
res["settings"] = serialize_to_json(self.settings)
37+
38+
return res

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
setup(
1212
name="recombee-api-client",
13-
version="6.2.0",
13+
version="6.3.0",
1414
description="Client for Recombee recommendation API",
1515
long_description=long_description,
1616
url="https://github.com/Recombee/python-api-client",
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
#
4+
# This file is auto-generated, do not edit
5+
#
6+
7+
import time
8+
from abc import ABC, abstractmethod
9+
from tests.test_cases.recombee_test import (
10+
RecombeeTest,
11+
InteractionsTest,
12+
RecommendationsTest,
13+
)
14+
from recombee_api_client.exceptions import ResponseException
15+
from recombee_api_client.api_requests import *
16+
17+
18+
class AddItemPropertyTest(RecombeeTest, ABC):
19+
20+
@abstractmethod
21+
def create_request(self, property_name, type, role=None, metadata=None):
22+
pass
23+
24+
def test_add_item_property(self):
25+
26+
# it 'does not fail with valid name and type'
27+
req = self.create_request("number", "int")
28+
resp = self.client.send(req)
29+
req = self.create_request("str", "string")
30+
resp = self.client.send(req)
31+
# it 'fails with invalid type'
32+
req = self.create_request("prop", "integer")
33+
try:
34+
self.client.send(req)
35+
self.fail()
36+
except ResponseException as ex:
37+
self.assertEqual(ex.status_code, 400)
38+
# it 'really stores property to the system'
39+
req = self.create_request("number2", "int")
40+
resp = self.client.send(req)
41+
try:
42+
self.client.send(req)
43+
self.fail()
44+
except ResponseException as ex:
45+
self.assertEqual(ex.status_code, 409)
46+
# it 'does not fail with valid property role and metadata'
47+
req = self.create_request("title", "string", role="title")
48+
resp = self.client.send(req)
49+
# it 'fails with duplicate property role or invalid metadata'
50+
req = self.create_request("str4", "string", role="summary")
51+
resp = self.client.send(req)
52+
try:
53+
self.client.send(req)
54+
self.fail()
55+
except ResponseException as ex:
56+
self.assertEqual(ex.status_code, 409)
57+
req = self.create_request("str5", "string", role="titl")
58+
try:
59+
self.client.send(req)
60+
self.fail()
61+
except ResponseException as ex:
62+
self.assertEqual(ex.status_code, 404)
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
from recombee_api_client.api_requests import *
1616

1717

18-
class AddPropertyTest(RecombeeTest, ABC):
18+
class AddUserPropertyTest(RecombeeTest, ABC):
1919

2020
@abstractmethod
21-
def create_request(self, property_name, type):
21+
def create_request(self, property_name, type, role=None, metadata=None):
2222
pass
2323

24-
def test_add_property(self):
24+
def test_add_user_property(self):
2525

2626
# it 'does not fail with valid name and type'
2727
req = self.create_request("number", "int")

0 commit comments

Comments
 (0)