productAI

Image Search

ProductAI provides our corporate customers with customizable AI services based on their own data, which is managed as data set. Currently, our platform supports two types of data set: image set and product set. In search service, a data set is a collection of data. Compared with traditional database, data set can be regarded as the table in the traditional database, and the search service can be regarded as the index on the data table.

Image Set

Each image in image set (to analogy with data record in data table). Every image uses url as an unique id. The different url means the different data. If 2 records have the same url will be treated as the single record. When a new image set is created, an unique id is assigned, called IMAGE_SET_ID.

Create Image Set

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_set_creating_api()
resp = api.create_image_set(name=SET_NAME, description=SET_DESC)

if resp.status_code == 200:
import json
image_set = json.loads(resp.content)
image_set_id = image_set['id']
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->createImageSet($name=SET_NAME, $description=SET_DESC);
$image_set_id = $result['id'];
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.dataset.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
CreateDataSetRequest request = new CreateDataSetRequest(SET_NAME, SET_DESC);

CreateDataSetResponse response = client.getResponse(request);

String image_set_id = response.getDataSetId();
// return all the fields as JSON
// String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version="1",
AccessKeyId=ACCESS_KEY_ID,
SecretKey=SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

// Create request with image set name and description
var request = new CreateDataSetRequest
{
Name=SET_NAME,
Description=SET_DESC
};

var response = client.GetResponse(request);
var dataSetId = response.DataSetId;
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"name": "NAME", "description": "DESC"}' \
https://api.productai.com/image_sets/_0000014

Request

ArgumentTypeDescriptionRequiredLimitation
nameStringimage set nameYesMaximum 16 unicode characters, the extra characters are truncated
descriptionStringimage set descriptionNoMaximum 128 unicode characters, the extra characters are truncated

Response

200 HTTP Status Code
{
"created_at": "2017-12-13T08:40:51Z",
"creator_id": ...,
"description": "yyy",
"id": "l5qwws5f",
"modified_at": "2017-12-13T08:40:51Z",
"n_downloaded": 0,
"n_failed": 0,
"n_items": 0,
"name": "xxx",
"request_id": "53361e08-dfe1-11e7-a97c-664c03c7cfbb",
"status": "not-downloaded"
}
FeildTypeDescription
created_atStringCreated UTC datetime, the format is: %Y-%m-%dT%H:%M:%SZ
creator_idIntegerCreator ID
descriptionStringImage set description
idStringUnique ID, all the image set related APIs will use this ID to identify a image set
modified_atStringLast modified UTC datetime, the format is: %Y-%m-%dT%H:%M:%SZ
n_downloadedIntegerThe count of successful downloaded image
n_failedIntegerThe count of failed downloaded image
n_itemsIntegerThe total non-deleted image count
nameStringImage set name
request_idStringThe unique ID of this request, it can be used in product issue debugging with ProductAI support team
statusStringThe status of image set. If no any image is downloaded, the value is not-downloaded. If some of images are downloaded successfully, but the other haven’t been downloaded yet, the value of this field is downloading. If all the images were download successfully or failed, the value is downloaded
Non-200 HTTP Status Code
{
"error_code": 5001,
"message": "lineno 1 : `` should be a valid image URL less than or equal to 512 characters in length",
"request_id": "810c0180-e00e-11e7-9a0f-b217471bc47d"
}
FieldTypeDescription
error_codeIntegerDetailed error code
messageStringDetailed error message
request_idStringThe unique ID of this request, it can be used in product issue debugging with ProductAI support team

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aImage set creation successfully
4005004Missing image set name
4033003The total count of image sets for single account has an upper bound. Once user created too many image sets more than the limitation, he will receive this error code. More information, please read What is the difference between paid account and trial account?

List Image Sets

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_set_api()
resp = api.get_image_sets()
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->getImageSets();
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.dataset.GetAllDataSetsRequest;
import cn.productai.api.pai.entity.dataset.GetAllDataSetsResponse;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
GetAllDataSetsRequest request = new GetAllDataSetsRequest();

GetAllDataSetsResponse response = client.getResponse(request);

// return all the fields as JSON
// String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version="1",
AccessKeyId=ACCESS_KEY_ID,
SecretKey=SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

// Create request
var request = new GetAllDataSetsRequest;

var response = client.GetResponse(request);
curl -X GET \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
https://api.productai.com/get_image_sets/_0000014

Request

N/a

Response

200 HTTP Status Code
{
"request_id": "a05da544-0f9c-11e8-8f9b-0242ac120103",
"results": [
{
"created_at": "2018-02-06T12:32:22Z",
"creator_id": ...,
"description": "...",
"id": "37coud1d",
"modified_at": "2018-02-07T01:53:12Z",
"n_downloaded": 319,
"n_failed": 0,
"n_items": 319,
"name": "...",
"status": "downloaded"
},
...
]
}
FieldTypeDescription
resultsArrayAll the existing image sets, the fields of single item in array is same as Create Image Set Response
request_idStringThe unique ID of this request, it can be used in product issue debugging with ProductAI support team

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aList image sets successfully

