Skip to content

Commit d22c054

Browse files
committed
Support Recommend Items to Item Segment endpoint.
1 parent 19358b4 commit d22c054

File tree

6 files changed

+264
-3
lines changed

6 files changed

+264
-3
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ repositories {
1616
}
1717
1818
dependencies {
19-
implementation "com.recombee.apiclientkotlin:4.1.1"
19+
implementation "com.recombee.apiclientkotlin:5.0.0"
2020
}
2121
```
2222

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ plugins {
1818
}
1919

2020
group = "com.recombee"
21-
version = "4.1.1"
21+
version = "5.0.0"
2222

2323
repositories {
2424
mavenCentral()

gradle/wrapper/gradle-wrapper.jar

1 Byte
Binary file not shown.

src/main/kotlin/com/recombee/apiclientkotlin/RecombeeClient.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public class RecombeeClient(
165165
return OkHttp3Request.Builder()
166166
.url(processRequestUri(request))
167167
.post(createJsonRequestBody(request.bodyParameters))
168-
.header("User-Agent", "recombee-kotlin-api-client/4.1.1")
168+
.header("User-Agent", "recombee-kotlin-api-client/5.0.0")
169169
.build()
170170
}
171171

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/*
2+
This file is auto-generated, do not edit
3+
*/
4+
5+
package com.recombee.apiclientkotlin.requests
6+
import java.time.Instant
7+
import com.recombee.apiclientkotlin.requests.Request
8+
import com.recombee.apiclientkotlin.bindings.*
9+
10+
/**
11+
* Recommend Items to Item Segment
12+
* @param contextSegmentId ID of the segment from `contextSegmentationId` for which the recommendations are to be generated.
13+
* @param targetUserId ID of the user who will see the recommendations.
14+
15+
Specifying the *targetUserId* is beneficial because:
16+
17+
* It makes the recommendations personalized
18+
* Allows the calculation of Actions and Conversions
19+
in the graphical user interface,
20+
as Recombee can pair the user who got recommendations
21+
and who afterward viewed/purchased an item.
22+
23+
If you insist on not specifying the user, pass `null`
24+
(`None`, `nil`, `NULL` etc., depending on the language) to *targetUserId*.
25+
Do not create some special dummy user for getting recommendations,
26+
as it could mislead the recommendation models,
27+
and result in wrong recommendations.
28+
29+
For anonymous/unregistered users, it is possible to use, for example, their session ID.
30+
31+
* @param count Number of items to be recommended (N for the top-N recommendation).
32+
* @param scenario Scenario defines a particular application of recommendations. It can be, for example, "homepage", "cart", or "emailing".
33+
34+
You can set various settings to the [scenario](https://docs.recombee.com/scenarios.html) in the [Admin UI](https://admin.recombee.com). You can also see the performance of each scenario in the Admin UI separately, so you can check how well each application performs.
35+
36+
The AI that optimizes models to get the best results may optimize different scenarios separately or even use different models in each of the scenarios.
37+
38+
* @param cascadeCreate If an item of the given *itemId* or user of the given *targetUserId* doesn't exist in the database, it creates the missing entity/entities and returns some (non-personalized) recommendations. This allows, for example, rotations in the following recommendations for the user of the given *targetUserId*, as the user will be already known to the system.
39+
* @param returnProperties With `returnProperties=true`, property values of the recommended items are returned along with their IDs in a JSON dictionary. The acquired property values can be used to easily display the recommended items to the user.
40+
41+
Example response:
42+
```
43+
{
44+
"recommId": "0c6189e7-dc1a-429a-b613-192696309361",
45+
"recomms":
46+
[
47+
{
48+
"id": "tv-178",
49+
"values": {
50+
"description": "4K TV with 3D feature",
51+
"categories": ["Electronics", "Televisions"],
52+
"price": 342,
53+
"url": "myshop.com/tv-178"
54+
}
55+
},
56+
{
57+
"id": "mixer-42",
58+
"values": {
59+
"description": "Stainless Steel Mixer",
60+
"categories": ["Home & Kitchen"],
61+
"price": 39,
62+
"url": "myshop.com/mixer-42"
63+
}
64+
}
65+
],
66+
"numberNextRecommsCalls": 0
67+
}
68+
```
69+
70+
* @param includedProperties Allows specifying which properties should be returned when `returnProperties=true` is set. The properties are given as a comma-separated list.
71+
72+
Example response for `includedProperties=description,price`:
73+
```
74+
{
75+
"recommId": "6842c725-a79f-4537-a02c-f34d668a3f80",
76+
"recomms":
77+
[
78+
{
79+
"id": "tv-178",
80+
"values": {
81+
"description": "4K TV with 3D feature",
82+
"price": 342
83+
}
84+
},
85+
{
86+
"id": "mixer-42",
87+
"values": {
88+
"description": "Stainless Steel Mixer",
89+
"price": 39
90+
}
91+
}
92+
],
93+
"numberNextRecommsCalls": 0
94+
}
95+
```
96+
97+
* @param filter Boolean-returning [ReQL](https://docs.recombee.com/reql.html) expression, which allows you to filter recommended items based on the values of their attributes.
98+
99+
Filters can also be assigned to a [scenario](https://docs.recombee.com/scenarios.html) in the [Admin UI](https://admin.recombee.com).
100+
101+
* @param booster Number-returning [ReQL](https://docs.recombee.com/reql.html) expression, which allows you to boost the recommendation rate of some items based on the values of their attributes.
102+
103+
Boosters can also be assigned to a [scenario](https://docs.recombee.com/scenarios.html) in the [Admin UI](https://admin.recombee.com).
104+
105+
* @param logic Logic specifies the particular behavior of the recommendation models. You can pick tailored logic for your domain and use case.
106+
See [this section](https://docs.recombee.com/recommendation_logics.html) for a list of available logics and other details.
107+
108+
The difference between `logic` and `scenario` is that `logic` specifies mainly behavior, while `scenario` specifies the place where recommendations are shown to the users.
109+
110+
Logic can also be set to a [scenario](https://docs.recombee.com/scenarios.html) in the [Admin UI](https://admin.recombee.com).
111+
112+
* @param minRelevance **Expert option** If the *targetUserId* is provided: Specifies the threshold of how relevant must the recommended items be to the user. Possible values one of: "low", "medium", "high". The default value is "low", meaning that the system attempts to recommend a number of items equal to *count* at any cost. If there is not enough data (such as interactions or item properties), this may even lead to bestseller-based recommendations being appended to reach the full *count*. This behavior may be suppressed by using "medium" or "high" values. In such case, the system only recommends items of at least the requested relevance and may return less than *count* items when there is not enough data to fulfill it.
113+
114+
* @param rotationRate **Expert option** If the *targetUserId* is provided: If your users browse the system in real-time, it may easily happen that you wish to offer them recommendations multiple times. Here comes the question: how much should the recommendations change? Should they remain the same, or should they rotate? Recombee API allows you to control this per request in a backward fashion. You may penalize an item for being recommended in the near past. For the specific user, `rotationRate=1` means maximal rotation, `rotationRate=0` means absolutely no rotation. You may also use, for example, `rotationRate=0.2` for only slight rotation of recommended items.
115+
116+
* @param rotationTime **Expert option** If the *targetUserId* is provided: Taking *rotationRate* into account, specifies how long it takes for an item to recover from the penalization. For example, `rotationTime=7200.0` means that items recommended less than 2 hours ago are penalized.
117+
118+
* @param expertSettings Dictionary of custom options.
119+
120+
* @param returnAbGroup If there is a custom AB-testing running, return the name of the group to which the request belongs.
121+
122+
*/
123+
public class RecommendItemsToItemSegment (
124+
public val contextSegmentId: String,
125+
public val targetUserId: String,
126+
public val count: Long,
127+
public val scenario: String? = null,
128+
public val cascadeCreate: Boolean? = true,
129+
public val returnProperties: Boolean? = null,
130+
public val includedProperties: List<String>? = null,
131+
public val filter: String? = null,
132+
public val booster: String? = null,
133+
public val logic: Logic? = null,
134+
public val minRelevance: String? = null,
135+
public val rotationRate: Double? = null,
136+
public val rotationTime: Double? = null,
137+
public val expertSettings: Map<String, Any>? = null,
138+
public val returnAbGroup: Boolean? = null
139+
): Request<RecommendationResponse>(3000) {
140+
141+
/**
142+
* A string representing the path part of the URI.
143+
*/
144+
override val path: String
145+
get() = "/recomms/item-segments/items/"
146+
147+
/**
148+
* The query parameters for the request.
149+
*
150+
* A map containing the names and values of the query parameters.
151+
*/
152+
override val queryParameters: Map<String, Any>
153+
get() = emptyMap()
154+
155+
/**
156+
* The body parameters for the request.
157+
*
158+
* A map containing the names and values of the body parameters.
159+
*/
160+
override val bodyParameters: Map<String, Any>
161+
get() {
162+
val parameters = mutableMapOf<String, Any>(
163+
"contextSegmentId" to contextSegmentId,
164+
"targetUserId" to targetUserId,
165+
"count" to count
166+
)
167+
scenario?.let { parameters["scenario"] = it}
168+
cascadeCreate?.let { parameters["cascadeCreate"] = it}
169+
returnProperties?.let { parameters["returnProperties"] = it}
170+
includedProperties?.let { parameters["includedProperties"] = it}
171+
filter?.let { parameters["filter"] = it}
172+
booster?.let { parameters["booster"] = it}
173+
logic?.let { parameters["logic"] = it}
174+
minRelevance?.let { parameters["minRelevance"] = it}
175+
rotationRate?.let { parameters["rotationRate"] = it}
176+
rotationTime?.let { parameters["rotationTime"] = it}
177+
expertSettings?.let { parameters["expertSettings"] = it}
178+
returnAbGroup?.let { parameters["returnAbGroup"] = it}
179+
return parameters
180+
}
181+
182+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.recombee.apiclientkotlin
2+
3+
import org.junit.jupiter.api.Assertions.*
4+
import java.util.concurrent.CountDownLatch
5+
import java.util.concurrent.TimeUnit
6+
import kotlin.test.Test
7+
import kotlinx.coroutines.runBlocking
8+
import kotlin.random.Random
9+
10+
import com.recombee.apiclientkotlin.RecombeeTest
11+
import com.recombee.apiclientkotlin.requests.*
12+
import com.recombee.apiclientkotlin.bindings.*
13+
14+
15+
class TestRecommendItemsToItemSegment: RecombeeTest() {
16+
17+
@Test
18+
fun callbackTest() {
19+
// Initialize the real RecombeeClient
20+
val client = getClient()
21+
22+
// Create a RecommendItemsToItemSegment request
23+
val request = RecommendItemsToItemSegment("3", "user-1", 5, scenario = "i-to-is")
24+
25+
// CountDownLatch for waiting for the response
26+
val latch = CountDownLatch(1)
27+
28+
// Define a flag to track if the request was successful
29+
var requestSuccessful = false
30+
31+
// Call the send method
32+
client.send(request,
33+
onResponse = { response ->
34+
// Handle successful response
35+
requestSuccessful = true
36+
37+
assertEquals(response.recomms.size, 5)
38+
latch.countDown()
39+
},
40+
onFailure = { exception ->
41+
// Handle failure
42+
latch.countDown()
43+
fail("Request failed with exception: ${exception.message}")
44+
}
45+
)
46+
47+
// Wait for the response (with a timeout to avoid indefinitely waiting)
48+
val responseReceived = latch.await(30, TimeUnit.SECONDS)
49+
50+
// Assert that the response was received and the request was successful
51+
assertTrue(responseReceived, "The response was not received within the timeout period.")
52+
assertTrue(requestSuccessful, "The request did not complete successfully.")
53+
}
54+
55+
@Test
56+
fun coroutineTest() = runBlocking {
57+
// Initialize the real RecombeeClient
58+
val client = getClient()
59+
60+
// Create a RecommendItemsToItemSegment request
61+
val request = RecommendItemsToItemSegment("3", "user-1", 5, scenario = "i-to-is")
62+
63+
// Call the sendAsync method and wait for the result
64+
val result = client.sendAsync(request)
65+
66+
// Process the result
67+
result.onSuccess { response ->
68+
// Handle successful response
69+
assertEquals(response.recomms.size, 5)
70+
}.onFailure { exception ->
71+
// Handle failure
72+
fail("Request failed with exception: ${exception.message}")
73+
}
74+
75+
// Additional assertions can be added if necessary
76+
assertTrue(result.isSuccess, "The request did not complete successfully.")
77+
}
78+
79+
}

0 commit comments

Comments
 (0)