Skip to content

Commit 1d08e9e

Browse files
committed
Node.js client for Recombee recommendation API
0 parents  commit 1d08e9e

File tree

375 files changed

+55607
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

375 files changed

+55607
-0
lines changed

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
doc/

README.md

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Recombee API Client
2+
3+
A Node.js client (SDK) for easy use of the [Recombee](https://www.recombee.com/) recommendation API.
4+
5+
If you don't have an account at Recombee yet, you can create a free account [here](https://www.recombee.com/).
6+
7+
Documentation of the API can be found at [docs.recombee.com](https://docs.recombee.com/).
8+
9+
## Installation
10+
11+
```
12+
npm i recombee-api-client --save
13+
```
14+
15+
## Promises / callbacks
16+
17+
The SDK supports both Promises and callbacks, so you can choose the way which suits your coding style and conventions of your project:
18+
19+
```javascript
20+
//Using Promise
21+
client.send(new AddDetailView)
22+
.then((response) => {
23+
//handle response
24+
})
25+
.catch((error) => {
26+
//handle error
27+
});
28+
29+
//Using callback
30+
client.send(new AddDetailView,
31+
(error, response) => {
32+
//handle result
33+
}
34+
);
35+
```
36+
37+
38+
## Examples
39+
40+
### Basic example
41+
42+
```javascript
43+
var recombee = require('recombee-api-client');
44+
var rqs = recombee.requests;
45+
46+
var client = new recombee.ApiClient('--my-database-id--', '--my-secret-token--');
47+
48+
// Prepare some userIDs and itemIDs
49+
const NUM = 100;
50+
var userIds = Array.apply(0, Array(NUM)).map((_, i) => {
51+
return `user-${i}`;
52+
});
53+
54+
var itemIds = Array.apply(0, Array(NUM)).map((_, i) => {
55+
return `item-${i}`;
56+
});
57+
58+
59+
// Generate some random purchases of items by users
60+
const PROBABILITY_PURCHASED = 0.1;
61+
var purchases = [];
62+
userIds.forEach((userId) => {
63+
var purchased = itemIds.filter(() => Math.random() < PROBABILITY_PURCHASED);
64+
purchased.forEach((itemId) => {
65+
66+
purchases.push(new rqs.AddPurchase(userId, itemId, {'cascadeCreate': true}))
67+
68+
});
69+
});
70+
71+
// Send the data to Recombee, use Batch for faster processing of larger data
72+
client.send(new rqs.Batch(purchases))
73+
.then(() => {
74+
//Get 5 recommended items for user 'user-25'
75+
client.send(new rqs.UserBasedRecommendation('user-25', 5))
76+
.then((recommended) => {
77+
console.log(`Recommended items for user-25: ${recommended}`);
78+
});
79+
})
80+
.catch((error) => {
81+
console.error(error);
82+
// Use fallback
83+
});
84+
85+
```
86+
87+
### Using property values
88+
89+
```javascript
90+
var recombee = require('recombee-api-client');
91+
var rqs = recombee.requests;
92+
93+
var client = new recombee.ApiClient('--my-database-id--', '--my-secret-token--');
94+
const NUM = 100;
95+
96+
// We will use computers as items in this example
97+
// Computers have three properties
98+
// - price (floating point number)
99+
// - number of processor cores (integer number)
100+
// - description (string)
101+
102+
// Add properties of items
103+
client.send(new rqs.Batch([new rqs.ResetDatabase(), //TODO
104+
new rqs.AddItemProperty('price', 'double'),
105+
new rqs.AddItemProperty('num-cores', 'int'),
106+
new rqs.AddItemProperty('description', 'string'),
107+
new rqs.AddItemProperty('time', 'timestamp')
108+
]))
109+
.then((responses) => {
110+
//Prepare requests for setting a catalog of computers
111+
112+
var requests = Array.apply(0, Array(NUM)).map((_, i) => {
113+
return new rqs.SetItemValues(
114+
`computer-${i}`, //itemId
115+
//values:
116+
{
117+
'price': 600 + 400 * Math.random(),
118+
'num-cores': Math.floor(Math.random() * 8) + 1,
119+
'description': 'Great computer',
120+
'time': new Date().toISOString()
121+
},
122+
//optional parameters:
123+
{
124+
'cascadeCreate': true // Use cascadeCreate for creating item
125+
// with given itemId, if it doesn't exist
126+
}
127+
);
128+
});
129+
//Send catalog to the recommender system
130+
return client.send(new rqs.Batch(requests));
131+
})
132+
.then((responses) => {
133+
// Generate some random purchases of items by users
134+
var userIds = Array.apply(0, Array(NUM)).map((_, i) => {
135+
return `user-${i}`;
136+
});
137+
var itemIds = Array.apply(0, Array(NUM)).map((_, i) => {
138+
return `computer-${i}`;
139+
});
140+
141+
// Generate some random purchases of items by users
142+
const PROBABILITY_PURCHASED = 0.1;
143+
var purchases = [];
144+
userIds.forEach((userId) => {
145+
var purchased = itemIds.filter(() => Math.random() < PROBABILITY_PURCHASED);
146+
purchased.forEach((itemId) => {
147+
purchases.push(new rqs.AddPurchase(userId, itemId, {'cascadeCreate': true}))
148+
});
149+
});
150+
// Send purchases to the recommender system
151+
return client.send(new rqs.Batch(purchases));
152+
})
153+
.then((responses) => {
154+
// Get 5 recommendations for user-42, who is currently viewing computer-6
155+
return client.send(new rqs.ItemBasedRecommendation('computer-6', 5,
156+
{'targetUserId': 'user-42'}));
157+
})
158+
.then((recommended) => {
159+
console.log(`Recommended items: ${recommended}`);
160+
161+
// Get 5 recommendations for user-42, but recommend only computers that
162+
// have at least 3 cores
163+
return client.send(new rqs.ItemBasedRecommendation('computer-6', 5,
164+
{'targetUserId': 'user-42',
165+
'filter': "'num-cores'>=3"
166+
}));
167+
})
168+
.then((recommended) => {
169+
console.log(`Recommended items with at least 3 processor cores: ${recommended}`);
170+
171+
// Get 5 recommendations for user-42, but recommend only items that
172+
// are more expensive then currently viewed item (up-sell)
173+
return client.send(new rqs.ItemBasedRecommendation('computer-6', 5,
174+
{'targetUserId': 'user-42',
175+
'filter': "'num-cores'>=3"
176+
}));
177+
})
178+
.then((recommended) => {
179+
console.log(`Recommended up-sell items: ${recommended}`)
180+
})
181+
.catch((error) => {
182+
console.error(error);
183+
// Use fallback
184+
});
185+
```
186+
187+
## Errors handling
188+
189+
Various errors can occur while processing request, for example because of adding an already existing item or submitting interaction of nonexistent user without *cascadeCreate* set to true. These errors lead to the *ResponseError*, which is thrown or put to callback function by the *send* method of the client (depending on using Promises or callbacks). Another reason for errorneous request is a timeout. *ApiError* is the base class of both *ResponseError* and *TimeoutError*.
190+
191+
We are doing our best to provide the fastest and most reliable service, but production-level applications must implement a fallback solution since problems can always happen. The fallback might be, for example, showing the most popular items from the current category, or not displaying recommendations at all.

0 commit comments

Comments
 (0)