Fetch Image Set

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_set_api(IMAGE_SET_ID)
resp = api.get_image_set()
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->getImageset($set_id=IMAGE_SET_ID);
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.dataset.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

// Create a request with a IMAGE_SET_ID
IWebClient client = new DefaultProductAIClient(profile);
GetDataSetInfoRequest request = new GetDataSetInfoRequest(IMAGE_SET_ID);

// Parse the result from response
GetDataSetInfoResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

// Create a request with IMAGE_SET_ID
var request = new GetDataSetInfoRequest
{
DataSetId = IMAGE_SET_ID
};

var response = client.GetResponse(request);
curl -X GET \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
https://api.productai.com/image_sets/_0000014/IMAGE_SET_ID

Request

N/a

Response

Same as Create Image Set Response

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aFetch image set successfully
4031002Authentication failed
4042001Image set doesn’t exist

Modify Image Set

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_set_api(IMAGE_SET_ID)

# Modify the name of image set
resp = api.update_image_set(name=NEW_NAME)

# Modify the description of image set
resp = api.update_image_set(description=NEW_DESC)

# Modify both
resp = api.update_image_set(name=NEW_NAME, description=NEW_DESC)
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->updateImageSetNameDesc($set_id=IMAGE_SET_ID, $name=NEW_NAME, $description=NEW_DESC);
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.dataset.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

// Set image set name and description
IWebClient client = new DefaultProductAIClient(profile);
UpdateDataSetRequest request = new UpdateDataSetRequest(IMAGE_SET_ID, SET_NAME, SET_DESC);

// Parse the response
UpdateDataSetResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

// Create a request with new name and new description
var request = new UpdateDataSetRequest
{
Name = SET_NAME,
Description = SET_DESC,
DataSetId = IMAGE_SET_ID,
};
var response = client.GetResponse(request);
curl -X PUT \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"name": "NEW_NAME", "description": "NEW_DESC"}' \
https://api.productai.com/image_sets/_0000014/IMAGE_SET_ID

Request

Same as Create Image Set Request

Response

Same as Create Image Set Response

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aModify image set successfully
4005004Empty image set name is disallowed
4031002Authentication failed
4042001Image set doesn’t exist

Delete Image Set

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_set_api(IMAGE_SET_ID)

resp = api.delete_image_set()
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->removeImageSet($set_id=IMAGE_SET_ID);
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.dataset.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
DeleteDataSetRequest request = new DeleteDataSetRequest(IMAGE_SET_ID);

DeleteDataSetResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

var request = new DeleteDataSetRequest
{
DataSetId = IMAGE_SET_ID
};
var response = client.GetResponse(request);
curl -X DELETE \
-H 'x-ca-accesskeyid:ACCESS_KEY_ID' \
https://api.productai.com/image_sets/_0000014/IMAGE_SET_ID

Request

N/a

Response

N/a

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
204N/aDelete image set successfully
4031002Authentication failed
4033001Can’t delete image set because some running services depend on it
4042001Image set doesn’t exist

Data

There are 3 fields can be included in a image data:

  • url, Url of uploading image, currently this url is used as the unique ID, that means different url indicates different image data.
  • metadata, information about the image, it is returned in response along with image
  • tags, tags for the image, it is searched with image and can be used in tag filter. Note that multiple tags should be delimited by |

Add Single Data to Image Set

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_set_api(IMAGE_SET_ID)
api.add_image(url, meta, tags='cartoon|square')
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->addImageToSet($set_id=IMAGE_SET_ID, $image_url='http://yyyy', $meta="metadata" , $tags=200 ['cartoon','square']);
import java.util.ArrayList;
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.dataset.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);

ArrayList<String> tagList = new ArrayList<String>();
tagList.add("cartoon");
tagList.add("square");

DataSetSingleAddByImageUrlRequest request = new DataSetSingleAddByImageUrlRequest(IMAGE_SET_ID, tagList, "metadata");
request.imageUrl = "http://yyyy";

DataSetBaseResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

// Create a request to add an image with url, tags, and metadata. tags and metadata are optional fields.
var request = new DataSetSingleAddByImageUrlRequest(IMAGE_SET_ID, "http://yyyy", tags=new List<String>() {"cartoon", "square"}, metaId="metadata");
var response = client.GetResponse(request);
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-d 'image_url=http://yyyy&meta=metadata&tags=cartoon|square' \
https://api.productai.com/image_sets/_0000014/IMAGE_SET_ID

Request

ArgumentTypeDescriptionRequiredLimitation
urlStringURL for uploading imageYesMaximum 512 unicode characters, will raise an error if length exceeds this limit
metaStringData descriptionNoMaximum 512 unicode characters, will raise an error if length exceeds this limit
tagsStringData tagsNoTags are indexed along with image data, and are used in filtering requests initiated by user. Note that this field can contain multiple tags, they should be delimited with ‘|’, For example: coat|tshirt|POLO. Please use utf-8 encoding for non-ascii characters

