Skip to content

Commit

Permalink
Java client for Recombee API
Browse files Browse the repository at this point in the history
  • Loading branch information
OndraFiedler committed Aug 23, 2016
0 parents commit 3f80bd1
Show file tree
Hide file tree
Showing 173 changed files with 10,809 additions and 0 deletions.
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2015 Recombee s.r.o.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
178 changes: 178 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# Recombee API Client

A Java client for easy use of the [Recombee](https://www.recombee.com/) recommendation API.

If you don't have an account at Recombee yet, you can create a free account [here](https://www.recombee.com/).

Documentation of the API can be found at [docs.recombee.com](https://docs.recombee.com/).

## Installation

The client shall be available in the Maven Central Repository within days.
Until then, you can use [jitpack](https://jitpack.io/#Recombee/java-api-client) for an easy install.

## Examples

### Basic example

Examples are located in [src/examples](https://github.com/Recombee/java-api-client/tree/master/src/examples/java/com/recombee/api_client/examples/).

```java
package com.recombee.api_client.examples;

import com.recombee.api_client.RecombeeClient;
import com.recombee.api_client.api_requests.*;
import com.recombee.api_client.bindings.Recommendation;
import com.recombee.api_client.exceptions.ApiException;

import java.util.ArrayList;
import java.util.Random;

public class BasicExample {
public static void main(String[] args) {

RecombeeClient client = new RecombeeClient("client-test", "jGGQ6ZKa8rQ1zTAyxTc0EMn55YPF7FJLUtaMLhbsGxmvwxgTwXYqmUk5xVZFw98L");
try {
final int NUM = 100;
//Create some users and send them to Recombee, use Batch for faster processing
ArrayList<Request> addUserRequests = new ArrayList<Request>();
for (int i = 0; i < NUM; i++) addUserRequests.add(new AddUser(String.format("user-%s", i)));

System.out.println("Send users");
client.send(new Batch(addUserRequests));

//Now create some items
ArrayList<Request> addItemRequests = new ArrayList<Request>();
for (int i = 0; i < NUM; i++) addItemRequests.add(new AddItem(String.format("item-%s", i)));

System.out.println("Send items");
client.send(new Batch(addItemRequests));

// Generate some random purchases of items by users
final double PROBABILITY_PURCHASED = 0.01;
Random r = new Random();
ArrayList<Request> addPurchaseRequests = new ArrayList<Request>();
for (int i = 0; i < NUM; i++)
for (int j = 0; j < NUM; j++)
if (r.nextDouble() < PROBABILITY_PURCHASED)
addPurchaseRequests.add(new AddPurchase(String.format("user-%s", i),String.format("item-%s", j)));

System.out.println("Send purchases");
client.send(new Batch(addPurchaseRequests));

// Get 5 recommendations for user 'user-25'
Recommendation[] recommended = client.send(new UserBasedRecommendation("user-25", 5));
System.out.println("Recommended items:");
for(Recommendation rec: recommended) System.out.println(rec.getId());

} catch (ApiException e) {
e.printStackTrace();
//use fallback
}
}
}

```

### Using property values
```java
package com.recombee.api_client.examples;

import com.recombee.api_client.RecombeeClient;
import com.recombee.api_client.api_requests.*;
import com.recombee.api_client.bindings.Recommendation;
import com.recombee.api_client.exceptions.ApiException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

public class ItemPropertiesExample {
public static void main(String[] args) {

RecombeeClient client = new RecombeeClient("client-test", "jGGQ6ZKa8rQ1zTAyxTc0EMn55YPF7FJLUtaMLhbsGxmvwxgTwXYqmUk5xVZFw98L");

try {
client.send(new ResetDatabase()); //Clear everything from the database

/*
We will use computers as items in this example
Computers have three properties
- price (floating point number)
- number of processor cores (integer number)
- description (string)
*/

client.send(new AddItemProperty("price", "double"));
client.send(new AddItemProperty("num-cores", "int"));
client.send(new AddItemProperty("description", "string"));

// Prepare requests for setting a catalog of computers
final ArrayList<Request> requests = new ArrayList<Request>();
final int NUM = 100;
final Random rand = new Random();

for(int i=0; i<NUM; i++)
{
final SetItemValues req = new SetItemValues(
String.format("computer-%s",i), //itemId
//values:
new HashMap<String, Object>() {{
put("price", 600.0 + 400*rand.nextDouble());
put("num-cores", 1 + rand.nextInt(7));
put("description", "Great computer");
put("!cascadeCreate", true); // Use !cascadeCreate for creating item
// with given itemId, if it doesn't exist
}}
);
requests.add(req);
}
client.send(new Batch(requests)); // Send catalog to the recommender system

// Generate some random purchases of items by users
final double PROBABILITY_PURCHASED = 0.02;
ArrayList<Request> addPurchaseRequests = new ArrayList<Request>();
for (int i = 0; i < NUM; i++)
for (int j = 0; j < NUM; j++)
if (rand.nextDouble() < PROBABILITY_PURCHASED) {
AddPurchase req = new AddPurchase(String.format("user-%s", i),String.format("computer-%s", j))
.setCascadeCreate(true); //use cascadeCreate to create the users
addPurchaseRequests.add(req);
}
client.send(new Batch(addPurchaseRequests)); // Send purchases to the recommender system


// Get 5 recommendations for user-42, who is currently viewing computer-6
Recommendation[] recommended = client.send(new ItemBasedRecommendation("computer-6", 5)
.setTargetUserId("user-42"));
System.out.println("Recommended items:");
for(Recommendation rec: recommended) System.out.println(rec.getId());


// Get 5 recommendations for user-42, but recommend only computers that have at least 3 cores
recommended = client.send(new ItemBasedRecommendation("computer-6", 5).setTargetUserId("user-42")
.setFilter(" 'num-cores'>=3 "));
System.out.println("Recommended items with at least 3 processor cores:");
for(Recommendation rec: recommended) System.out.println(rec.getId());

// Get 5 recommendations for user-42, but recommend only items that are more expensive then currently viewed item (up-sell)
recommended = client.send(new ItemBasedRecommendation("computer-6", 5).setTargetUserId("user-42")
.setFilter(" 'price' > context_item[\"price\"] "));

System.out.println("Recommended up-sell items:");
for(Recommendation rec: recommended) System.out.println(rec.getId());

} catch (ApiException e) {
e.printStackTrace();
//Use fallback
}
}
}

```

## Exception handling

Various errors can occur while processing request, for example because of adding an already existing item or submitting interaction of nonexistent user without *setCascadeCreate(true)*. These errors lead to throwing the *ResponseException* by the *send* method of the client. Another reason for throwing an exception is a timeout. *ApiException* is the base class of both *ResponseException* and *ApiTimeoutException*.

We are doing our best to provide the fastest and most reliable service, but production-level applications must implement a fallback solution since errors can always happen. The fallback might be, for example, showing the most popular items from the current category, or not displaying recommendations at all.
67 changes: 67 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.recombee</groupId>
<artifactId>api-client</artifactId>
<version>1.2.3</version>

<name>Recombee API Client</name>
<description>A client library for easy use of the Recombee recommendation API</description>
<url>http://recombee.com</url>

<licenses>
<license>
<name>MIT License</name>
<url>http://www.opensource.org/licenses/mit-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>

<scm>
<url>https://github.com/Recombee/java-api-client</url>
<connection>scm:git:git@github.com:Recombee/java-api-client.git</connection>
<developerConnection>scm:git:git@github.com:Recombee/java-api-client.git</developerConnection>
</scm>

<developers>
<developer>
<id>ondra_fiedler</id>
<name>Ondrej Fiedler</name>
<email>ondrj.fiedler@recombee.com</email>
<url>https://github.com/OndraFiedler</url>
<organization>Recombee</organization>
<organizationUrl>http://recombee.com</organizationUrl>
</developer>
</developers>

<dependencies>
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.recombee.api_client.examples;

import com.recombee.api_client.RecombeeClient;
import com.recombee.api_client.api_requests.*;
import com.recombee.api_client.bindings.Recommendation;
import com.recombee.api_client.exceptions.ApiException;

import java.util.ArrayList;
import java.util.Random;

public class BasicExample {
public static void main(String[] args) {

RecombeeClient client = new RecombeeClient("client-test", "jGGQ6ZKa8rQ1zTAyxTc0EMn55YPF7FJLUtaMLhbsGxmvwxgTwXYqmUk5xVZFw98L");
try {
final int NUM = 100;
//Create some users and send them to Recombee, use Batch for faster processing
ArrayList<Request> addUserRequests = new ArrayList<Request>();
for (int i = 0; i < NUM; i++) addUserRequests.add(new AddUser(String.format("user-%s", i)));

System.out.println("Send users");
client.send(new Batch(addUserRequests));

//Now create some items
ArrayList<Request> addItemRequests = new ArrayList<Request>();
for (int i = 0; i < NUM; i++) addItemRequests.add(new AddItem(String.format("item-%s", i)));

System.out.println("Send items");
client.send(new Batch(addItemRequests));

// Generate some random purchases of items by users
final double PROBABILITY_PURCHASED = 0.01;
Random r = new Random();
ArrayList<Request> addPurchaseRequests = new ArrayList<Request>();
for (int i = 0; i < NUM; i++)
for (int j = 0; j < NUM; j++)
if (r.nextDouble() < PROBABILITY_PURCHASED)
addPurchaseRequests.add(new AddPurchase(String.format("user-%s", i),String.format("item-%s", j)));

System.out.println("Send purchases");
client.send(new Batch(addPurchaseRequests));

// Get 5 recommendations for user 'user-25'
Recommendation[] recommended = client.send(new UserBasedRecommendation("user-25", 5));
System.out.println("Recommended items:");
for(Recommendation rec: recommended) System.out.println(rec.getId());

} catch (ApiException e) {
e.printStackTrace();
//use fallback
}
}
}
Loading

0 comments on commit 3f80bd1

Please sign in to comment.