Skip to content

Commit

Permalink
samples: Added the Product Search tests and the src file updates (#1196)
Browse files Browse the repository at this point in the history
* Adding the Product Search tests.

* Fixing review issues.

* Product Search tests and src file updates to include GCS image file.

* Fixing issues after review.

* Inc. to LLC
  • Loading branch information
nirupa-kumar authored and chingor13 committed Aug 13, 2020
1 parent 3ff8d26 commit f1f8c14
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 22 deletions.
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
107 changes: 93 additions & 14 deletions vision/snippets/src/main/java/com/example/vision/ProductSearch.java
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
116 changes: 116 additions & 0 deletions vision/snippets/src/test/java/com/example/vision/ProductSearchIT.java
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

0 comments on commit f1f8c14

Please sign in to comment.