Response

Same as Create Image Set Response

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aUpload data successfully
4005001Url contains more than 512 unicode characters, or Url is empty, or meta field contains more than 512 unicode characters
4031002Authentication failed
4042001Image set doesn’t exist
5004001Can’t download the image from url.

Add Multiple Data to Image Set

It is recommended to use csv file to prepare image data, and then upload the csv file. Note that each line in the csv file should contain one image data. The format should follow this pattern: each line contains 3 columns, that is image Url, image metadata(optional), tags(optional). For details, please refer to csv file example. Example of batch uploading images to image set:

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_set_api(IMAGE_SET_ID)
with open('added.csv') as f:
api.add_images_in_bulk(f)
use ProductAI;
$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->addImagesToSet($set_id=IMAGE_SET_ID, $filename = 'added.csv');
import java.io.File;
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.dataset.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
DataSetBatchAddRequest request = new DataSetBatchAddRequest(IMAGE_SET_ID);
request.setCsvFile(new File("added.csv"));

DataSetBaseResponse response = client.getResponse(request);
String json=response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

var request = new DataSetBatchAddRequest(IMAGE_SET_ID)
{
CsvFile = new System.IO.FileInfo(@"added.csv")
};
var response = client.GetResponse(request);
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-F "urls_to_add=@add.csv" \
https://api.productai.com/image_sets/_0000014/IMAGE_SET_ID

This API service also supports tar.gz compressed file. You can create compressed file by following command

tar zcvf added.tar.gz added.csv

Request

ArugumentTypeDescriptionRequiredLimitation
fFilecsv file content, for csv file format please refer to csv file exampleYesshould be smaller than 50MB

Response

Same as Create Image Set Response

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aSuccess
4005001Invalid csv file, for example: contains more than 3 columns in one line, the first column is not a valid url
4031002Authentication failed
4042001Image set doesn’t exist

Delete Multiple Data from Image Set

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_set_api(IMAGE_SET_ID)
with open('deleted.csv') as f:
api.delete_images_in_bulk(f)
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->removeImagesFromSet($set_id=IMAGE_SET_ID, $filename = 'deleted.csv');
import java.io.File;
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.dataset.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
DataSetBatchDeleteRequest request = new DataSetBatchDeleteRequest(IMAGE_SET_ID);
request.setCsvFile(new File("deleted.csv"));

DataSetBaseResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

var request = new DataSetBatchDeleteRequest(IMAGE_SET_ID)
{
CsvFile = new System.IO.FileInfo(@"deleted.csv")
};
var response = client.GetResponse(request);
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-F "urls_to_delete=@deleted.csv" \
https://api.productai.com/image_sets/_0000014/IMAGE_SET_ID

Request

ArgumentTypeDescriptionRequiredLimitation
fFilecsv file content, for csv file format please refer to csv file example. Note that only URL, which is the unique ID for an image, is required when deleting an imageYesshould be smaller than 50MB

Response

Same as Create Image Set Response

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aSuccess
4005001Invalid csv file, for example: contains more than 3 columns in one line, the first column is not a valid url
4031002Authentication failed
4042001Image set doesn’t exist

Update Multiple Data in Image Set

Please use the method introduced in Add Multiple Data to Image Set to update metadata and tags information in image data set. ProductAI image search service uses URL as unique ID for every image. When uploading data, ProductAI will not re-download or re-insert the image if its URL already exists in data set. Note that metadata and tags will be updated if they are provided in uploaded data.

Search Service

Create Search Service

With dataset, and by choosing a suitable scenario, you can create a search service. And then users can query this search service right after this service is created. But please note that at this initial stage only a few images can be fetched because the indexing process is just started. The whole indexing stage will finish after a certain time frame. The total time cost depends on image data size, scenario model complexity and infrastructure resources used on this service which is scheduled by ProductAI. Please contact our account manager if you need a priority indexing service.

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)

api = cli.get_image_set_api(IMAGE_SET_ID)

resp = api.create_service(name='NAME', scenario='fashion_5_7')

import json
service = json.loads(resp.content)
service_id = service['id']
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->createService($image_set_id=IMAGE_SET_ID, $name='NAME', $scenario='fashion_5_7');
$service_id = $result['id']
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.service.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
CreateSearchServiceRequest request = new CreateSearchServiceRequest(IMAGE_SET_ID, "NAME", "fashion_5_7");

CreateSearchServiceResponse response = client.getResponse(request);

String service_id = response.getServiceId();
//String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

var request = new CreateSearchServiceRequest(IMAGE_SET_ID, "NAME", "fashion_5_7");
var response = client.GetResponse(request);
var serviceId = response.ServiceId;
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"name": "NAME", "scenario": "fashion_5_7"}' \
https://api.productai.com/image_sets/_0000014/IMAGE_SET_ID/services

