Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the Product Search tests and the src file updates #1196

Merged
2 changes: 1 addition & 1 deletion vision/product-search/cloud-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<parent>
<groupId>com.google.cloud.samples</groupId>
<artifactId>shared-configuration</artifactId>
<version>1.0.9</version>
<version>1.0.10</version>
</parent>

<properties>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,7 @@
import com.google.cloud.vision.v1p3beta1.Image;
import com.google.cloud.vision.v1p3beta1.ImageAnnotatorClient;
import com.google.cloud.vision.v1p3beta1.ImageContext;
import com.google.cloud.vision.v1p3beta1.ImageSource;
import com.google.cloud.vision.v1p3beta1.ProductSearchParams;
import com.google.cloud.vision.v1p3beta1.ProductSearchResults.Result;
import com.google.cloud.vision.v1p3beta1.ProductSetName;
Expand Down Expand Up @@ -54,7 +55,7 @@ public class ProductSearch {

// [START vision_product_search_get_similar_products]
/**
* Search similar products to image.
* Search similar products to image in local file.
*
* @param projectId - Id of the project.
* @param computeRegion - Region name.
Expand All @@ -66,7 +67,7 @@ public class ProductSearch {
* color:red AND style:kids color:blue AND style:kids
* @throws IOException - on I/O errors.
*/
public static void getSimilarProducts(
public static void getSimilarProductsFile(
String projectId,
String computeRegion,
String productSetId,
Expand All @@ -85,11 +86,8 @@ public static void getSimilarProducts(

// Create annotate image request along with product search feature.
Feature featuresElement = Feature.newBuilder().setType(Type.PRODUCT_SEARCH).build();
// The input image can be a GCS link or HTTPS link or Raw image bytes.
// The input image can be a HTTPS link or Raw image bytes.
// Example:
// To use GCS link replace with below code
// ImageSource source = ImageSource.newBuilder().setGcsImageUri(gcsUri).build();
// Image image = Image.newBuilder().setSource(source).build();
// To use HTTP link replace with below code
// ImageSource source = ImageSource.newBuilder().setImageUri(imageUri).build();
// Image image = Image.newBuilder().setSource(source).build();
Expand Down Expand Up @@ -130,6 +128,73 @@ public static void getSimilarProducts(
}
// [END vision_product_search_get_similar_products]

// [START vision_product_search_get_similar_products_gcs]
/**
* Search similar products to image in Google Cloud Storage.
*
* @param projectId - Id of the project.
* @param computeRegion - Region name.
* @param productSetId - Id of the product set.
* @param productCategory - Category of the product.
* @param gcsUri - GCS file path of the image to be searched
* @param filter - Condition to be applied on the labels. Example for filter: (color = red OR
* color = blue) AND style = kids It will search on all products with the following labels:
* color:red AND style:kids color:blue AND style:kids
* @throws Exception - on errors.
*/
public static void getSimilarProductsGcs(String projectId,
String computeRegion,
String productSetId,
String productCategory,
String gcsUri,
String filter) throws Exception {
ImageAnnotatorClient queryImageClient = ImageAnnotatorClient.create();

// Get the full path of the product set.
String productSetPath = ProductSetName.of(projectId, computeRegion, productSetId).toString();

// Get the image from Google Cloud Storage
ImageSource source = ImageSource.newBuilder().setGcsImageUri(gcsUri).build();

// Create annotate image request along with product search feature.
Feature featuresElement = Feature.newBuilder().setType(Type.PRODUCT_SEARCH).build();
Image image = Image.newBuilder().setSource(source).build();
ImageContext imageContext =
ImageContext.newBuilder()
.setProductSearchParams(
ProductSearchParams.newBuilder()
.setProductSet(productSetPath)
.addProductCategories(productCategory)
.setFilter(filter))
.build();

AnnotateImageRequest annotateImageRequest =
AnnotateImageRequest.newBuilder()
.addFeatures(featuresElement)
.setImage(image)
.setImageContext(imageContext)
.build();
List<AnnotateImageRequest> requests = Arrays.asList(annotateImageRequest);

// Search products similar to the image.
BatchAnnotateImagesResponse response = queryImageClient.batchAnnotateImages(requests);

List<Result> similarProducts =
response.getResponses(0).getProductSearchResults().getResultsList();

System.out.println("Similar Products: ");
for (Result product : similarProducts) {
System.out.println(String.format("\nProduct name: %s", product.getProduct().getName()));
System.out.println(
String.format("Product display name: %s", product.getProduct().getDisplayName()));
System.out.println(
String.format("Product description: %s", product.getProduct().getDescription()));
System.out.println(String.format("Score(Confidence): %s", product.getScore()));
System.out.println(String.format("Image name: %s", product.getImage()));
}
}
// [END vision_product_search_get_similar_products_gcs]

public static void main(String[] args) throws Exception {
ProductSearch productSearch = new ProductSearch();
productSearch.argsHelper(args, System.out);
Expand All @@ -139,26 +204,40 @@ public static void argsHelper(String[] args, PrintStream out) throws Exception {
ArgumentParser parser = ArgumentParsers.newFor("Product Search").build();
Subparsers subparsers = parser.addSubparsers().dest("command");

Subparser getSimilarProductsParser = subparsers.addParser("get_similar_products");
getSimilarProductsParser.addArgument("productSetId");
getSimilarProductsParser.addArgument("productCategory");
getSimilarProductsParser.addArgument("filePath");
getSimilarProductsParser.addArgument("filter").nargs("?").setDefault("");
Subparser getSimilarProductsFileParser = subparsers.addParser("get_similar_products_file");
getSimilarProductsFileParser.addArgument("productSetId");
getSimilarProductsFileParser.addArgument("productCategory");
getSimilarProductsFileParser.addArgument("filePath");
getSimilarProductsFileParser.addArgument("filter").nargs("?").setDefault("");

Subparser getSimilarProductsGcsParser = subparsers.addParser("get_similar_products_gcs");
getSimilarProductsGcsParser.addArgument("productSetId");
getSimilarProductsGcsParser.addArgument("productCategory");
getSimilarProductsGcsParser.addArgument("gcsUri");
getSimilarProductsGcsParser.addArgument("filter").nargs("?").setDefault("");

String projectId = System.getenv("PROJECT_ID");
String computeRegion = System.getenv("REGION_NAME");

Namespace ns = null;
try {
ns = parser.parseArgs(args);
if (ns.get("command").equals("get_similar_products")) {
getSimilarProducts(
if (ns.get("command").equals("get_similar_products_file")) {
getSimilarProductsFile(
projectId,
computeRegion,
ns.getString("productSetId"),
ns.getString("productCategory"),
ns.getString("filePath"),
ns.getString("filter"));
} else if (ns.get("command").equals("get_similar_products_gcs")) {
getSimilarProductsGcs(
projectId,
computeRegion,
ns.getString("productSetId"),
ns.getString("productCategory"),
ns.getString("gcsUri"),
ns.getString("filter"));
}

} catch (ArgumentParserException e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.vision;

import static com.google.common.truth.Truth.assertThat;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Integration (system) tests for {@link ProductSearch}. */
@RunWith(JUnit4.class)
@SuppressWarnings("checkstyle:abbreviationaswordinname")
public class ProductSearchIT {
private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT");
private static final String COMPUTE_REGION = "us-west1";
private static final String GCS_URI =
"gs://java-docs-samples-testing/product-search/indexed_product_sets.csv";
private static final String PRODUCT_SET_ID = "indexed_product_set_id_for_testing";
private static final String PRODUCT_CATEGORY = "apparel";
private static final String PRODUCT_ID_1 = "indexed_product_id_for_testing_1";
private static final String PRODUCT_ID_2 = "indexed_product_id_for_testing_2";
private static final String IMAGE_URI_1 =
"gs://java-docs-samples-testing/product-search/shoes_1.jpg";
private static final String FILE_PATH_1 = "./resources/shoes_1.jpg";
private static final String FILTER = "style=womens";
private static final String BUCKET = "java-docs-samples-testing";
private ByteArrayOutputStream bout;
private PrintStream out;

@Before
public void setUp() throws Exception {

bout = new ByteArrayOutputStream();
out = new PrintStream(bout);
System.setOut(out);
ImportProductSets.importProductSets(PROJECT_ID, COMPUTE_REGION, GCS_URI);
bout.reset();
}

@After
public void tearDown() throws Exception {
ProductManagement.deleteProduct(PROJECT_ID,COMPUTE_REGION,PRODUCT_ID_1);
ProductManagement.deleteProduct(PROJECT_ID,COMPUTE_REGION,PRODUCT_ID_2);
ProductSetManagement.deleteProductSet(PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID);
System.setOut(null);
}

@Test
public void testGetSimilarProductsFile() throws Exception {
// Act
ProductSearch.getSimilarProductsFile(
PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID, PRODUCT_CATEGORY, FILE_PATH_1, "");

// Assert
String got = bout.toString();
assertThat(got).contains(PRODUCT_ID_1);
assertThat(got).contains(PRODUCT_ID_2);
}

@Test
public void testGetSimilarProductsGcs() throws Exception {
// Act
ProductSearch.getSimilarProductsGcs(
PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID, PRODUCT_CATEGORY, IMAGE_URI_1, "");

// Assert
String got = bout.toString();
assertThat(got).contains(PRODUCT_ID_1);
assertThat(got).contains(PRODUCT_ID_2);
}

@Test
public void testGetSimilarProductsFileWithFilter() throws Exception {
// Act
ProductSearch.getSimilarProductsFile(
PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID, PRODUCT_CATEGORY, FILE_PATH_1, FILTER);

// Assert
String got = bout.toString();
assertThat(got).contains(PRODUCT_ID_1);
assertThat(got).doesNotContain(PRODUCT_ID_2);
}

@Test
public void testGetSimilarProductsGcsWithFilter() throws Exception {
// Act
ProductSearch.getSimilarProductsGcs(
PROJECT_ID, COMPUTE_REGION, PRODUCT_SET_ID, PRODUCT_CATEGORY, IMAGE_URI_1, FILTER);

// Assert
String got = bout.toString();
assertThat(got).contains(PRODUCT_ID_1);
assertThat(got).doesNotContain(PRODUCT_ID_2);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018 Google Inc.
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down