Request

ArgumentTypeDescriptionRequiredLimitation
nameStringService NameYes32 unicode characters, the extra characters are truncated
scenarioStringScenario TypeYesMust be one of the Supported Scenarios

Response

200 HTTP Status Code
{
"created_at": "2017-12-17T13:49:56Z",
"creator_id": ...,
"id": "790jvquc",
"image_set_id": "0mspcj1m",
"indexed_ratio": 0,
"last_indexed_time": null,
"last_updated_at": null,
"n_indexed": 0,
"name": "xxx",
"request_id": "298f4aea-e331-11e7-a97c-664c03c7cfbb",
"scenario": "fashion_v5_6",
"status": "running",
"status_duration": 0
}
FieldTypeDescription
created_atStringCreated UTC datetime, the format is: %Y-%m-%dT%H:%M:%SZ
creator_idIntegerCreator ID
idStringUnique ID of search service, all following operations are depending on this ID
image_set_idStringDataset ID which is used for current service
indexed_ratioFloatration = indexed image amount / downloaded image amount
last_indexed_timeStringlast index deployed time for this service
last_updated_atStringlast modified UTC time, to seconds, the format is: %Y-%m-%dT%H:%M:%SZ
n_indexedIntegercurrently indexed amount
nameStringsearch service name
request_idStringThe unique ID of this request, it can be used in product issue debugging with ProductAI support team
statusStringonly one status running right now
status_durationIntegerN/a
typeIntegerN/a
Non-200 HTTP Status Code
{
"error_code": 5003,
"message": "Scenarios Not Supported",
"request_id": "a0393714-e331-11e7-9a0f-b217471bc47d"
}
FieldTypeDescription
error_codeIntegerDetailed error code
messageStringDetailed error message
request_idStringThe unique ID of this request, it can be used in product issue debugging with ProductAI support team

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aSuccess
4005003Specified scenario does not exist
4033004Created service amount exceeded account limit, please refer to account limitations
4093002Only one scenario can be created upon one image set, server will return an error if user try to create another service upon the same image dataset

List Search Services

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_customer_service_api()
resp = api.get_services()
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->getServices();
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.service.GetAllServicesRequest;
import cn.productai.api.pai.entity.service.GetAllServicesResponse;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
GetAllServicesRequest request = new GetAllServicesRequest();

GetAllServicesResponse response = client.getResponse(request);

//String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version="1",
AccessKeyId=ACCESS_KEY_ID,
SecretKey=SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

var request = new GetAllServicesRequest();

var response = client.GetResponse(request);
curl -X GET \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
https://api.productai.com/customer_services/_0000172

Request

N/a

Response

200 HTTP Status Code
{
"request_id": "a06e3800-0f9c-11e8-8f9b-0242ac120103",
"results": [
{
"created_at": "2018-02-06T12:49:49Z",
"creator_id": ...,
"id": "...",
"image_set_id": "...",
"indexed_ratio": 1.0,
"last_indexed_time": "2018-02-08T07:01:49Z",
"last_updated_at": "2018-02-08T06:53:53Z",
"n_indexed": 319,
"name": "...",
"scenario": "furniture_v6",
"status": "running",
"status_duration": 0,
"type": 1
},
...
]
}
FieldTypeDescription
resultsArrayList all the customer’s running services, the field of single service is same as Create Search Service Response
request_idStringThe unique ID of this request, it can be used in product issue debugging with ProductAI support team

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aSuccess

Fetch Search Service

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_customer_service_api(SERVICE_ID)
resp = api.get_service()

import json
service = json.loads(resp.content)
service_id = service['id']
service_status = service['status']
use ProductAI;
$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->getService($service_id=SERVICE_ID);
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.service.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
GetServiceInfoRequest request = new GetServiceInfoRequest(SERVICE_ID);

GetServiceInfoResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

var request = new GetServiceInfoRequest
{
ServiceId = SERVICE_ID
};
var response = client.GetResponse(request);
curl -X GET \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
https://api.productai.com/customer_services/_0000172/SERVICE_ID

Request

N/a

Response

Same as Create Search Service Response

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aSuccess
4031003Authentication failed
4042002Service doesn’t exist

Modify Search Service

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_customer_service_api(SERVICE_ID)
api.update_service(name='NEW_NAME')
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->updateServiceName($service_id=SERVICE_ID, $name='NEW_NAME');
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.service.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
UpdateServiceRequest request = new UpdateServiceRequest(SERVICE_ID, "NEW_NAME");

UpdateServiceResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

var request = new UpdateServiceRequest
{
Name = "NEW_NAME",
ServiceId = SERVICE_ID
};
var response = client.GetResponse(request);
curl -X PUT \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"name": "NEW_NAME"}' \
https://api.productai.com/customer_services/_0000172/SERVICE_ID

Request

ArgumentTypeDescripitonRequiredLimitation
nameStringService nameYes32 characters, extra characters will be truncated

Response

Same as Create Search Service Response

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aSuccess
4031003Authentication failed
4042002Service doesn’t exist

Delete Search Service

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_customer_service_api(SERVICE_ID)
api.delete_service()
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);
$result = $product_ai->removeService($service_id=SERVICE_ID);
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.service.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");

IWebClient client = new DefaultProductAIClient(profile);
DeleteServiceRequest request = new DeleteServiceRequest(SERVICE_ID);

DeleteServiceResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

var request = new DeleteServiceRequest
{
ServiceId = SERVICE_ID
};
var response = client.GetResponse(request);
curl -X DELETE \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
https://api.productai.com/customer_services/_0000172/SERVICE_ID

Request

N/a

Response

N/a

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
204N/aSuccess
4031003Authentication failed
4042002Service doesn’t exist

Python

PHP

Java

C#

cURL

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_search_api(SERVICE_ID)

resp = api.query(image='http://yyyy', loc='0.1-0.1-0.8-0.7')

with open("fashion.jpg", mode='rb') as search:
resp = api.query(search)

# Indicate query result should contain MALE and SHOES tag
resp = api.query('http://yyyy', count=2, tags=['MALE', 'SHOES'])

# Or set the condition in following way, "|" equals to "and" operator
resp = api.query('http://yyyy', count=2, tags='MALE|SHOES')

# Or use a comprehansive search condition
resp = api.query('http://yyyy', count=2, tags={'and': ['MALE', 'SHOES', {'or': ['TMALL', 'TAOBAO']}]})
use ProductAI;

$product_ai = new ProductAI\API($access_key_id=ACCESS_KEY_ID, $secret_key=SECRET_KEY);


$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='http://yyyy', $loc=[0, 0.1, 0.4, 0.5])

$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='@zzzz.jpg')

// Indicate query result should contain MALE and SHOES tag
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='http://yyyy', $loc=[], $tags=['MALE', 'SHOES'], $count=2)

// Or set the condition in following way, "|" equals to "and" operator
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='@zzzz.jpg', $loc=[], $tags='MALE|SHOES')

// Or use a comprehansive search condition
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='@zzzz.jpg', $loc=[], $tags='{"and":["123",{"or":["456","789"]}]}')
import java.io.File;
import cn.productai.api.core.*;
import cn.productai.api.core.enums.*;
import cn.productai.api.pai.entity.search.*;

IProfile profile = new DefaultProfile();
profile.setAccessKeyId(ACCESS_KEY_ID);
profile.setSecretKey(SECRET_KEY);
profile.setVersion("1");
IWebClient client = new DefaultProductAIClient(profile);

// Indicate query result should contain MALE and SHOES tag
ISearchTag andTag = new AndTag();
andTag.Add("MALE");
andTag.Add("SHOES");

// Condition OR, with a TMALL tag
ISearchTag orTag = new OrTag();
orTag.Add("TMALL");
andTag.Add(orTag);

ITag searchTag = new SearchTag();
searchTag.setTag(andTag);

ImageSearchByImageUrlRequest request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.setUrl("http://yyyy");

ImageSearchByImageFileRequest request = new ImageSearchByImageFileRequest(SERVICE_ID);
request.setImageFile(new File("zzzz.jpg"));

request.setCount(2);
request.setSearchTag(searchTag);

ImageSearchResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
using MalongTech.ProductAI.Core;
using MalongTech.ProductAI.API.Entity;

IProfile profile = new DefaultProfile
{
Version = "1",
AccessKeyId = ACCESS_KEY_ID,
SecretKey = SECRET_KEY
};
var client = new DefaultProductAIClient(profile);

ISearchTag andTag = new AndTag();
andTag.Add(new List<string> { "MALE", "SHOES" });

ISearchTag orTag = new OrTag();
orTag.Add("TMALL");
andTag.Add(orTag);

ITag searchTag = new SearchTag
{
Tag = andTag
};

var request = new ImageSearchByImageUrlRequest(SERVICE_ID)
{
Url = "http://yyyy",
SearchTag = searchTag
};
request.Options.Add("count", "1");

var request = new ImageSearchByImageFileRequest("k7h9fail")
{
ImageFile = new System.IO.FileInfo(@"zzzz.jpg"),
SearchTag = searchTag
};

var response = client.GetResponse(request);
# Request service by URL
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"url":"http://yyyy","count":"2","tags":{"and":["123",{"or":["456","789"]}]}}' \
https://api.productai.com/search/SERVICE_ID

# Request service by local file
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-F "search=@zzzz.jpg" \
-F "count=2" \
-F 'tags={"and":["123",{"or":["456","789"]}]}' \
https://api.productai.com/search/SERVICE_ID

Request

ArgumentTypeDescriptionRequiredLimitation
searchFileImage content for queryYesShould fill this field or url
urlStringImage url for queryYesShould fill this field or search
countIntegerSpecify result countNo20 by default, the value range is [1-3000], but should no more than 3000
tagsStringData tagsNoTags can be used as filtering condition of search result. These tags are specified by user when uploading/updating data, they are not generated automatically. A simple way to leverage these tags: when use multiple tags, please delimit with “|”. Service will return result which contains all the tags specified in the condition. For example, coat|tshirt|POLO. Please use utf-8 encoding for non-ascii characters. For complex condition: 1), {“or”, [one or more sub-conditions]}, {“and”: [one or more sub-conditions]}. For example: tags={“and”:[“coat”,{“or”:[“blue”,”leisure”]}]}. Please refer to usage of tags.
locStringSearch area within a imageNoBounding box info, format is “x-y-w-h”. x,y,w,h means: mark top left corner of image as (0,0), right bottom corner as (1,1), x is bounding-box-left-position/image-width , y is bounding-box-top-position/image-height, w is bounding-box-width/image-width, h is bounding-box-height/image-height, for details please refer to loc usage.

Response

200 HTTP Status Code
{
"detect_time": "0.000",
"detection_score": null,
"download_time": "0.004",
"ds": "70awubt0",
"is_err": 0,
"loc": [
0,
0,
1080,
1920
],
"most_common_tags": [],
"preprocess_time": "0.005",
"request_id": "d2605570-e33a-11e7-9a73-92019f9dce87",
"results": [
...
],
"searchtime": "0.307",
"time": "0.324",
"type": [
"Jumpsuit-romper",
"beidaiku",
"leisure-pants",
"flat-sandals",
"bodycon-dress",
"Culotte-pants"
],
"ver": "20171113-135702"
}

results field is an arrary, it contains all the search results, for details please refer to Results details

Fields relate to time

FieldTypeDescription
detect_timeStringTime cost of detection, seconds
download_timeStringTime cost of image downloading, seconds
preprocess_timeStringTime cost of preprocessing, seconds
searchtimeStringTime cost of search, seconds
timeStringTotal time cost on server side, seconds

Fields relate to detector

FieldTypeDescription
detect_timeStringTime cost of detection, seconds
detection_scoreFloatConfidence score returned by detection service
locArrayReturned from detection service, object detected with highest score, values are x, y, w, h
typeArrayReturned from detection service, category of detected object

Other fields

FieldTypeDescription
dsStringdeprecated, please do not use
is_errIntegerdeprecated, please do not use
most_common_tagsArrayFor details please refer to ret_img_tags
request_idStringUnique ID of this API call, can be used in issue debugging with ProductAI support team
verStringindex version number

Results details

{
"metadata": "131",
"score": 0.5732779921465632,
"url": "http://xxx/131/ab505d2fd40e17f64397c796adfb6a8b.jpg",
"tags": [
"FEMALE",
"FOREVER21",
"ONE-PIECE"
]
}
FieldTypeDescription
urlStringUrl of result image
scoreFloatSimilarity score with query image
metadataStringMetadata of result image, please refer to metadata
tagsArrayTags of result image, please refer to ret_img_tags
Non-200 HTTP Status Code
{
"error_code": 1004,
"message": "Image Downloading Not Found",
"request_id": "eccff8dc-b86c-11e7-ab03-b66791ba711f"
}
FieldTypeDescription
error_codeIntegerThe detail error type
messageStringThe detail error message
request_idStringThe unique ID of this request, it can be used in product issue debugging with ProductAI support team

Error Code

SDK/API notifies the client about whether the request success or fails via HTTP status code

HTTP Status Codeerror_codeDescription
200N/aSuccess
4001001Query isn’t provided in request
4001002Query is too small to process, please refer to faq-error
4001003Query image type isn’t supported, please refer to faq-data
4001004Query url doesn’t exist (URL return 404)
4001005Timeout, when download query from URL
4001006Failed to download the query
4001007Query url is invalid
4001008Query loc parameter format is invalid
4001014Failed to detect query
429N/aExceeds concurrency limits, please refer to concurrency limits
5002001Detection failure

Advanced

Metadata

Any image in the imageset can have a metadata. Metadata can be any string without comma. This metadata will be returned to user along with image in the search result. Note that metadata is of maximum 512 unicode characters, will raise an error if length exceeds this limit.

  1. Image with product ID: set metadata as ID, query image to get ID, and then fetch detailed product information by this ID in your own database
  2. Image with product link: set metadata to contain url info, query image to get url and then navigate to this link
  3. Image with product details: set metadata to contain detailed product info (for example, a json object), query image to get detailed info to avoid time cost for fetching product details

tags

Any image can contain a set of tags, multiple tags should be delimited with |, a tag must not contain comma. Search service will index tag along with image, user can use tags as search condition along with query image. We call this search as tag filter. Tag filter make the searching more accurate and more faster

  1. Since service search the only main object detected in query image, it is strongly recommended to use tags when query image including only one object. Or with loc parameter to specify the object wanting to search.
  2. Image category in tags: so that user can limit the result category.
  3. Image related user ID in tags: so that user can limit the search only across some certain users, in order to implement scenarios such as personal photo albumns.

Tag Syntax

Currently support 3 types:

  • Pass tags as array with SDK

Python

PHP

Java

C#

cURL

api.query("http://yyyy", tags=['MALE', 'SHOES'])
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='http://yyyy', $loc=[], $tags=['MALE', 'SHOES'])
ISearchTag andTag = new AndTag();
andTag.Add("MALE");
andTag.Add("SHOES");

ITag searchTag = new SearchTag();
searchTag.setTag(andTag);

ImageSearchByImageUrlRequest request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.setUrl("http://yyyy");
request.setSearchTag(searchTag);
ISearchTag andTag = new AndTag();
andTag.Add(new List<string> { "MALE", "SHOES" });

ITag searchTag = new SearchTag
{
Tag = andTag
};

var request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.Url = 'http://yyyy';
request.SearchTag = searchTag;
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"url":"http://yyyy","tags":{"and":["MALE","SHOES"]}}' \
https://api.productai.com/search/SERVICE_ID
  • Join a set of tags with delimiter “|”

Python

PHP

Java

C#

cURL

api.query(image_url, tags='MALE|SHOES')
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='http://yyyy', $loc=[], $tags='MALE|SHOES')
ImageSearchByImageUrlRequest request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.setUrl("http://yyyy");
request.tags="MALE|SHOES";
// Not supported at this moment
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"url":"http://yyyy","tags":"MALE|SHOES"}' \
https://api.productai.com/search/SERVICE_ID
  • Supoort expression tree consists with and and or

Python

PHP

Java

C#

cURL

api.query(image_url, tags={'and': ['MALE', 'SHOES', {'or': ['TMALL', 'TAOBAO']}]})
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='http://yyyy', $loc=[], $tags='{"and":["MALE", "SHOES",{"or":["TMALL","TAOBAO"]}]}')
ISearchTag orTag = new OrTag();
orTag.Add("TMALL");
orTag.Add("TAOBAO");

ISearchTag andTag = new AndTag();
andTag.Add("MALE");
andTag.Add("SHOES");
andTag.Add(orTag);

ITag searchTag = new SearchTag();
searchTag.setTag(andTag);

ImageSearchByImageUrlRequest request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.setUrl('http://yyyy');
request.setSearchTag(searchTag);
ISearchTag orTag = new OrTag();
orTag.Add("TMALL");
orTag.Add("TAOBAO");

ISearchTag andTag = new AndTag();
andTag.Add(new List<string> { "MALE", "SHOES" });
andTag.Add(orTag);

ITag searchTag = new SearchTag
{
Tag = andTag
};

var request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.Url = "http://yyyy";
request.SearchTag = searchTag;
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"url":"http://yyyy","tags":{"and":["MALE","SHOES",{"or":["TMALL","TAOBAO"]}]}}' \
https://api.productai.com/search/SERVICE_ID

loc Usage

Python

PHP

Java

C#

cURL

resp = api.query("http://yyyy", loc = '0.1-0.1-0.8-0.7')
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $image='http://yyyy', $loc = [0.1,0.1,0.8,0.7])
ImageSearchByImageUrlRequest request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.setUrl('http://yyyy');
request.setLoc('0.1-0.1-0.8-0.7');
var request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.Url = "http://yyyy";
request.Loc = '0.1-0.1-0.8-0.7';
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"url":"http://yyyy","loc":"0.1-0.1-0.8-0.7"}' \
https://api.productai.com/search/SERVICE_ID

Bounding box info, format is “x-y-w-h”. x,y,w,h means:

  • mark top left corner of image as (0,0)
  • right bottom corner as (1,1)
  • x is bounding-box-left-position/image-width
  • y is bounding-box-top-position/image-height
  • w is bounding-box-width/image-width
  • h is bounding-box-height/image-height

Two common usage of loc:

  1. Limit the search area to be the bounding box, to reduce background inference
  2. Use loc to specify which object in the image should be searched
QuerySearch RegionSearch Result
example1red coatexample2
example3black bagexample4

Paging

Search supports paging feature, which returns up to 3000 results.

Note: when more than 3,000 results are requested, the service returns an empty response.

Python

PHP

Java

C#

# request top 10 results
api.query('http://yyyy', count=10)

# request the first page with 5 results per one page
api.query('http://yyyy', page=0, count=5)

# request the second page with 5 results per one page
api.query('http://yyyy', page=1, count=5)
# request top 10 results
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $url='http://yyyy', $loc=[], $tags=[], $count=10)

// request the 1st page with 5 results per page
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $url='http://yyyy', $loc=[], $tags=[], $count=5, $page=0)

// request the 2nd page with 5 results per page
$result = $product_ai->searchImage($service_type='search', $service_id=SERVICE_ID, $url='http://yyyy', $loc=[], $tags=[], $count=5, $page=1)
// by default, we have 10 results
ImageSearchByImageUrlRequest request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.setUrl("http://yyyy");

// request top 5 results
request.setCount(5)

// request the 1st page with 5 results per page
request.getOptions().put("page", "0");

// request the 2nd page with 5 results per page
request.getOptions().put("page", "1");

ImageSearchResponse response = client.getResponse(request);
String json = response.getResponseJsonString();
// by default, we have 10 results
var request = new ImageSearchByImageUrlRequest(SERVICE_ID)
{
Url = "http://yyyy",
};

// request top 5 results
request.Options.Add("count", "5");

// request the 1st page with 5 results per page
request.Options.Add("page", "0");

// request the 2nd page with 5 results per page
request.Options.Add("page", "1");

var response = client.GetResponse(request);

ret_img_tags

When parameter ret_img_tags is set to 1, service will return tags (which is submitted with image in csv file) along with image, and the tag with most occurrence will be stored in most_common_tags result field as well.

Python

PHP

Java

C#

cURL

api.query('http://yyyy', ret_img_tags=1)
$result = $product_ai->generalRequest($service_type='search', $service_id=SERVICE_ID, $image='http://yyyy', $args=['ret_img_tags' => 1], $json=false);
ImageSearchByImageUrlRequest request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.setUrl('http://yyyy');
request.getOptions().put('ret_img_tags', '1');
var request = new ImageSearchByImageUrlRequest(SERVICE_ID);
request.Url = "http://yyyy";
request.Options.Add('ret_img_tags', '1');
curl -X POST \
-H 'x-ca-version: 1.0' \
-H 'x-ca-accesskeyid: ACCESS_KEY_ID' \
-H 'Content-Type: application/json' \
-d '{"url":"http://yyyy","ret_img_tags":"1"}' \
https://api.productai.com/search/SERVICE_ID

In the response:

  • Each item in results contains a corresponding tags field
  • most_common_tags indicates a collection of tags, which have the most occurrences and their occurrence count

Recommended usage:

  • Can be used to infer possible objects in the image. As in following example, ONE-PIECE presents 19 times, FEMALE presents 18 times, so that it is highly possible that query image contains FEMALE and ONE-PIECE
{
"detect_time": "1.093",
"detection_score": 0.9705721139907837,
"download_time": "0.000",
"ds": "u70rgsx2",
"is_err": 0,
"loc": [
438,
301,
1015,
1691
],
"most_common_tags": [
[
"ONE-PIECE",
19
],
[
"FEMALE",
18
],
...
],
"preprocess_time": "0.005",
"request_id": "754e5fd8-e3a5-11e7-a97c-664c03c7cfbb",
"results": [
{
"metadata": "",
"score": 0.7404570709058489,
"tags": [
"FEMALE",
"FOREVER21",
"ONE-PIECE",
"JUMPSUIT-ROMPER",
"TOP",
"TANK-STRAP-TOPS",
"FLAT-SANDALS",
"SHOES"
],
"url": "https://oss-downloader.productai.cn/mQxMzhiMzJiYjU1M2RlYThmMmYuanBn.jpg"
},
...
],
"searchtime": "0.323",
"time": "1.429",
"type": [
"Jumpsuit-romper",
"beidaiku",
"leisure-pants",
"flat-sandals",
"bodycon-dress",
"Culotte-pants"
],
"ver": "20170730-184346"
}

Common features on E-commerce product images:

  • multiple images for one product
  • each image presents a certain aspect or a certain detail, or model in different color
  • images are PGC (Professional generated content, well shooted product picture with clean background, or street photo by professional photographers)

Some common scenarios:

  • to determine if a product exists in database
  • search for same model
  • deduplicate
  • product relations

Solution for improve precision:

  • Create Search Service, set scenario=”ecom_product_2_1” (In Console, choose scenario “E-commerce product image search v2.1”)
  • Upload multiple images for a certain product (with different aspects, details, or color)
  • Set image metadata to be product ID
  • Call service with code similar to following

Python

from productai import Client

cli = Client(ACCESS_KEY_ID, SECRET_KEY)
api = cli.get_image_search_api(SERVICE_ID)

resp = api.query('http://yyyy', count=6)

import json
obj = json.loads(resp1.content)

statistics_counter = {}
for x in obj.get('results'):
pid = x.get('metadata')
statistics_counter.setdefault(pid, [x.get('url'), 0, 0])
# calculate product occurrence in result
statistics_counter[pid][1] += 1
# calculate total score for each product in the result
statistics_counter[pid][2] += x.get('score')

# only keep product which occurs more than 1 time
statistics_counter = [x for x in statistics_counter.items() if x[1][1] > 1]

# order products with average score in descending
results = sorted(statistics_counter, key = lambda x: x[1][2] / x[1][1], reverse = True)

# we can only fetch top 1 result for most precise result
results = results[:1]