From 7461899260b9ad74e1be2fe7786d1726b6757081 Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Thu, 19 Jul 2018 07:16:57 -0700 Subject: [PATCH 01/10] Test push --- .../vision/samples/automl/DatasetApi.java | 347 ++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 vision/automl/src/main/java/com/google/cloud/vision/samples/automl/DatasetApi.java diff --git a/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/DatasetApi.java b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/DatasetApi.java new file mode 100644 index 00000000000..c75d8b15e31 --- /dev/null +++ b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/DatasetApi.java @@ -0,0 +1,347 @@ +/* + * 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.google.cloud.vision.samples.automl; + +// Imports the Google Cloud client library +import com.google.cloud.automl.v1beta1.AutoMlClient; +import com.google.cloud.automl.v1beta1.ClassificationProto.ClassificationType; +import com.google.cloud.automl.v1beta1.Dataset; +import com.google.cloud.automl.v1beta1.DatasetName; +import com.google.cloud.automl.v1beta1.GcsDestination; +import com.google.cloud.automl.v1beta1.GcsSource; +import com.google.cloud.automl.v1beta1.ImageClassificationDatasetMetadata; +import com.google.cloud.automl.v1beta1.InputConfig; +import com.google.cloud.automl.v1beta1.ListDatasetsRequest; +import com.google.cloud.automl.v1beta1.LocationName; + +import com.google.cloud.automl.v1beta1.OutputConfig; +import com.google.protobuf.Empty; +import java.io.IOException; +import java.io.PrintStream; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import net.sourceforge.argparse4j.inf.Subparsers; + +/** + * Google Cloud AutoML Vision API sample application. Example usage: mvn package exec:java + * -Dexec.mainClass ='com.google.cloud.vision.samples.automl.DatasetAPI' -Dexec.args='create_dataset + * test_dataset' + */ +public class DatasetApi { + + // [START automl_vision_create_dataset] + + /** + * Demonstrates using the AutoML client to create a dataset + * + * @param projectId the Google Cloud Project ID. + * @param computeRegion the Region name. (e.g., "us-central1") + * @param datasetName the name of the dataset to be created. + * @param multiLabel the type of classification problem. Set to FALSE by default. + * @throws IOException on Input/Output errors. + */ + public static void createDataset( + String projectId, String computeRegion, String datasetName, Boolean multiLabel) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Resource representing the Google Cloud Platform location + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Classification type assigned based on multiLabel value. + ClassificationType classificationType = + multiLabel ? ClassificationType.MULTILABEL : ClassificationType.MULTICLASS; + + // Specify the image classification type for the dataset. + ImageClassificationDatasetMetadata imageClassificationDatasetMetadata = + ImageClassificationDatasetMetadata.newBuilder() + .setClassificationType(classificationType) + .build(); + + // Create a dataset with dataset name and set the dataset metadata. + Dataset myDataset = + Dataset.newBuilder() + .setDisplayName(datasetName) + .setImageClassificationDatasetMetadata(imageClassificationDatasetMetadata) + .build(); + + // Create dataset with the dataset metadata in the region. + Dataset dataset = client.createDataset(projectLocation, myDataset); + + // Display the dataset information + System.out.println(String.format("Dataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Image classification dataset specification:"); + System.out.print(String.format("\t%s", dataset.getImageClassificationDatasetMetadata())); + System.out.println(String.format("Dataset example count: %d", dataset.getExampleCount())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + // [END automl_vision_create_dataset] + + // [START automl_vision_listdatasets] + /** + * Demonstrates using the AutoML client to list all datasets. + * + * @param projectId - Id of the project. + * @param computeRegion - Region name. + * @param filter - Filter expression. + * @throws IOException on Input/Output errors. + */ + public static void listDatasets(String projectId, String computeRegion, String filter) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Build the List datasets request + ListDatasetsRequest request = + ListDatasetsRequest.newBuilder() + .setParent(projectLocation.toString()) + .setFilter(filter) + .build(); + + // List all the datasets available in the region by applying the filter. + System.out.println("List of datasets:"); + for (Dataset dataset : client.listDatasets(request).iterateAll()) { + // Display the dataset information + System.out.println(String.format("\nDataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Image classification dataset specification:"); + System.out.print(String.format("\t%s", dataset.getImageClassificationDatasetMetadata())); + System.out.println(String.format("Dataset example count: %d", dataset.getExampleCount())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + } + // [END automl_vision_listdatasets] + + // [START automl_vision_getdataset] + /** + * Demonstrates using the AutoML client to get a dataset by ID. + * + * @param projectId - Id of the project. + * @param computeRegion - Region name. + * @param datasetId - Id of the dataset. + * @throws IOException on Input/Output errors. + */ + public static void getDataset(String projectId, String computeRegion, String datasetId) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + // Get all the information about a given dataset. + Dataset dataset = client.getDataset(datasetFullId); + + // Display the dataset information. + System.out.println(String.format("Dataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Image classification dataset specification:"); + System.out.print(String.format("\t%s", dataset.getImageClassificationDatasetMetadata())); + System.out.println(String.format("Dataset example count: %d", dataset.getExampleCount())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + // [END automl_vision_getdataset] + + // [START automl_vision_importdata] + /** + * Demonstrates using the AutoML client to import labeled images. + * + * @param projectId - Id of the project. + * @param computeRegion - Region name. + * @param datasetId - Id of the dataset to which the training data will be imported. + * @param path - Google Cloud Storage URIs. Target files must be in AutoML vision CSV format. + * @throws Exception on AutoML Client errors + */ + public static void importData( + String projectId, String computeRegion, String datasetId, String path) throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + GcsSource.Builder gcsSource = GcsSource.newBuilder(); + + // Get multiple training data files to be imported + String[] inputUris = path.split(","); + for (String inputUri : inputUris) { + gcsSource.addInputUris(inputUri); + } + + // Import data + InputConfig inputConfig = InputConfig.newBuilder().setGcsSource(gcsSource).build(); + System.out.println("Processing import..."); + Empty response = client.importDataAsync(datasetFullId.toString(), inputConfig).get(); + System.out.println(String.format("Dataset imported. %s", response)); + } + // [END automl_vision_importdata] + + // [START automl_vision_exportdata] + /** + * Demonstrates using the AutoML client to export a dataset to a Google Cloud Storage bucket. + * + * @param projectId - Id of the project. + * @param computeRegion - Region name. + * @param datasetId - Id of the dataset. + * @param gcsUri - Destination URI (Google Cloud Storage) + * @throws Exception on AutoML Client errors + */ + public static void exportData( + String projectId, String computeRegion, String datasetId, String gcsUri) throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + // Set the output URI + GcsDestination gcsDestination = GcsDestination.newBuilder().setOutputUriPrefix(gcsUri).build(); + + // Export the dataset to the output URI. + OutputConfig outputConfig = OutputConfig.newBuilder().setGcsDestination(gcsDestination).build(); + System.out.println("Processing export..."); + + Empty response = client.exportDataAsync(datasetFullId, outputConfig).get(); + System.out.println(String.format("Dataset exported. %s", response)); + } + // [END automl_vision_exportdata] + + // [START automl_vision_deletedataset] + /** + * Delete a dataset. + * + * @param projectId - Id of the project. + * @param computeRegion - Region name. + * @param datasetId - Id of the dataset. + * @throws Exception on AutoML Client errors + */ + public static void deleteDataset(String projectId, String computeRegion, String datasetId) + throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + // Delete a dataset. + Empty response = client.deleteDatasetAsync(datasetFullId).get(); + + System.out.println(String.format("Dataset deleted. %s", response)); + } + // [END automl_vision_deleteDataset] + + public static void main(String[] args) throws Exception { + DatasetApi datasetApi = new DatasetApi(); + datasetApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) throws Exception { + ArgumentParser parser = + ArgumentParsers.newFor("DatasetAPI") + .build() + .defaultHelp(true) + .description("Dataset API operations."); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser createDatasetParser = subparsers.addParser("create_dataset"); + createDatasetParser.addArgument("datasetName"); + createDatasetParser + .addArgument("multiLabel") + .nargs("?") + .type(Boolean.class) + .choices(Boolean.FALSE, Boolean.TRUE) + .setDefault(Boolean.FALSE); + + Subparser listDatasetsParser = subparsers.addParser("list_datasets"); + listDatasetsParser + .addArgument("filter") + .nargs("?") + .setDefault("imageClassificationDatasetMetadata:*"); + + Subparser getDatasetParser = subparsers.addParser("get_dataset"); + getDatasetParser.addArgument("datasetId"); + + Subparser importDataParser = subparsers.addParser("import_data"); + importDataParser.addArgument("datasetId"); + importDataParser.addArgument("path"); + + Subparser exportDataParser = subparsers.addParser("export_data"); + exportDataParser.addArgument("datasetId"); + exportDataParser.addArgument("gcsUri"); + + Subparser deleteDatasetParser = subparsers.addParser("delete_dataset"); + deleteDatasetParser.addArgument("datasetId"); + + 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("create_dataset")) { + createDataset( + projectId, computeRegion, ns.getString("datasetName"), ns.getBoolean("multiLabel")); + } + if (ns.get("command").equals("list_datasets")) { + listDatasets(projectId, computeRegion, ns.getString("filter")); + } + if (ns.get("command").equals("get_dataset")) { + getDataset(projectId, computeRegion, ns.getString("datasetId")); + } + if (ns.get("command").equals("import_data")) { + importData(projectId, computeRegion, ns.getString("datasetId"), ns.getString("path")); + } + if (ns.get("command").equals("export_data")) { + exportData(projectId, computeRegion, ns.getString("datasetId"), ns.getString("gcsUri")); + } + if (ns.get("command").equals("delete_dataset")) { + deleteDataset(projectId, computeRegion, ns.getString("datasetId")); + } + + } catch (ArgumentParserException e) { + parser.handleError(e); + } + } +} From f4531a9f5daee44cb053e5e88b970044da1d0aa7 Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Sat, 21 Jul 2018 16:49:35 -0700 Subject: [PATCH 02/10] Vision AutoML --- vision/automl/README.md | 87 ++++ vision/automl/pom.xml | 154 ++++++ vision/automl/resources/dandelion.jpg | Bin 0 -> 53485 bytes .../vision/samples/automl/DatasetApi.java | 80 +-- .../cloud/vision/samples/automl/ModelApi.java | 460 ++++++++++++++++++ .../vision/samples/automl/PredictionApi.java | 142 ++++++ .../vision/samples/automl/DatasetApiIT.java | 107 ++++ .../vision/samples/automl/ModelApiIT.java | 88 ++++ .../samples/automl/PredictionApiIT.java | 64 +++ 9 files changed, 1142 insertions(+), 40 deletions(-) create mode 100644 vision/automl/README.md create mode 100644 vision/automl/pom.xml create mode 100644 vision/automl/resources/dandelion.jpg create mode 100644 vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java create mode 100644 vision/automl/src/main/java/com/google/cloud/vision/samples/automl/PredictionApi.java create mode 100644 vision/automl/src/test/java/com/google/cloud/vision/samples/automl/DatasetApiIT.java create mode 100644 vision/automl/src/test/java/com/google/cloud/vision/samples/automl/ModelApiIT.java create mode 100644 vision/automl/src/test/java/com/google/cloud/vision/samples/automl/PredictionApiIT.java diff --git a/vision/automl/README.md b/vision/automl/README.md new file mode 100644 index 00000000000..24a73c48ece --- /dev/null +++ b/vision/automl/README.md @@ -0,0 +1,87 @@ +# AutoML Sample + + +Open in Cloud Shell + +[Google Cloud Vision API][vision] provides feature detection for images. +This API is part of the larger collection of Cloud Machine Learning APIs. + +This sample Java application demonstrates how to access the Cloud Vision API +using the [Google Cloud Client Library for Java][google-cloud-java]. + +[vision]: https://cloud.google.com/vision/docs/ +[google-cloud-java]: https://github.com/GoogleCloudPlatform/google-cloud-java + +## Set the environment variables + +PROJECT_ID = [Id of the project] +REGION_NAME = [Region name] +## Build the sample + +Install [Maven](http://maven.apache.org/). + +Build your project with: + +``` +mvn clean package +``` + +### Dataset API + +#### Create a new dataset +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.DatasetApi" -Dexec.args="create_dataset test_dataset" +``` + +#### List datasets +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.DatasetApi" -Dexec.args="list_datasets" +``` + +#### Get dataset +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.DatasetApi" -Dexec.args="get_dataset [dataset-id]" +``` + +#### Import data +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.DatasetApi" -Dexec.args="import_data gs://java-docs-samples-testing/flower_traindata.csv" +``` + +### Model API + +#### Create Model +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.ModelApi" -Dexec.args="create_model test_model" +``` + +#### List Models +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.ModelApi" -Dexec.args="list_models" +``` + +#### Get Model +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.ModelApi" -Dexec.args="get_model [model-id]" +``` + +#### List Model Evaluations +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.ModelApi" -Dexec.args="list_model_evaluation [model-id]" +``` + +#### Get Model Evaluation +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.ModelApi" -Dexec.args="get_model_evaluation [model-id] [model-evaluation-id]" +``` + +#### Delete Model +``` +mvn exec:java-Dexec.mainClass="com.google.cloud.vision.samples.automl.ModeltApi" -Dexec.args="delete_model [model-id]" +``` +### Predict API + +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.vision.samples.automl.PredictApi" -Dexec.args="predict [model-id] ./resources/dandelion.jpg 0.7" +``` + diff --git a/vision/automl/pom.xml b/vision/automl/pom.xml new file mode 100644 index 00000000000..5b5dd838624 --- /dev/null +++ b/vision/automl/pom.xml @@ -0,0 +1,154 @@ + + + 4.0.0 + com.example.vision + vision-automl + jar + + + + com.google.cloud.samples + shared-configuration + 1.0.9 + + + + 1.8 + 1.8 + UTF-8 + + + + + + com.google.cloud + google-cloud-automl + 0.55.0-beta + + + net.sourceforge.argparse4j + argparse4j + 0.8.1 + + + + + + junit + junit + 4.12 + test + + + + com.google.truth + truth + 0.41 + test + + + + + + DatasetApi + + + DatasetApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.vision.samples.automl.DatasetApi + false + + + + + + + ModelApi + + + ModelApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.vision.samples.automl.ModelApi + false + + + + + + + PredictApi + + + PredictApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.vision.samples.automl.PredictApi + false + + + + + + + diff --git a/vision/automl/resources/dandelion.jpg b/vision/automl/resources/dandelion.jpg new file mode 100644 index 0000000000000000000000000000000000000000..326e4c1bf533799771a86daa32fe4acbd70285aa GIT binary patch literal 53485 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 {J6HT)NUt64jDrt|AY@zqNAdI*}N%BvD zp(4#61Ji9QNu`Pi9h8e&cgYICW@dU?h@1JvlVAjDsb;so#=Y)pDct$MCI4VThrR0K%NC zeq~&rY?{=9eDRfy`3DMjJ}oCc=fA1x+L5{nUI>?WkRtL@OM8h2hfbGB^PZUill1!L zrsUrN#D6E;g}PN2a+GC07~zm?J+Lqj{HBi2EL*YU;iawQj>ty1Uz0j_?VRWJ$)hEV z87ttMJYV5)iTHwZ94jiUap@sHG20?2{MhB&pdA35n_QsMT#!Zm&l8estAh4CHWCJ9 zQ;la}29x_&#^EvHz}-gmB_}U)70Y+RCtYy}?;@7U(%yJ&r)5_wrRBIF?ad?R>#_rZ zWxIVG|%#Dlr=7#O6JZTt-slF1u_%8zq$ zzYMU%kP)gDC^GvTp(T1_%K&18ozy|wkiDI)lH6WRX*z=#8q97Y4BIM3b$E6QjARbG zRn|$S=;MgmOYmGJ+BqPQK{OhbJRk{mDv&iHT`l{=`XrUMQ8b66B2yEzI$Xt#OSoZ; z_8y}+-=OJI+tUkbF3|q~3bm5zHHzjx8f3)z$g7XPynKo6oMC2&>{m|xiNQPM=8l_` zU9&~)$o$qn32pGJCc8od+RE7RM02DcQSzMhBig5{9l7W-SM6``$V1+cKC@&;D60zI{9-6VPfMm}0Sg zp{~j&GCGAJV{k!6&djGLZ?50YtH?n~F$;l)O)hjZZ?VY%y7b7v$gRPwlQ@q0z^njG z3yhn2(T&oRd%eM z0Osb~S{*d;!w=w#CA6{2xZ1Ads5j8+9SP-J&nyDMP#1)KDl$aL-xj*GN-*BEmK4vWNC?za5k*Kh6!#lc;=yz<_Q1>ujy4(U;~-Z|7-Gs+ zGMJ~=3R?+ulm!}0s^>TZJ7>FfuBgrQQ93X1+@_YEMU0M$Zk0RM(lCvwPq0>G0Qd*LSsS~p1bECP3p-eF!lH0yD?~POm8Ei1~3IzFTX%M$=e%d zqp1pZkx0RE%%|dhBM-wpqr}s^z8psokQ{BOV1c1dReZ>18)>LHr0Tzcr#eefBG%q8XggCb7h$?iXte>29(Im-G%@gclI8&Yij{Z zvY!Y85#5ag1`-iTWtNaPZo`uv#-XtP~CnUj#(j0{1k|isqGyYPxcLcACe=$*)kV;Og$(`de@bt0@@mzA+ zK;N^`jDdiDU{6!to)S+85WBI?7|_244`p%0Ay_X0f>0^L#6~t?+Bj}i zkAgzFijoJYQ=PDU`x>f+qeY@$;~RL7#2Z*u9x@h1iMebEAH9s}KhCA86oi#aCNg1f zCA^|oE@E=NG+DHqk4+$-rFr|JrM2Jh{{TeC{{Ri#S#c{A;8QHHs=1odS)?Dble&|F zRa>|qjq|oDwF#|~OlZ`W&)A*BC59(oinhJBk{2<)xis>aZHWj6!=KH#8P7s$Ix$nZ##cngt@Ob?Ol z-Sn?&c>6|9-q{JyYc-|)#ngqaAb825WY%I0X>HJ+Z0w^i74%7*0)y{{7&ZW z*&a5)1hK&n)G_D=qQ1i?vV)UuRxfr`c%!n8+mn&Q) z?0TCu(DH{!dcs2+X{kljjL_7w20Q0Iook^mMGaag1nPK~xz@}-MaebO84inlC17XB z63pY}iU_op_au^|=uf3vPM&!hD87^2DixgDTU%rk1PINO{-S!H`HA+fg?*Gwm8}jD zS)wZEW#$~WzmWP0VbIgMBWf}!agmdj$DjA@SYwN)R#if!+d1%zVB&*jCUGtg4fqmD z83{OaQd61a7>)kh)MXoHq{)Feq_;l_V;{meQ69BV8lgLt{HmA-Zv9x0FmzjQ26kzT zk-=yd5~{eu;DEXMo&El`SKv2Bdiu~^OxPjjlY#Q65Tu+Pmm_1l zVyhY1MUz0+N&vS3{AhHj-0iVB_aR5r)9z0LnMpa*%*`db+WE*Mg#akq^ zXVE|(N~3pyE2Hvn#8<}S@jn&fwkb4s4J*SfzNHDvQKb-!9EDX~C(9$M?<-0)2bK;G zhT|WHW%xTRPX~fqXL8=77{-07EvU-kxdqn-gMo0Cx47aq(Z~|mtR+lQXgZXsAdnA> z4#P;)*y;r)qm;ee6_#5=zlDAd*Nfc7n2j#yHj+$O>UmgX1t6W*0on3GD&!s1S3*ri zHPR-q@@hC|6gF|kZFEP(Pk1FS)hESk?p|?26w(K^BT+n&0em2zHDu=qa zLmbgR{&ZlKAp2mC>{4nqC2Nr~nUuY^lE&qPI;Y{2Cao+3l1QDE9o2;pB zTni;n;hCFB*3$62Ea@C)21ppm67SLDY?Sugdecgp-4;)VY_A$W#9SU(t=&!ZF_vb9 z%CwQL2Cj$1n*)$?rB7p9?rLk4R%?2+WjHmX@gz%gGbPL(2xkneg?i|1Cn^EKUA!kC zcv!0SwQB2=McOu(KZUPhjc!&o)WKYZ-^4q2=rgysl_Ju88&WOgfczL+#F1QENi!LY z%9&juf`OgbZ`X6E`*f`0*C>*YOeE4swo;hwVu`>QX44@Jk%D}N2X9Jv@q`hGxP-=4 zOVoRdGa!-^8DllRMn^5Q;~6`nUkJIC9^E4xLdM|^2~|Z3Nd23s zI+TsE{Eb5Br1~io!*d6i!!8si$h{oU_o&|+JDT8{}#gB}Jmsektky4JhJn3csOisc@4637S$L~aYH$SER#4*AC9 z>_|Q7WszMxvzuAvaNOu&x8^n{fD-3d<$qj_j(duelM?fiC*lhshe;buT|sPMpCjw* z-@lk$wT^*QesRTYRUDWJVb`W9BPGF;qFMqQ2Wn{!hg9eT9qJDzEn9f)v*}T4nGz(6 z{{Rqu>i2=uz;|$oy-h1%s}XzMFO2P1T2_bKg7*rXv|+1{Rc&P2qff(c1dE}KQ%&wb zLOgQBP75f>s+q3QmWc}9DmR@hm$WZ~MZ>4$Um(r_rPEmv@>#r(ROF80x)l^7WPy-( zs9h5ou;UGFAXhnFgc=c*;1@=T;kV*e;g<&^?M&4TMq7yR`RrsZ9$G))O44Xr@DA4W zG0^AfT+)M20KX+mc-6jBPZ?sE%K+y*sg(B3B(UuU@*4q{ zcB&~Q&@3cZGR=e|5a;BLjB)!MZpYAOuL(9Xc51jyx?7^o@VIr~W zB&@7)lEP0rxKxHjILotX)T7ruGvq&B&25xS?ipm1>nyr6r4?NmW3eZvOrED;J*xyP z*B~7BB&w6#_w_UzFhL_8`Cvu|YQeDg?K;{62zHh67>!0jW8J*~&t93NacE~O8U8CE zkgQFD0n@Ayqo+(T>7)#ijfwN!X8eg)f)64hk;5F(ym%UxMggT@cIt8md=GP-vCiY3 zLa8e2`}_np?}lS*aTcwgrjzu>5BJuMd^8KZfqoau%OXr-BXyC<)AR#YKDC@$`~r_H z_%+q+{Ht|Twvc$TG>J!>V|_U4Gn2mie^ zZJxjmn{DBzN|lwz9V4lDjGELth@7IcB7RbELXP_aqML9fE{Xg?bhdFc#Un{Hkfahx zK1jQ{$Rod%2{jzBTi|bnDYu$ii2;m2Gy6lTQd{NJdLZiB7juD=+JaAa_WuCrbn&<` zom%!t2?1i*WNZqImOkEp(9=oX&|t1q$To_+U-3x8NVzwMpooU5*(ypbOTu47NnXWR#dqR@^#b`TL1nSJk7_x@X@kEzgPVxwC??BZO zgQ&3>Vml8IC%<1>J8JhaZ#X)&n$v>u?GRh&GXRrGG4aZWqsD_Q<2cFisNDN3qQ0Bk z*8zN&_+F{_!%ciyZA5KoXC!Kwv})x?ww&w<0BBu{7C05jDLKP*xG0rMktXUxYdy`& zpiUs#t*tFoV2Nd8mL#H+y9(?2l7^bb2st!pKk)_SfN;x*pIplf^D`*M zZX<-nCV$jk<5fFuDvCDR+&OP~qm16o3Nt{?B^p8bBvfv`fsp6a)ReH9r-?DSty<|` z-4w?>5^9OC01b|wsOycrG5K>+)K2gP?psV(;vO9}w-j6WF0C!nY%8R!7>387CwzZr zs#Do_R7t1M$Km^qM-q-}dC_JEn;fy*2;=4ff;A8|YF&zqk~>g}Qd^VYrkicjFIm`d z=%$N_+FC%i7XZl;i1kPq9JDKu^6lYau~uAnuK1@aOf6>yzlmL2ad;Ul*afyZ*IEPZjhu>Dnl_Bm0{C2pPwjVA(W?fxO4h2#C` zjFLA1;Nhot zXxr?dFGZ>)BIm4n42$6xVuJ9@MrJs^xo@Fde4dj!OXK_<^~&MtqnNiCTh{Ax1XI5 ze#WTS*<@#v0;1777P(Dnk=Bu_U}Ibph{+JqsN@>FTC9hoXqqnJ(%=>#AAE|N@`7b} z*9CZI=G%j}QAzM4ID%)7L10InbMVc;d$|OP2(4o@* zo6BRXc`jIpxmsb1R0-k>u`Yjky-DtUYLTu6SQ(OdVODj_(yxI~Hl{2_NE_|2&NcvP zqTO&c(bTT-Mz1!I>M#%-DwF1W?b?z~j5%Y09=R2dk^{LuztV~s4qdA<5a`5Pk-l)c z%8*Wbia^EuAx;%_8cf#{FD7ZqopbLbg^NBke6ftT*bMfkRJbS0u{rPLirMaFj!5PO zVMJC2;^$gqDQ>8t)w*@a9qL++qkaDXKlC0}3zqTx9ksQL&NY$LPY26jTob2tkAZ#_v@Fpz+&33bg~y6Tzq zCt}iY$xOF|Q4Q^DN4&xW)7HGhYBN!1{AZ+ZTU`9^eiOI>XIVPp= z>yHRHwMK3v5q>}7ykCkVe}wQb@+@6)ia~Ln?<0_zJ>2$CE5AXh>8dkb6|L_N7yLbQ z!|$fY7~$o3yu|)-A!x2!+g!1q{{YUDQZ*LEmyxNLr9IN6V1pO z-0ERlRscxlBaavp5O7xq9xkIvAc8i}O4gSGIX;2Hu}^O`%pjwDvLlVt9akrQzGKrh zH}1+8ko-ZXv*32p$hxJ1c$0aE zx{yf86~`|hDLofBAZNDTe|oF-sz#e^$#EVf#Vj0&l}eGbh!#~N+X26i)}cK~K$C4e zgyFnq*NTRLn#L=lFjN4dLFJ{!W)uJ+Gei4?l!KBtyz>tp-QnQ>=KnNA3ftj^1>sH^j1<12y!(&$ku~D4dgm%hC zXkfq?s4Y9mo&yq%@h)i&kMX8cUXwcVHz1Am|5Ozv&0Pb*1E@`5x!mf!kGiW|xqn#h5xg2bOV#AG_EczVyq1khSDd zT*mMc!V)lZoxt03_N9`wlQS`OZymJEk~9kJOSuS1W7`>R!1Wc%mTVIC;Q9;L1aA=} zj^h{u9(cta@s=zRk@MWFQM)P<7kwb^JhmM_@4hosPX;J(Ngarl=NN3Vs*Ea(6XDNR zAxSKI3=OH!=?w8Zr;CS0G-&NC$Or6(vH`|$K^bGHfJVS-J%tGd>n2l;*R;@m|kW{kLjpHnehoB%-BjO5@SKjBWi84mCZJWVCr zCoVYRURnTILk|>sL1WVej>9;~t+vOD?4u6}xiHA;!JW>cWjG#ylY#1d_U%E%rD00M zc%(8}!SIe*-YANa!~*WyvCl!4Cx0L+MJ0rh1CN6T{vN%gNSf~_2oy-E%u$&M$=fB2 z8*fF@jAAEDTk#N%&yT@rtVs=kOE`l9t^^@sIBuJ?Oit&oN=;dR7`HB%&CwvmqZ*_EN_)WL?rwp|MF!vCtjzk@sPKRH*kz5kfdRmDVtB2sF3^G~Y zMLVfgnb|&3OW%ieNRIkUs4aS*hFK4w-9eVPMlacEbg(Mzm zTlZ>^&+26NFTg*;oJ->&XweF@N6(5S!8%->ae>^Vnt&ZVAar9wGO1G!F%5NOCx#e8 zB$B%HW8q~!OnZPv3F@Um##NNhDW%Cb#T_JO$smQ~k=taBP4$7DB)B`3$;JrC=z3B@ zE1qZ$N?k6 z^f=FLBfTrNOkT%gQD=7%w|v0t3i%PcANoL7IrJx~6k4pI_&yi#aZ4*k*UOdFw4Ck= zf^dI$X>OiFBDUouD|SG-mxyqg*gz6%YzPPdgRKT)~9n6lG@+t;Z&q8zd+K#1Ff+;i@-W11AQCzD| z#@ZAzT%Z+N*ePnl+Yo>%b9;=AZY-3_Sd7x8KxpBkXx9q3?OE8Z(2dQ^@PmM8!U|6y zOq6dYl5CJgbV?COdR(&S1(D>F$DQk%QOKR(dg8@oZNScGtLQI~)|@|(`qX3Ef^PC} zldHj~5Ne868?%_-L~5b10O?fRyB;=?nU{mz++C6m5FWKnIVBMksTv3@o;X!luk)Ee3=;Of#tG%T6%0sJa&+U#YMlO)R;=q8y$XJp#*ktT70XaMDGRI@Pz;1@&xqF9^d8AuLOHS%BoPJ%p zoyOVjGI!p4?ffHIa>nye<~Yz5OR(vKjN|AqKJ{fQRx)I(+mRK-(vDzhIc)g_x9^U? zbw1?OWi6~*$;{HMw%R8GLL3vx%14d6kMZ z?8Gywe(94+sP3_sBc}HGDu~>2=v-fkF76>!RavElGDLCZ)nibgkk9)y?WI(KzVsy5 zlXCKBIBYk@ce|GI;7nZ4^17s&x&WZ(PDt?o0HF39LZ*44vTHgX#;3vl?NeCwlP;9!7EO=Pt=M)>JJFBD4 z6+Uldj^*FLGT<>G0r^PC-J1h)2E-fy%bg!{rWGc#hdBMTSFs{Rr&9jSgRwfg9=);% zApZbibzq(%7T;!1iAe$cQ}})-h^4K9PsAirKP+rmf(|hD*oMrUr0;F%KAFlEcf~(oa@Zg}^Ka_?6L` zNR5^HhI6V|;xd=dW1J8@H65#?OIhs7D;XN^!dw*!1%?@;w`L`SLeZ?R1&zZ;dmh6=iO)9!+nh7) zQ}s~YQbk*(BlIw~{6f^^;5f-3ZSPXie^xFJkxYN$-W4h`>`ul^f25orF`wP8X-d`j;Ro)G_Ke3D zkKuTItWMm?uMWAHx-21|bMJ<4Xvdvi65XS3mIyt(jabclV;|wUEi#isJjGayff^K3 zpD=YC{cENY_Np_uymVaR96VaJy~hcKxl>B>!xG?yS1e?NpCph-xX(!xkaMxsO)bc7 zI4eg7#sbVUw%~Y-iN5F5WP(37Pw#B;_pFH3v6Qx1WgiwW5Q7_*&Knv)K6`XM$6SyI zv{idm}hhI!*uGEd% zV!WPP-Nx4PTEren5A2aP!<-PY4_4B|d9tWINUavW(57Z)mF!LFj2Z3VFkZyLws?Yt zay-6lf-!;)I`0Wwa86jUsQ&;F&1ZGH+BinCk|+m&G;F>G{n9bvIKjqnM&l!T)6|cHZrjlhid>80Zf);*x>sOwj)T;H zO6Q*GWjq1w+{>jw&2(u+C2XRi zzX7$K+%p5FrL8s5DZ9cpmhr4njYk#6xdpUz#xBGYR=NYQN0bkX6s_0+PZSa^+Gxcv z;6&I&PQV&1un$;StZkLW6oJ7_E%Mzd@R6)`IEI>6MkH|}k;+CWT{{_hB^K7ij+6>o zWkVuI9;P8yx;Qzqz(IKx$YBcujlJn7CWcXc2=N%?H;R!dieHrWHKo9Q1Mw~$9OIiG zUc?HE10*6C*sE+s6o7)nRhtZ78R(}J6Q`3{@+d_dm_~lAf2ZkPF`tA{Iuw@j=2sBL z!CA5dP&f|2eA=Ww7|?!ZQJ%j}y*W3AI(AXBGqmCu<#>Z*opJ#g9X8L2kL5%d3Nl;9 zN~PZvKSsXR+D!>=^H-nB5Ve(pbUAP{{UK@P2nJ9Gn}y&qCAY8%a%FMZT9cb zQ$BDLt9wThH1oV0^(SMe-#@S0&Vq|h*itHq#k2_JTU5Rn(;d2W`+lC4OU6gBZ^ch7 zg@kud2(bWVjvQhxe2s>Yw1P(21-yV80!=KhPw*K$82PxT6P!dMJd-LHR)|K(5D-D% z0G7v}wJ+3d;222eIW8j(E-xBb!8<_5SUdhvf&KKU%5SzKWnKqk@b7cP;)*s)G!Vf( z&yC)4cEkSajJW^|kOxDM>p5S!NcmwEnh4S;`I1W^3mlUGWSxMs+o?hJ;cbvcHbjH<5U64z%@=LoxOPCYE}=D5F@{4Udc6PN-&n9~_uvjtCYh zok_qtMp;+=PUt*?9}RXxb$A_lH9R{02(6dlnWwf@Ik=U~hI5wa&ACjZn~VnKwgv#n zo~F#c0`ZcB_en1fYcz;6l0eDNFsWq#Z?VEQ2Sbc^$flH(<7ihV`7+n`mX|hi%>#hV zfcs!ZM&K|Ylp^>{MFv=5Db z8H)N=kX=S?&NRWgv~l1Bh@O~G066Q9Q(lC0t>AgX7BR&v3|6+b%#kcGLQw0Gf|fd1 z>;VU_a(Y$vIHeWPtaI@CO~he)38c2f&6r*WEFzrXh9dxJE{v!Cbv>&jM3Mi#MVge@8T{a%-rj8ihL<31DzkSKePk)U5DiqChdW=*`B|)V{Hg%%h}Bu zMIrp^(GsDD`oO^QJC60qC%5oT{{RAsZ_c;mT;QI9L)>-@JCD?MsK-~PWcnk$frdlB zgFQ3So9iwClvm*-Ms${?`m{V*O6~~cg!eTm>kVdRTL``*rcF_6Iuhu+XB2Qlorcvt z)&e&czmPEz6YMJ5agSiO#qDlxTdrtoIIaNjH0?25?^2A=ypv?RnmKU9;<}=fSRF+& z=MR+02xH|_ZkdOzZZyfHk=B{u7tvjA<5cQ1OJSg}P9#D>rE&!j__zN6FmigjL zCA5|~*93#sxwT-Ev=b-k4X|jt zNLb;YU&0}nI_CkUmPY z{{Zs%W*`x|j`d_ZBN+rzVj>h04tnb#?S=f6n|JxJJXk)4!n^H=IpuETVVe+G&9SvoS?Dcb|Fa&x#F`?o=WD`}_5RhAv(NEYilOfAav&dky#dQF5h_*mRqtNcoMM3J3#P@&md4 z_ohr_$37z25GBk}IdA-;po|aR+Kb!6Lnec1mQEn^k*h7G9G{T)&z6z;vW~gH%6T_- z4*Ex92!Jt!ks0VPr%)v4)GywIo5gTqG`4fC@o8sbid#&K*zlZyHXEFF^QomP%LC+Y z!aGqXgnUEfAfWfJuiy>8s19AsXlyvMd=SwI) zP}8P}_GvUO%{+sdAUO?!6$hd7>F7P^Lw76)bi%5)EuaP}B0FUc`8fw}#8GO~8DWgv zSy^0M+e0PEf@ZggNj@N>0|b7Dsj5j<5b3@QzvHeQcYns_y3}H}XqFX>29T6d;22$i zAd`%Yuw#R&xpm^?N>{kgMZ+{9d!&+42+U1zo9a6PtGPJqxC3Fn`$`e+UcfwJlvOujIyh>s)B2sWtJRcl~ zd>jHb1+IkGHaS;^4t3qMe8rYFm1B8hK#|CHGBPjaj3OjxIs^;mYnRl@-6KihbC@J( z<&}yDh25EUDpli`Ao+!P57M90%h~&olNaN$OtO4*S{COotye0%#mSL2-%nQ<+yY4X zNHlLdg|omHiT)PgkIdwv6x{=tUuHk!t$G1(YT9R$jAtz_(KZN+fwifo6S2q_d!%Qbm?maL_Z*Whp zE6tvc$8dk3@YJQW*T6)#2z(M`fTVn_pX2N8T{+IYBDZL@_)!5z zmRTdXcP*uw&|1ndjfe!PIUQF5pHC)eQ=Y0&Oq12PJ48w7SM&{Chl3Jib+JQS&D!kKEF4$31l3TuWq8ZOQ{~>N!U5c1znFX zAbM|;Np+UQZo4wWh(jEAl1^@&^e7tSRtLwZfN`J6zSYjBkuS)Myhb?hE{>6jq+5k6 zxk-_>Z!N*!+*dxXs*4g*MGO0gBS};c5!g(Cbjch401#?YZL9KTWVoLhOLibq$3f44 zM?4TNe-MXbis+A{D4@b{{v^)eja5Be3P5U&G*?dWjm-;J`hpW2W00tr7k?9!#;#UFkHi8ll*3(94j1Vr1V*3FhuXKn!Yp3hkN>8z~mRvGt@* z*zw?*#BL0;cy}b?noKDs6Y8sWF?8);+V%_UG1tQ9A>N%1sCdckN; z`sBwB2pRROzC#b5ov^Pet@a3O3RI(ByUF3ZHzCeGd@9Z;MPB)jp z7ENSVB_mRb5=X+KvjxEEvW|dy=e<|zSL!m6<;3qj%0z}n!)Q^K0H3(c2dd{PL2lg) zM=D0lit)k}V3i76fA7|-Yb$}17_oTXXXIqK1j!~zVmyiLJt?5#-?S^>scCLnU?SO@ z8-bF2cRK-&{{B^Dvw_i4Sz(2FQ8I;4LGvB*eMvd`)g2{63S2rJMIRHGum%RhR(Abr za=XBAN}eNeAz5{0GEs}}K_^(xP@v%Lj4DG(KYpZv+$AYUUt-`cKj{Mao7@c-fxpp8nKlK6ZqP*>A?!(|& zbaf5t#~rNr8dBkqgWXyvLl0sLee17Dr4&YJViT=i#&*)pt`ja#g5unaIQ7s2dg)=_ zslGhaLQmoKNW^i;2ONO%)d1bCc~uk>`%6XM3X>#hX5(yX?0nUK+Lk&@ zc&cO$7iuNCXH$p{dGEearO`x7j}S>xm>%l;=EUwU+~&pkRz0 zwWz~>U@?xhIZf6K+epvJ#AeI6WNd?y2=X`^`}x#2OOb3*?%F^LDcEFcQP%(+@_ehC zR#$>;fSTdvSb@$_G#^|Yzf2FM2P`2hi^MEmb~_VY8ak>a;VLG-3@CRM(e2FHw`?|XO4aZMViR7nO3xb|B!g6n@*Sl#zfj1nwxtGwVzo~JWQsXJ zJr80lP^Sb*2-x(YEisd$h}2IZ4YLtblG=xkMfCFID&1*VjGGwvtDR z-*Ko7*pA9Ony#J7+jt5p+fE_21(d3Tm533y{LRpxYVCt+JQPm_DDNaL5?2Ut41qx; z4=;1m_yL-_lN!PEOss8*D)Q+iy6@Nd5leS~pCpD$g)#?OIY%mX&@#it>$o9$kb41H zJ7!NHP3F0zQH^Njbe^sT#CZ&0{Xn3#6AjpdGRH3L&mQvbaC&7&+Xw1=sxO~`N|sae zmC>*k85TpHjk!;t>GTGx2{{ay^pa)FL5XQF#~ni-FHyOx4nyKH{6x*r61o>3l|U`^ z7$|)+T)NM2-3Q`Oh`7tj$NalsGCYEjkJhEDan!$oF?M@yy=0&*6wsjY@tQ;x{njH5Z&ci>q!2?blFa z)Zx_azUR)Lh%%AklM=>DUNJ1z@db&ck=ke3RO>p_1A*J-IXEEfFlswq>q5yr#co^1 zQZ64F%CcanISaq$W9RGFs}cqUSt`U=A^aa-O$-(eA(tS6(S^oLXr%)Iz5#h0=WmpG zQ^}~T1+#{}l?~ichRBuUU0qp(WQ=F9F?HxaN)ekhXSaZsm#u`8Qjkb;S0n&VHa+?f zHr$_0nNG^@vfmHA_`7m6m2y}d50!ue0C^2q9-#S(qL$<(+3y#)(kHh&No)&7%6AAh z&+y3gp(jXI`esni1d|kOtc{Qqpz$1JfCp2K-F&msx#}#Pp;mQ`LS)SeT%!Us>Hh#r z58<^=R)r(q!KPkhC6U3(k>MlTAIiDqxjRe@hj}dKLS-z+_tycwxdb1uKD6Ia_A7PC z@(oFnVSf2BgnzC-sjgi~_!XS00M#yqLHR%?aZMYth=+W@O^&{m*A;-G&j7a6H4$9$ z_edxQ;)ygwR2u5hg*zGZM7{$*kCx|iQ}s~1p=79gjM^!SSQS4{C&0WrGp#yCNF8g? zP-T)5p6fp;szwwth}R6_%?yA!1W=xmV#*z(Z^QVMbHS%0aniXYoJsykoKC)~rNpLU0QsMPrb{kZ0B?fqMg+?N)r!C48*4Khq!RtkbanrbAwN6UF*oEvOSXn(bH9Kk9lOsnN#u#)MHAegl*mhoR7skt=7>m>WWB{i|#btj%HqfIG>F&MDDx4Ys&;jE9GdkV z$DMMx?E`l5E~%@(ewCY`GT#i9qfi*+RM#Lw(`hPMXwnG_h+Kqh7RPF=6Ju4Ee-GR= zh^nCJ3Pyd-=lN15y4C&>nv{2&&Hj}8IQW$Q3k4D{6qgc9z z7m}7L%Chu3YF5sa9;E*O`x=_HCe3*}l&p-u{{YZaATNZ10b&PHlm7tZDcxV>ET_U@ zIaqab5z(;6rb`ANt}5DatTCdfV(uxVSf;g7^5}T52KuwqeGl-blI;{(5D}BcEUn6N zK{@^3pv+!Q5p#ERh>N9=0*-JJUG@wz zax>;O#xb>NY02RZjRofmziU{+{6uLSs-?oS7eF#wZkmpxx!WSSh(!9Bj=CRyRO+GMciq+uG}qQe{miDV!Ff#eTOvFTNW z6{98Orw~h9C$+PR*uf!GnPu@Ti5WN;Cku>^U8uMusC7u{>Kj>6xo@8r%9uKv%LlIA zv)EBdGzUbftlj?rW6Y7}oRwW*4GMl^xH!*GZB!a{ff^LJ2Ih5&259Z|A|kGV`z1JD z+20Z|+w=NTHPRJ|SS!zVpxrBzbrh14gBa9upnmAju1@|!f{sDUJ?5grY+z<7463o} z8g=6ft%1jcK0f&F)vYCtjNgII0z#V@(^-kwsUNzE<=CI7>(-hLkEa(d3OraF--o_J z1jUM=EvHtmnGSoNqt|aLZBKSlX?l5c+A;UMn2P}$n`R&``>s1@%}6-%$C0i{OKY=^ zNhd`4Bo5BJ+^mhOos1Q8+~c5bht`9g_G?0B;gL!^G3-MgmCW@T!!V@okL60_D`;KF zLE)%1Y@2710K`*P4HQslNrUN446=r5>K6F1o`ly^crtWqtQtFeJf5UfV6BvjG5mh> zojFxC+Z9L)F3C2MJXcD?rfAA4QK6-jY_72{4an+NxL~%-mq+JUjLUHA>t4)Kqox@` z?8nZUhNIZ>PG~bR+b$&~yvj0hNi8)bB%x;8hVc}*ga#uxt_kVWAyiYdDy~4r4{AiZ z1yeb@w$&(Q8+8<|8LMDfHp^{_ZnPR67wICjdN_oR}uGBoV*w7`spAIgkUbWvpt@K#2GHzaFQo$G2UlQglD z%gdHY$p-+?jBN;&p4-nH$Wl-bk*2CcRTHl*z8YaAxgdH~VX11EaLSfEQz#a0zoDg+ zP?Argk18qGTr2~5R3#4rSA*4OhB6pniiJB0b;yOM7;}BgAdq%7*YsZ7MH1|@Cj=Lg zq~DbFp{ClvwMK@<(mP0krYV~82K)?}2Xj-FrEn#JcL%8X>EGY*T9=EbrHY-YM1uISa^eaAQV zLKmEkFE9pH&qP&?`AR)@&N~7-?NxHG$ZYyKo=!GIK)jP+pd+9$E>F29?O93vPnK)Q zRlTTYRnj-au|=NZK+f=b^6Txn!~n-W||uxS!$W(yb}G)zZwG2mfc zFiJ?inoVFvTc{zrX)`m%_;NL>sb4RrN|dCNpik}@P9qEjlH5Bp9HB)205M43LC|!@ zeUEWP%|&2kRcK@UVq}reII^kG6%MvzjrJWj&fDX@DlpXdFs8~fUn-&ui1f#)!6O5? zB#&{wL7t|&EnxwKM%C~yZyFF8gGr2Gb(4|i50`$Y0*mT|6yg`D1Q#l$f-%7J9s)D> z6*)?*&Cwd#@>n(9Ip#pSGIhz$HqU&5J@9%1P=uPx5jIm!G#iqdOvd$Cpi!xoAUsR~ z-G(#a-Smb#f(=h;hG=fAUgL*4GRO!)lYl;4dJqF_e9bbdxPjAH7UAOMBb9V% z%fpOGxB07<$sK{u@T85T@G7wfy%#({F+8MZk}V8~a5gG4kVi~(%_Eh_R`L%1_3XGj z5+k{k!6r^hoSBt;$sR4XKb7i_Q)Dcxb)^W>Ck{J3&5V{Z+!)g2=!LZr$#6V5Zn!K0 zlb(;B)fj7UTVG`5>L(@0rM=vjXtK;o7XVAPJVR|*^XN~mYnxJS@=aw~=P|A3Y=vxP z9UG$#;Qs($V_f^(9zajOxl+y*q#=LHb{n$x4eB~){jkoY4c1K;4a~tcoNxw)8cd~4 zEQrqRq}L!7Nh}W(Xw^p}e=5*JnakV@jQJXO$$?(p;@?W0@rtIJ&5ccv?XB8rNn%cW z)wL%`YoM2w`f;FcDKzDLfiktcul^sP^~NbAmf;hu8JoTxB$qD0bv4}`RYl<}9DjmL z-HmUr6Fo+Tqu??Gsl9aAzfjvBu{c#w%k;<2;G$UJL-*>7^j99BE@d4iJ7u0u1yNoOzX#w64fI< zhOxVQg3G0j;+9eD$qXciJNKom0ikQy#;wlGG}0&FXo_(3WPz9*6l$icO`2XqPZ^mB z?@JdzOy=4R{Y7a^W682xPI4$OCRjL<94@8$(?(uRVJ$8siG~>M*wJE2DAC$VE~C)n zJ9VjHu~X@cS@0N=aV`g)RX4!t*CozuaVSjS3N_fS*sb;VB{eSMqbXkkiCXbwnZ9B7 zsA?v;86tt7Qu&JJa%P}yFYMVtIAg!HGL|UR8rt9_>mv<8UzwzLARK+am0A)@A>f%c z;l!inckya&=SyeqO8pcH+Ip8^vc06?Zb^zamQ=GG)*F>ylqdsyvk~9<*K&02b3=AK z^TwLwx|9Mjl|nvY&<|t$DO{EN*m2m+p;fg+hB?G6z-x4kRE5YJvEL<+Oy?DNDDA+@ zf`Pk+)nVPb|HsptGuX*NJ8l6|eLDJz;?|Y7xf0ZtMIecR zHkXyy*0L~AE zcPBb`rk<**ch54|5c;s3$-7Gu;SVyt(>0*U7 zIF{l*W~U?tBn?CWJUCH-w#1wbuuZPQ;3|Z$gH?vdV$b+XCi`0x&kN3##tV5e==V!`z|C0Kxnqm z!yo0zoG2S$As(WtG&L3{;uA+GRWCenrVQ#&JP+P{e9CYmb%x43{%oF_JiD4(hL+C0(^;PI5Hr?mBd&b#{bp zF@7&RQrXXB>_;X|2*hoiyJy(8{_UQXJzYfN;AuNXb_iBL(aLnAZ<0P%?0>Cs!RDDI zlZmA^Xvwg_{YRB--4DhD6NxnP1>3?jgXv8zJXwFuyAvn|DEV&ti=jX2*UMOii}9(e+s)#Q{= z?*@X-(YatM?rV}x**3>TiXs+}idjjn45Qm3-(SaWbg38>)2F25gBaL~aai^4MrzN~ zv!V!W@rYDlVv%}g3B(ke!r21(Bhq!Z-8J+SF zbO*glQkS&|`Jkro%yLb0>PDHKKs4BGn>*8}+85xvz;2U$MwLRC5>`7StGPKF(=-N* zoHAj;H_F`)k)YM9Mri6t%x$Q2qZ!^96CJc6(D{zlrqVOWyo=3XGwoAujG4qSm`t&f zPm5#bD@t3bhECDe>)UEu63+ysdUfeVA=L}EbraT~17Kzp<|!TN9sm(68fH*~2hOsa z1fFnfI8P52(1w$)DdQf+sttX_Vz)zvrfk*ZfcLF+DJtC!E0YFB=a5Tnp}uT=>Mst% z$&2RAYsAV7g(t0c?2e=?tZBsC@YxzzMx(uXTCv*1YR=`B}PbLXH zDc}nqg7ucjTjjrK!bt+QHtY}a`qkyE;~k@J#T0G$jCS#^i**Ea3%CB`pU{12VXYLn z4bVAw%(oJ49^hlbTmJxa6O;9;KT_qw1C@q*`CR+~Di780<52-ZLW3u4V^RBUnptZ$ z@NLX~+E%vY$#P3+$mNd_c5L`}>U}rcIl!*1Hq~w&I#~lB5H`F{C3g*k!uYZ>z-n?& zT#|R{Ko|g5Mw(4D&YdNO&SRL#psCW!oj#1ce_em2LRfe?+qOAz#0|W%Mv5K@$&-}Z z23G);&u#T!_9C;?uWv@(SRJythVH@b=AJq2t`L~@4K4<9$iQq_PC6WbbB{WvryZ@@ zV@6h~nBFG^*9pFM3~=PDY5|q;wwF_}?Xe!By!XFJ(Qm^5Kk)V`o7tgfH5ubdnjo84fJ&@+!ty zr13H+JK{t-fcNe8u847wqJ=nA(%d9g@sKBonJpNMgOigH^d}{Jn>gL7n4z5&xFbt$ z77WUk=tD#qvSB@TJ#_nE_w&y-rnxyz%kyyn`3mAW-E@uD8P)2Qb~x- z7X{&sc_3yVvmdQ->gsL5Da)i*Th7 zNgpj2EyyXJqy)t5HY!a`$j26kopm6St}{(FQNUQ#(W0rSrtCsn%7L&erA5%`2aOg$ z2&Hz6Ib&+gCIH&9_b}dQ(ZK|E$*J*?RY@Z@2J48csg5&AJxbtHFFQ<^Ezc#BJ5f?n zL5p3CM+np;jO{_s6g-k0j#U^9QEZdIwfr!j+JFfiY4qm!89EfV;|m<26!*naex1o! z^vxx`%y$t3o$Jq(TwMy!OhS>^1aDwCIH%K>kTfT5Ss%n|(_4l~l+r~bpg#G2?B=|mNakw@8MCbmMt9#kF#StZWt0cO-wvG&<|pv1kCy)cOqe)f<&m-V z9<&s?0(m~-JXvIrMZ_X&g-{T-tUP3Fbg|gu0|4!?p)F-EY{zoxka(LkM@&-}h14i* zI(4Wy!5;X?^Bwjyk&}yQJRN#GA6VXhhFDE>xHtDjp@5N-5)p}IAon@tue^t~b!oK- zx%OVK@HmWC-7RD!NXJ}`PDm~DAE3bd`P3%yU9mM58yZOk!In)RYhuZss=WaIe@Zf+ zCjw+|#ZXAkE_$g%8)E@fEhnR|J8#47 z&;|-O^7E)mR!moYlqU-D^FSK2i9H+7*|+-V%u>tTtXVQm#_d^fDhml1-lZhL*g>aO z)Q-T;%M4)Ah|v(d0k;)svFt%%V<&{w9O-0fJRZ+v%rZ{&BdU<9N6?`{7KEMTSu{B# zXomu)6>Q7F9K4+D*JUazMG+yi*`h~x>DKAS}s%&Ebl32*-DYmhZCisJ#Rp5$5QpOQ2(y6D^l}7_f z(lqe!Lpvx@g{~#6$WCo=Y0@~jUk}tk4UMWwE^-&-!f_kcyuQYAGhN#@K%`?z#xGx! zY7})f%cQqT%(4T9-4P%MrB_!^29!+$Co(RZn&ntzKtk;jmEWyVr1EOBi~PlOtUg_V zq|?fvA)9H22*}TB4mN<$)K?fjwFyRv+gu+_K7?{M)w#t58^HBs`#X%!pUg6*uHi^& zEDXsb9gQlA5h88mWf(G&LGM+A=yX}&wyhupjj9t{oe1sV(Z*r6QIa)N;s|bqxQy*2 zejS1DT$0spMB5|8ag&|tn-53K!cCf)D##82Fyk51&C>_WHnsX6pXJ2knu-}u(_s|f|f>cqUEm`T_c;da!*00fm#`UBMYtr z15tWXF*0kQWXcZv*F-e&kc`1G`M1SSQY8Bg8Rkr&btDfuMIM0pFG)5dNMZp(ZMNi} zGJBuU5@^p+MQw<}(v1)W?)W~+GlBIapP;1N_Rvo(6aN5++cpn{!)@um@~6_ok(VMt z4LPAl>6OS3XuZbJ)gOjFn{LK;QhuA-mQD1Xm!Cc*z=sPp4ADw*)Gnwt{s+T z{{YMbKKRalqxsgF&hI13$u{MWCjjl7)`QI*ex2Z1Tn3HE)ufCA)6?mivUJYGIc7=L z@-cUAr1$fwYD&e_t)*)xQ7!@S^aIj`?mW-H#}$QSfU(^7u9Gtvb#P&336e!tD)|b? zm-w8@aB>A%X+`ih)K}p*`i@`3j5M<68kF@P&)f> zSQxN1Jw-yu6!MWK1!zYDMFaq{->fP0;-ntssmjCv#l;@&!RAc10mb_NuCRU~=gStPd-K>~UICNnk*d z+4wLjOH(G`n>P(|b_Tj(u7^{g2Zl-ORr=^{=o#UXG2b*kx(@Msz8t|1n5KrZY-r4x zX%j8#05{Ea&HHjvPU3!{!qrmLI}X+5uejziABy;+Nai&-0=*pwc03m2JHph-b*T2H z^%AI;mJrtxa?g(4Dmp5VsI&NcgC1YR+zx{v9@QOvYkOi&Qrzh4;()j)PkPD^ZHZl- z%AmI0D<^|d?kRTdki0P%%f9Lk#+}r83uzVYV3I}g4gUa*LUi~gCb~Vk zi%yMyFGK8VQF&uU`6t`NA-;4ikaq^UcW#Pfz5~r52O5TH5*CMSEe+Vx>EZLOU7$Rb z=49d4xERP3j%w){x<+<8`EGAFW2ZFQkoM#aV%emfb7UBKSDKYb4}wjg4plJJHZBSA zgB;@-1Rk_o74lYqj0%ldPUj%^>rY*baGn6nI_Y8e82)ugV$KlfJX(D=lRu%y)~yLt8V!iEYLK5j>Te<(&n9D3>H_0`Jm>h6LhNf4xd7Xezc4h> z!#e#lLdZ1_5W%W5u?||}U@B8sG?oL$A&J4E2b0NoV^r(-CU zxLn-GvTKuGG|0^y+{ihUbmM@-!Mv?pqdY2aIf#1uOo zl|NA{z|wgs@Qxa9ufwwb%@5qvaPIBoQE;n+PHhh@K)OwmtEj`ZJKZ6)pnKkEf zYpwA`Qo(NCK+vf@YnoBWoDAFBq(#PZ4{GOgY>SXs)))rMOHN#i$??BL*+o2IfTdt2 zoX(*7;55yz1kz$E`GeTEb z1AQTX#1j^_$nGnjL0s|*$(*s5Oz3;&yR{=|w3ZFzY$V}8`d5=BQX@o5Mk_P-EG zee+!H3QXcrx5Y;2aHnHkIucu2Wg$kVg{Vt)$ln#kKXi=oz|%>N)IJ0}4owt-aWiaa zn}SQP?X%`-?$EuBYtjZO5Kd%~vx;j*XME79xu%Xr0WHYJ)YQRXz9l(qxH)18`e*vn zZNOQ`Io_3s22;KbB1UH{KW1~i70K10@-3_{iy7@!Nc19t*tSk-H8>2ihgDIxH7MPl zOqN;Mg;{Y|>{_B-*9(s=AUlfaj;l(BR)|+}x;BoYx*-(Rl#0Bap)C&dlEXJ*F~_Rm zs?F3!ydGcM9kK66PGO5H@PJYc`qv+*%!yAd;grcf1w3$!ogw>s2|DL*dP(XgBaq>Y zMw{0)_8_yL7SzD8E7>ro2CbzWm4dM=OJ=y6d}B4yIjEwt!Y$1Va9iLG)yKKXlCdi{ z)gh`*I0?rWhr^s=pFxH$nG~T1YU{GLdalZ7RhV|#;IC3?S{0(2Toz4IwNgsGH^ z65;mD(JX0=PS~NVKXr{Mc5GpeJ`cnCW%2sb#yg#|d}PG&Ysb2rl1?*Sv5wR response = + client.createModelAsync(projectLocation, myModel); + + System.out.println( + String.format("Training operation name: %s", response.getInitialFuture().get().getName())); + System.out.println("Training started..."); + } + // [END automl_vision_create_model] + + // [START automl_vision_get_operation_status] + /** + * Demonstrates using the AutoML client to get operation status. + * + * @param operationFullId : Full name of a operation. For example, the name of your operation is + * projects/[projectId]/locations/us-central1/operations/[operationId]. + * @throws IOException on Input/Output errors. + */ + public static void getOperationStatus(String operationFullId) throws IOException { + AutoMlClient client = AutoMlClient.create(); + + // Get the latest state of a long-running operation. + Operation response = client.getOperationsClient().getOperation(operationFullId); + + System.out.println(String.format("Operation status: %s", response)); + } + // [END automl_vision_get_operation_status] + + // [START automl_vision_list_models] + /** + * Demonstrates using the AutoML client to list all models. + * + * @param projectId - Id of the project. + * @param computeRegion - Region name. + * @param filter - Filter expression. + * @throws IOException on Input/Output errors. + */ + public static void listModels(String projectId, String computeRegion, String filter) + throws IOException { + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Create list models request + ListModelsRequest listModlesRequest = + ListModelsRequest.newBuilder() + .setParent(projectLocation.toString()) + .setFilter(filter) + .build(); + + System.out.println("List of models:"); + for (Model model : client.listModels(listModlesRequest).iterateAll()) { + // Display the model information. + System.out.println(String.format("Model name: %s", model.getName())); + System.out.println( + String.format( + "Model id: %s", model.getName().split("/")[model.getName().split("/").length - 1])); + System.out.println(String.format("Model display name: %s", model.getDisplayName())); + System.out.println("Image classification model metadata:"); + System.out.println( + "Tranning budget: " + model.getImageClassificationModelMetadata().getTrainBudget()); + System.out.println( + "Tranning cost: " + model.getImageClassificationModelMetadata().getTrainCost()); + System.out.println( + String.format( + "Stop reason: %s", model.getImageClassificationModelMetadata().getStopReason())); + System.out.println( + String.format( + "Base model id: %s", model.getImageClassificationModelMetadata().getBaseModelId())); + System.out.println("Model create time:"); + System.out.println(String.format("\tseconds: %s", model.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", model.getCreateTime().getNanos())); + System.out.println(String.format("Model deployment state: %s", model.getDeploymentState())); + } + } + // [END automl_vision_list_models] + + // [START automl_vision_get_model] + /** + * Demonstrates using the AutoML client to get model details. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @throws IOException on Input/Output errors. + */ + public static void getModel(String projectId, String computeRegion, String modelId) + throws IOException { + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Get complete detail of the model. + Model model = client.getModel(modelFullId); + + // Display the model information. + System.out.println(String.format("Model name: %s", model.getName())); + System.out.println( + String.format( + "Model id: %s", model.getName().split("/")[model.getName().split("/").length - 1])); + System.out.println(String.format("Model display name: %s", model.getDisplayName())); + System.out.println("Image classification model metadata:"); + System.out.println( + "Tranning budget: " + model.getImageClassificationModelMetadata().getTrainBudget()); + System.out.println( + "Tranning cost:" + model.getImageClassificationModelMetadata().getTrainCost()); + System.out.println( + String.format( + "Stop reason: %s", model.getImageClassificationModelMetadata().getStopReason())); + System.out.println( + String.format( + "Base model id: %s", model.getImageClassificationModelMetadata().getBaseModelId())); + System.out.println("Model create time:"); + System.out.println(String.format("\tseconds: %s", model.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", model.getCreateTime().getNanos())); + System.out.println(String.format("Model deployment state: %s", model.getDeploymentState())); + } + // [END automl_vision_get_model] + + // [START automl_vision_list_model_evaluations] + /** + * Demonstrates using the AutoML client to list model evaluations. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @param filter the Filter expression. + * @throws IOException on Input/Output errors. + */ + public static void listModelEvaluations( + String projectId, String computeRegion, String modelId, String filter) throws IOException { + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Create list model evaluations request + ListModelEvaluationsRequest modelEvaluationsrequest = + ListModelEvaluationsRequest.newBuilder() + .setParent(modelFullId.toString()) + .setFilter(filter) + .build(); + + System.out.println("List of model evaluations:"); + // List all the model evaluations in the model by applying filter. + for (ModelEvaluation element : + client.listModelEvaluations(modelEvaluationsrequest).iterateAll()) { + System.out.println(element); + } + } + // [END automl_vision_list_model_evaluations] + + // [START automl_vision_get_model_evaluation] + /** + * Demonstrates using the AutoML client to get model evaluations. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @param modelEvaluationId the Id of your model evaluation. + * @throws IOException on Input/Output errors. + */ + public static void getModelEvaluation( + String projectId, String computeRegion, String modelId, String modelEvaluationId) + throws IOException { + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model evaluation. + ModelEvaluationName modelEvaluationFullId = + ModelEvaluationName.of(projectId, computeRegion, modelId, modelEvaluationId); + // Perform the AutoML Model request to get Model Evaluation information + ModelEvaluation response = client.getModelEvaluation(modelEvaluationFullId); + + System.out.println(response); + } + // [END automl_vision_get_model_evaluation] + + // [START automl_vision_display_evaluation] + /** + * Demonstrates using the AutoML client to display model evaluation. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @param filter the Filter expression. + * @throws IOException on Input/Output errors. + */ + public static void displayEvaluation( + String projectId, String computeRegion, String modelId, String filter) throws IOException { + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // List all the model evaluations in the model by applying filter. + ListModelEvaluationsRequest modelEvaluationsrequest = + ListModelEvaluationsRequest.newBuilder() + .setParent(modelFullId.toString()) + .setFilter(filter) + .build(); + + // Iterate through the results. + String modelEvaluationId = ""; + for (ModelEvaluation element : + client.listModelEvaluations(modelEvaluationsrequest).iterateAll()) { + if (element.getAnnotationSpecId() != null) { + modelEvaluationId = element.getName().split("/")[element.getName().split("/").length - 1]; + } + } + + // Resource name for the model evaluation. + ModelEvaluationName modelEvaluationFullId = + ModelEvaluationName.of(projectId, computeRegion, modelId, modelEvaluationId); + + // Get a model evaluation. + ModelEvaluation modelEvaluation = client.getModelEvaluation(modelEvaluationFullId); + + ClassificationEvaluationMetrics classMetrics = + modelEvaluation.getClassificationEvaluationMetrics(); + List confidenceMetricsEntries = + classMetrics.getConfidenceMetricsEntryList(); + + // Showing model score based on threshold of 0.5 + for (ConfidenceMetricsEntry confidenceMetricsEntry : confidenceMetricsEntries) { + if (confidenceMetricsEntry.getConfidenceThreshold() == 0.5) { + System.out.println("Precision and recall are based on a score threshold of 0.5"); + System.out.println( + String.format("Model Precision: %.2f ", confidenceMetricsEntry.getPrecision() * 100) + + '%'); + System.out.println( + String.format("Model Recall: %.2f ", confidenceMetricsEntry.getRecall() * 100) + '%'); + System.out.println( + String.format("Model F1 score: %.2f ", confidenceMetricsEntry.getF1Score() * 100) + + '%'); + System.out.println( + String.format( + "Model Precision@1: %.2f ", confidenceMetricsEntry.getPrecisionAt1() * 100) + + '%'); + System.out.println( + String.format("Model Recall@1: %.2f ", confidenceMetricsEntry.getRecallAt1() * 100) + + '%'); + System.out.println( + String.format("Model F1 score@1: %.2f ", confidenceMetricsEntry.getF1ScoreAt1() * 100) + + '%'); + } + } + } + // [END automl_vision_display_evaluation] + + // [START automl_vision_delete_model] + /** + * Demonstrates using the AutoML client to delete a model. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @throws Exception on AutoML Client errors + */ + public static void deleteModel(String projectId, String computeRegion, String modelId) + throws InterruptedException, ExecutionException, IOException { + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Delete a model. + Empty response = client.deleteModelAsync(modelFullId).get(); + + System.out.println("Model deletion started..."); + } + // [END automl_vision_delete_model] + + public static void main(String[] args) + throws IOException, InterruptedException, ExecutionException { + ModelApi modelApi = new ModelApi(); + modelApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) + throws IOException, InterruptedException, ExecutionException { + ArgumentParser parser = + ArgumentParsers.newFor("ModelApi") + .build() + .defaultHelp(true) + .description("Model API operations."); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser createModelParser = subparsers.addParser("create_model"); + createModelParser.addArgument("datasetId"); + createModelParser.addArgument("modelName"); + createModelParser.addArgument("trainBudget"); + + Subparser listModelParser = subparsers.addParser("list_models"); + listModelParser + .addArgument("filter") + .nargs("?") + .setDefault("imageClassificationModelMetadata:*"); + + Subparser getModelParser = subparsers.addParser("get_model"); + getModelParser.addArgument("modelId"); + + Subparser listModelEvaluationsParser = subparsers.addParser("list_model_evaluations"); + listModelEvaluationsParser.addArgument("modelId"); + listModelEvaluationsParser.addArgument("filter").nargs("?").setDefault(""); + + Subparser getModelEvaluationParser = subparsers.addParser("get_model_evaluation"); + getModelEvaluationParser.addArgument("modelId"); + getModelEvaluationParser.addArgument("modelEvaluationId"); + + Subparser displayEvaluationParser = subparsers.addParser("display_evaluation"); + displayEvaluationParser.addArgument("modelId"); + displayEvaluationParser.addArgument("filter").nargs("?").setDefault(""); + + Subparser deleteModelParser = subparsers.addParser("delete_model"); + deleteModelParser.addArgument("modelId"); + + Subparser getOperationStatusParser = subparsers.addParser("get_operation_status"); + getOperationStatusParser.addArgument("operationFullId"); + + 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("create_model")) { + createModel( + projectId, + computeRegion, + ns.getString("datasetId"), + ns.getString("modelName"), + ns.getString("trainBudget")); + } + if (ns.get("command").equals("list_models")) { + listModels(projectId, computeRegion, ns.getString("filter")); + } + if (ns.get("command").equals("get_model")) { + getModel(projectId, computeRegion, ns.getString("modelId")); + } + if (ns.get("command").equals("list_model_evaluations")) { + listModelEvaluations( + projectId, computeRegion, ns.getString("modelId"), ns.getString("filter")); + } + if (ns.get("command").equals("get_model_evaluation")) { + getModelEvaluation( + projectId, computeRegion, ns.getString("modelId"), ns.getString("modelEvaluationId")); + } + if (ns.get("command").equals("display_evaluation")) { + displayEvaluation( + projectId, computeRegion, ns.getString("modelId"), ns.getString("filter")); + } + if (ns.get("command").equals("delete_model")) { + deleteModel(projectId, computeRegion, ns.getString("modelId")); + } + if (ns.get("command").equals("get_operation_status")) { + getOperationStatus(ns.getString("operationFullId")); + } + } catch (ArgumentParserException e) { + parser.handleError(e); + } catch (Exception e) { + System.out.println("Exception in Model create caught"); + } + } +} diff --git a/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/PredictionApi.java b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/PredictionApi.java new file mode 100644 index 00000000000..a6070ad31d9 --- /dev/null +++ b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/PredictionApi.java @@ -0,0 +1,142 @@ +/* + * Copyright 2018 Google Inc. + * + * 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. + */ + +/* + * This application demonstrates how to perform basic operations on prediction + * with the Google AutoML Vision API. + * + * For more information, the documentation at + * https://cloud.google.com/vision/automl/docs. + */ + +package com.google.cloud.vision.samples.automl; + +// Imports the Google Cloud client library +import com.google.cloud.automl.v1beta1.AnnotationPayload; +import com.google.cloud.automl.v1beta1.ExamplePayload; +import com.google.cloud.automl.v1beta1.Image; +import com.google.cloud.automl.v1beta1.ModelName; +import com.google.cloud.automl.v1beta1.PredictResponse; +import com.google.cloud.automl.v1beta1.PredictionServiceClient; +import com.google.protobuf.ByteString; + +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import net.sourceforge.argparse4j.inf.Subparsers; + +/** + * Google Cloud AutoML Vision API sample application. Example usage: mvn package exec:java + * -Dexec.mainClass ='com.google.cloud.vision.samples.automl.PredictionApi' -Dexec.args='predict + * [modelId] [path-to-image] [scoreThreshold]' + */ +public class PredictionApi { + + // [START automl_vision_predict] + + /** + * Demonstrates using the AutoML client to predict an image. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model which will be used for text classification. + * @param filePath the Local text file path of the content to be classified. + * @param scoreThreshold the Confidence score. Only classifications with confidence score above + * scoreThreshold are displayed. + * @throws IOException on Input/Output errors. + */ + public static void predict( + String projectId, + String computeRegion, + String modelId, + String filePath, + String scoreThreshold) + throws IOException { + + // Create client for prediction service. + PredictionServiceClient predictionClient = PredictionServiceClient.create(); + + // Get the full path of the model. + ModelName name = ModelName.of(projectId, computeRegion, modelId); + + // Read the image and assign to payload. + ByteString content = ByteString.copyFrom(Files.readAllBytes(Paths.get(filePath))); + Image image = Image.newBuilder().setImageBytes(content).build(); + ExamplePayload examplePayload = ExamplePayload.newBuilder().setImage(image).build(); + + // Additional parameters that can be provided for prediction e.g. Score Threshold + Map params = new HashMap<>(); + if (scoreThreshold != null) { + params.put("scoreThreshold", scoreThreshold); + } + // Perform the AutoML Prediction request + PredictResponse response = predictionClient.predict(name, examplePayload, params); + + System.out.println("Prediction results:"); + for (AnnotationPayload annotationPayload : response.getPayloadList()) { + System.out.println("Predicted class name :" + annotationPayload.getDisplayName()); + System.out.println( + "Predicted class score :" + annotationPayload.getClassification().getScore()); + } + } + // [END automl_vision_predict] + + public static void main(String[] args) throws IOException { + PredictionApi predictionApi = new PredictionApi(); + predictionApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) throws IOException { + ArgumentParser parser = + ArgumentParsers.newFor("PredictionApi") + .build() + .defaultHelp(true) + .description("Prediction API Operation"); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser predictParser = subparsers.addParser("predict"); + predictParser.addArgument("modelId"); + predictParser.addArgument("filePath"); + predictParser.addArgument("scoreThreshold").nargs("?").type(String.class).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("predict")) { + predict( + projectId, + computeRegion, + ns.getString("modelId"), + ns.getString("filePath"), + ns.getString("scoreThreshold")); + } + } catch (ArgumentParserException e) { + parser.handleError(e); + } + } +} diff --git a/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/DatasetApiIT.java b/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/DatasetApiIT.java new file mode 100644 index 00000000000..1a45326169a --- /dev/null +++ b/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/DatasetApiIT.java @@ -0,0 +1,107 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.vision.samples.automl; + +import static com.google.common.truth.Truth.assertThat; +import static java.lang.Boolean.FALSE; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for Automl vision "Dataset API" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class DatasetApiIT { + + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String BUCKET = PROJECT_ID + "-vcm"; + private static final String COMPUTE_REGION = "us-central1"; + private static final String DATASET_NAME = "test_dataset"; + private ByteArrayOutputStream bout; + private PrintStream out; + private DatasetApi app; + private String datasetId; + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testCreateImportDeleteDataset() throws Exception { + // Act + DatasetApi.createDataset(PROJECT_ID, COMPUTE_REGION, DATASET_NAME, FALSE); + + // Assert + String got = bout.toString(); + datasetId = + bout.toString() + .split("\n")[0] + .split("/")[(bout.toString().split("\n")[0]).split("/").length - 1]; + assertThat(got).contains("Dataset id:"); + + // Act + DatasetApi.importData( + PROJECT_ID, COMPUTE_REGION, datasetId, "gs://" + BUCKET + "/flower_traindata.csv"); + + // Assert + got = bout.toString(); + assertThat(got).contains("Dataset id:"); + + // Act + DatasetApi.deleteDataset(PROJECT_ID, COMPUTE_REGION, datasetId); + + // Assert + got = bout.toString(); + assertThat(got).contains("Dataset deleted."); + } + + @Test + public void testListGetDatasets() throws Exception { + // Act + DatasetApi.listDatasets(PROJECT_ID, COMPUTE_REGION, "imageClassificationDatasetMetadata:*"); + + // Assert + String got = bout.toString(); + datasetId = + bout.toString() + .split("\n")[1] + .split("/")[(bout.toString().split("\n")[1]).split("/").length - 1]; + assertThat(got).contains("Dataset id:"); + + // Act + DatasetApi.getDataset(PROJECT_ID, COMPUTE_REGION, datasetId); + + // Assert + got = bout.toString(); + + assertThat(got).contains("Dataset id:"); + } +} diff --git a/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/ModelApiIT.java b/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/ModelApiIT.java new file mode 100644 index 00000000000..9dae82604a3 --- /dev/null +++ b/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/ModelApiIT.java @@ -0,0 +1,88 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.vision.samples.automl; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for vision "Model API" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class ModelApiIT { + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String COMPUTE_REGION = "us-central1"; + private ByteArrayOutputStream bout; + private PrintStream out; + private ModelApi app; + private String modelId; + private String modelEvaluationId; + + @Before + public void setUp() { + + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testModelApi() throws Exception { + // Act + ModelApi.listModels(PROJECT_ID, COMPUTE_REGION, ""); + + // Assert + String got = bout.toString(); + modelId = got.split("\n")[1].split("/")[got.split("\n")[1].split("/").length - 1]; + assertThat(got).contains("Model id:"); + + // Act + ModelApi.getModel(PROJECT_ID, COMPUTE_REGION, modelId); + + // Assert + got = bout.toString(); + assertThat(got).contains("Model name:"); + + // Act + ModelApi.listModelEvaluations(PROJECT_ID, COMPUTE_REGION, modelId, ""); + + // Assert + got = bout.toString(); + modelEvaluationId = got.split("List of model evaluations:")[1].split("\"")[1].split("/")[7]; + assertThat(got).contains("name:"); + + // Act + ModelApi.getModelEvaluation(PROJECT_ID, COMPUTE_REGION, modelId, modelEvaluationId); + + // Assert + got = bout.toString(); + assertThat(got).contains("name:"); + + } +} diff --git a/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/PredictionApiIT.java b/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/PredictionApiIT.java new file mode 100644 index 00000000000..db0e0401a01 --- /dev/null +++ b/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/PredictionApiIT.java @@ -0,0 +1,64 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.vision.samples.automl; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for vision "PredictionAPI" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class PredictionApiIT { + private static final String COMPUTE_REGION = "us-central1"; + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String modelId = "620201829169141520"; + private static final String filePath = "./resources/dandelion.jpg"; + private static final String scoreThreshold = "0.7"; + private ByteArrayOutputStream bout; + private PrintStream out; + private PredictionApi app; + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testPredict() throws Exception { + // Act + PredictionApi.predict(PROJECT_ID, COMPUTE_REGION, modelId, filePath, scoreThreshold); + + // Assert + String got = bout.toString(); + assertThat(got).contains("dandelion"); + } +} From 96bdd4902f3b54c8d78ea941853e0eec24e42f71 Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Sun, 22 Jul 2018 08:52:49 -0700 Subject: [PATCH 03/10] Vision AutoML updates + Translate AutoML --- translate/automl/README.md | 86 ++++++++++ translate/automl/pom.xml | 153 ++++++++++++++++++ translate/automl/resources/input.txt | 1 + .../cloud/vision/samples/automl/ModelApi.java | 22 ++- .../vision/samples/automl/PredictionApi.java | 2 +- 5 files changed, 251 insertions(+), 13 deletions(-) create mode 100644 translate/automl/README.md create mode 100644 translate/automl/pom.xml create mode 100644 translate/automl/resources/input.txt diff --git a/translate/automl/README.md b/translate/automl/README.md new file mode 100644 index 00000000000..83ccd3dc95e --- /dev/null +++ b/translate/automl/README.md @@ -0,0 +1,86 @@ +# AutoML Translate Sample + + +Open in Cloud Shell + +[Google Cloud Translate API][translate] provides feature AutoML. +This API is part of the larger collection of Cloud Machine Learning APIs. + +This sample Java application demonstrates how to access the Cloud Translate AutoML API +using the [Google Cloud Client Library for Java][google-cloud-java]. + +## Set the environment variables + +PROJECT_ID = [Id of the project] +REGION_NAME = [Region name] + +## Build the sample + +Install [Maven](http://maven.apache.org/). + +Build your project with: + +``` +mvn clean package +``` + +### Dataset API + +#### Create a new dataset +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.DatasetApi" -Dexec.args="create_dataset test_dataset" +``` + +#### List datasets +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.DatasetApi" -Dexec.args="list_datasets" +``` + +#### Get dataset +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.DatasetApi" -Dexec.args="get_dataset [dataset-id]" +``` + +#### Import data +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.DatasetApi" -Dexec.args="import_data gs://java-docs-samples-testing/flower_traindata.csv" +``` + +### Model API + +#### Create Model +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.ModelApi" -Dexec.args="create_model test_model" +``` + +#### List Models +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.ModelApi" -Dexec.args="list_models" +``` + +#### Get Model +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.ModelApi" -Dexec.args="get_model [model-id]" +``` + +#### List Model Evaluations +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.ModelApi" -Dexec.args="list_model_evaluation [model-id]" +``` + +#### Get Model Evaluation +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.ModelApi" -Dexec.args="get_model_evaluation [model-id] [model-evaluation-id]" +``` + +#### Delete Model +``` +mvn exec:java-Dexec.mainClass="com.google.cloud.translate.samples.ModelApi" -Dexec.args="delete_model [model-id]" +``` +### Predict API + +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.PredictApi" -Dexec.args="predict [model-id] ./resources/dandelion.jpg 0.7" +``` + + diff --git a/translate/automl/pom.xml b/translate/automl/pom.xml new file mode 100644 index 00000000000..488081b3fe2 --- /dev/null +++ b/translate/automl/pom.xml @@ -0,0 +1,153 @@ + + + 4.0.0 + com.google.cloud.translate.automl + translate-automl + jar + + + + com.google.cloud.samples + shared-configuration + 1.0.9 + + + + 1.8 + 1.8 + UTF-8 + + + + + + com.google.cloud + google-cloud-automl + 0.55.0-beta + + + net.sourceforge.argparse4j + argparse4j + 0.8.1 + + + + + + junit + junit + 4.12 + test + + + com.google.truth + truth + 0.41 + test + + + + + + DatasetApi + + + DatasetApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.translate.automl.DatasetApi + false + + + + + + + ModelApi + + + ModelApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.translate.automl.ModelApi + false + + + + + + + PredictionApi + + + PredictionApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.translate.automl.PredictionApi + false + + + + + + + diff --git a/translate/automl/resources/input.txt b/translate/automl/resources/input.txt new file mode 100644 index 00000000000..5aecd6590fc --- /dev/null +++ b/translate/automl/resources/input.txt @@ -0,0 +1 @@ +Tell me how this ends \ No newline at end of file diff --git a/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java index bcf913e1c4d..22e653cdd0f 100644 --- a/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java +++ b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java @@ -37,7 +37,7 @@ import java.io.IOException; import java.io.PrintStream; import java.util.List; -import java.util.concurrent.ExecutionException; + import net.sourceforge.argparse4j.ArgumentParsers; import net.sourceforge.argparse4j.inf.ArgumentParser; import net.sourceforge.argparse4j.inf.ArgumentParserException; @@ -106,7 +106,7 @@ public static void createModel( /** * Demonstrates using the AutoML client to get operation status. * - * @param operationFullId : Full name of a operation. For example, the name of your operation is + * @param operationFullId the complete name of a operation. For example, the name of your operation is * projects/[projectId]/locations/us-central1/operations/[operationId]. * @throws IOException on Input/Output errors. */ @@ -124,8 +124,8 @@ public static void getOperationStatus(String operationFullId) throws IOException /** * Demonstrates using the AutoML client to list all models. * - * @param projectId - Id of the project. - * @param computeRegion - Region name. + * @param projectId the Id of the project. + * @param computeRegion the Region name. * @param filter - Filter expression. * @throws IOException on Input/Output errors. */ @@ -137,14 +137,14 @@ public static void listModels(String projectId, String computeRegion, String fil LocationName projectLocation = LocationName.of(projectId, computeRegion); // Create list models request - ListModelsRequest listModlesRequest = + ListModelsRequest listModelsRequest = ListModelsRequest.newBuilder() .setParent(projectLocation.toString()) .setFilter(filter) .build(); System.out.println("List of models:"); - for (Model model : client.listModels(listModlesRequest).iterateAll()) { + for (Model model : client.listModels(listModelsRequest).iterateAll()) { // Display the model information. System.out.println(String.format("Model name: %s", model.getName())); System.out.println( @@ -278,7 +278,7 @@ public static void getModelEvaluation( * @param projectId the Id of the project. * @param computeRegion the Region name. * @param modelId the Id of the model. - * @param filter the Filter expression. + * @param filter the filter expression. * @throws IOException on Input/Output errors. */ public static void displayEvaluation( @@ -353,7 +353,7 @@ public static void displayEvaluation( * @throws Exception on AutoML Client errors */ public static void deleteModel(String projectId, String computeRegion, String modelId) - throws InterruptedException, ExecutionException, IOException { + throws Exception { AutoMlClient client = AutoMlClient.create(); // Get the full path of the model. @@ -367,13 +367,13 @@ public static void deleteModel(String projectId, String computeRegion, String mo // [END automl_vision_delete_model] public static void main(String[] args) - throws IOException, InterruptedException, ExecutionException { + throws Exception { ModelApi modelApi = new ModelApi(); modelApi.argsHelper(args, System.out); } public static void argsHelper(String[] args, PrintStream out) - throws IOException, InterruptedException, ExecutionException { + throws Exception { ArgumentParser parser = ArgumentParsers.newFor("ModelApi") .build() @@ -453,8 +453,6 @@ public static void argsHelper(String[] args, PrintStream out) } } catch (ArgumentParserException e) { parser.handleError(e); - } catch (Exception e) { - System.out.println("Exception in Model create caught"); } } } diff --git a/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/PredictionApi.java b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/PredictionApi.java index a6070ad31d9..a76c3f40caf 100644 --- a/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/PredictionApi.java +++ b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/PredictionApi.java @@ -75,7 +75,7 @@ public static void predict( String scoreThreshold) throws IOException { - // Create client for prediction service. + // Instantiate client for prediction service. PredictionServiceClient predictionClient = PredictionServiceClient.create(); // Get the full path of the model. From 0efcd8beaac14a85465753e0a630b7b3c776b31c Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Sun, 22 Jul 2018 08:57:47 -0700 Subject: [PATCH 04/10] Translate README fixes --- translate/automl/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translate/automl/README.md b/translate/automl/README.md index 83ccd3dc95e..e2248a17de7 100644 --- a/translate/automl/README.md +++ b/translate/automl/README.md @@ -43,7 +43,7 @@ mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.DatasetApi" - #### Import data ``` -mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.DatasetApi" -Dexec.args="import_data gs://java-docs-samples-testing/flower_traindata.csv" +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.DatasetApi" -Dexec.args="import_data gs://java-docs-samples-testing/en-ja.csv" ``` ### Model API @@ -80,7 +80,7 @@ mvn exec:java-Dexec.mainClass="com.google.cloud.translate.samples.ModelApi" -Dex ### Predict API ``` -mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.PredictApi" -Dexec.args="predict [model-id] ./resources/dandelion.jpg 0.7" +mvn exec:java -Dexec.mainClass="com.google.cloud.translate.samples.PredictApi" -Dexec.args="predict [model-id] ./resources/input.txt" ``` From 9150076c37c2f8ca90b6e70acc60f105df1f6baa Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Sun, 22 Jul 2018 09:09:24 -0700 Subject: [PATCH 05/10] Fixing Kokoro failure issue --- .../google/cloud/vision/samples/automl/ModelApi.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java index 22e653cdd0f..a0f6c7b002c 100644 --- a/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java +++ b/vision/automl/src/main/java/com/google/cloud/vision/samples/automl/ModelApi.java @@ -106,8 +106,8 @@ public static void createModel( /** * Demonstrates using the AutoML client to get operation status. * - * @param operationFullId the complete name of a operation. For example, the name of your operation is - * projects/[projectId]/locations/us-central1/operations/[operationId]. + * @param operationFullId the complete name of a operation. For example, the name of your + * operation is projects/[projectId]/locations/us-central1/operations/[operationId]. * @throws IOException on Input/Output errors. */ public static void getOperationStatus(String operationFullId) throws IOException { @@ -366,14 +366,12 @@ public static void deleteModel(String projectId, String computeRegion, String mo } // [END automl_vision_delete_model] - public static void main(String[] args) - throws Exception { + public static void main(String[] args) throws Exception { ModelApi modelApi = new ModelApi(); modelApi.argsHelper(args, System.out); } - public static void argsHelper(String[] args, PrintStream out) - throws Exception { + public static void argsHelper(String[] args, PrintStream out) throws Exception { ArgumentParser parser = ArgumentParsers.newFor("ModelApi") .build() From 3c7d7aa74f5986665cd063d21498d7d3e1e4d594 Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Sun, 22 Jul 2018 15:18:24 -0700 Subject: [PATCH 06/10] Language AutoML --- language/automl/README.md | 88 ++++ language/automl/pom.xml | 154 +++++++ language/automl/resources/input.txt | 1 + .../cloud/language/samples/DatasetApi.java | 349 ++++++++++++++ .../cloud/language/samples/ModelApi.java | 428 ++++++++++++++++++ .../cloud/language/samples/PredictionApi.java | 121 +++++ .../cloud/language/samples/DatasetApiIT.java | 108 +++++ .../cloud/language/samples/ModelApiIT.java | 92 ++++ .../language/samples/PredictionApiIT.java | 63 +++ 9 files changed, 1404 insertions(+) create mode 100644 language/automl/README.md create mode 100644 language/automl/pom.xml create mode 100644 language/automl/resources/input.txt create mode 100644 language/automl/src/main/java/com/google/cloud/language/samples/DatasetApi.java create mode 100644 language/automl/src/main/java/com/google/cloud/language/samples/ModelApi.java create mode 100644 language/automl/src/main/java/com/google/cloud/language/samples/PredictionApi.java create mode 100644 language/automl/src/test/java/com/google/cloud/language/samples/DatasetApiIT.java create mode 100644 language/automl/src/test/java/com/google/cloud/language/samples/ModelApiIT.java create mode 100644 language/automl/src/test/java/com/google/cloud/language/samples/PredictionApiIT.java diff --git a/language/automl/README.md b/language/automl/README.md new file mode 100644 index 00000000000..97e17bee204 --- /dev/null +++ b/language/automl/README.md @@ -0,0 +1,88 @@ +# AutoML Sample + + +Open in Cloud Shell + +[Google Cloud Natural Language API][language] provides feature detection for images. +This API is part of the larger collection of Cloud Machine Learning APIs. + +This sample Java application demonstrates how to access the Cloud Natural Language AutoML API +using the [Google Cloud Client Library for Java][google-cloud-java]. + +[language]: https://cloud.google.com/language/docs/ +[google-cloud-java]: https://github.com/GoogleCloudPlatform/google-cloud-java + +## Set the environment variables + +PROJECT_ID = [Id of the project] +REGION_NAME = [Region name] + +## Build the sample + +Install [Maven](http://maven.apache.org/). + +Build your project with: + +``` +mvn clean package +``` + +### Dataset API + +#### Create a new dataset +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.DatasetApi" -Dexec.args="create_dataset test_dataset" +``` + +#### List datasets +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.DatasetApi" -Dexec.args="list_datasets" +``` + +#### Get dataset +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.DatasetApi" -Dexec.args="get_dataset [dataset-id]" +``` + +#### Import data +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.DatasetApi" -Dexec.args="import_data gs://java-docs-samples-testing/happiness.csv" +``` + +### Model API + +#### Create Model +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.ModelApi" -Dexec.args="create_model test_model" +``` + +#### List Models +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.ModelApi" -Dexec.args="list_models" +``` + +#### Get Model +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.ModelApi" -Dexec.args="get_model [model-id]" +``` + +#### List Model Evaluations +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.ModelApi" -Dexec.args="list_model_evaluation [model-id]" +``` + +#### Get Model Evaluation +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.ModelApi" -Dexec.args="get_model_evaluation [model-id] [model-evaluation-id]" +``` + +#### Delete Model +``` +mvn exec:java-Dexec.mainClass="com.google.cloud.language.samples.ModelApi" -Dexec.args="delete_model [model-id]" +``` +### Predict API + +``` +mvn exec:java -Dexec.mainClass="com.google.cloud.language.samples.PredictApi" -Dexec.args="predict [model-id] ./resources/input.txt" +``` + diff --git a/language/automl/pom.xml b/language/automl/pom.xml new file mode 100644 index 00000000000..66f481dcf40 --- /dev/null +++ b/language/automl/pom.xml @@ -0,0 +1,154 @@ + + + 4.0.0 + com.example.vision + language-automl + jar + + + + com.google.cloud.samples + shared-configuration + 1.0.9 + + + + 1.8 + 1.8 + UTF-8 + + + + + + com.google.cloud + google-cloud-automl + 0.55.1-beta + + + net.sourceforge.argparse4j + argparse4j + 0.8.1 + + + + + + junit + junit + 4.12 + test + + + + com.google.truth + truth + 0.41 + test + + + + + + DatasetApi + + + DatasetApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.language.samples.DatasetApi + false + + + + + + + ModelApi + + + ModelApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.language.samples.ModelApi + false + + + + + + + PredictApi + + + PredictApi + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + + java + + + + + com.google.cloud.language.samples.PredictionApi + false + + + + + + + diff --git a/language/automl/resources/input.txt b/language/automl/resources/input.txt new file mode 100644 index 00000000000..a711059ba58 --- /dev/null +++ b/language/automl/resources/input.txt @@ -0,0 +1 @@ +creamy, full-flavored, nutty, sweet \ No newline at end of file diff --git a/language/automl/src/main/java/com/google/cloud/language/samples/DatasetApi.java b/language/automl/src/main/java/com/google/cloud/language/samples/DatasetApi.java new file mode 100644 index 00000000000..d7aa610f589 --- /dev/null +++ b/language/automl/src/main/java/com/google/cloud/language/samples/DatasetApi.java @@ -0,0 +1,349 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.language.samples; + +// Imports the Google Cloud client library +import com.google.cloud.automl.v1beta1.AutoMlClient; +import com.google.cloud.automl.v1beta1.ClassificationProto.ClassificationType; +import com.google.cloud.automl.v1beta1.Dataset; +import com.google.cloud.automl.v1beta1.DatasetName; +import com.google.cloud.automl.v1beta1.GcsDestination; +import com.google.cloud.automl.v1beta1.GcsSource; +import com.google.cloud.automl.v1beta1.InputConfig; +import com.google.cloud.automl.v1beta1.ListDatasetsRequest; +import com.google.cloud.automl.v1beta1.LocationName; +import com.google.cloud.automl.v1beta1.OutputConfig; +import com.google.cloud.automl.v1beta1.TextClassificationDatasetMetadata; +import com.google.protobuf.Empty; + +import java.io.IOException; +import java.io.PrintStream; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import net.sourceforge.argparse4j.inf.Subparsers; + +/** + * Google Cloud AutoML Natural Language API sample application. Example usage: mvn package exec:java + * -Dexec.mainClass ='com.google.cloud.vision.samples.automl.DatasetAPI' -Dexec.args='create_dataset + * test_dataset' + */ +public class DatasetApi { + + // [START automl_natural_language_create_dataset] + /** + * Demonstrates using the AutoML client to create a dataset + * + * @param projectId the Google Cloud Project ID. + * @param computeRegion the Region name. (e.g., "us-central1") + * @param datasetName the name of the dataset to be created. + * @param multiLabel the type of classification problem. Set to FALSE by default. False - + * MULTICLASS , True - MULTILABEL + * @throws IOException on Input/Output errors. + */ + public static void createDataset( + String projectId, String computeRegion, String datasetName, Boolean multiLabel) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Classification type assigned based on multilabel value. + ClassificationType classificationType = + multiLabel ? ClassificationType.MULTILABEL : ClassificationType.MULTICLASS; + + // Specify the text classification type for the dataset. + TextClassificationDatasetMetadata textClassificationDatasetMetadata = + TextClassificationDatasetMetadata.newBuilder() + .setClassificationType(classificationType) + .build(); + + // Set dataset name and dataset metadata. + Dataset myDataset = + Dataset.newBuilder() + .setDisplayName(datasetName) + .setTextClassificationDatasetMetadata(textClassificationDatasetMetadata) + .build(); + + // Create a dataset with the dataset metadata in the region. + Dataset dataset = client.createDataset(projectLocation, myDataset); + + // Display the dataset information. + System.out.println(String.format("Dataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Text classification dataset metadata:"); + System.out.print(String.format("\t%s", dataset.getTextClassificationDatasetMetadata())); + System.out.println(String.format("Dataset example count: %d", dataset.getExampleCount())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + // [END automl_natural_language_create_dataset] + + // [START automl_natural_language_list_datasets] + /** + * Demonstrates using the AutoML client to list all datasets. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param filter the Filter expression. + * @throws IOException on Input/Output errors. + */ + public static void listDatasets(String projectId, String computeRegion, String filter) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Build the List datasets request + ListDatasetsRequest request = + ListDatasetsRequest.newBuilder() + .setParent(projectLocation.toString()) + .setFilter(filter) + .build(); + + // List all the datasets available in the region by applying filter. + System.out.println("List of datasets:"); + for (Dataset dataset : client.listDatasets(request).iterateAll()) { + // Display the dataset information. + System.out.println(String.format("\nDataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Text classification dataset metadata:"); + System.out.print(String.format("\t%s", dataset.getTextClassificationDatasetMetadata())); + System.out.println(String.format("Dataset example count: %d", dataset.getExampleCount())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + } + // [END automl_natural_language_list_datasets] + + // [START automl_natural_language_get_dataset] + /** + * Demonstrates using the AutoML client to get a dataset by ID. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param datasetId the Id of the dataset. + * @throws IOException on Input/Output errors. + */ + public static void getDataset(String projectId, String computeRegion, String datasetId) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + // Get all the information about a given dataset. + Dataset dataset = client.getDataset(datasetFullId); + + // Display the dataset information. + System.out.println(String.format("Dataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Text classification dataset metadata:"); + System.out.print(String.format("\t%s", dataset.getTextClassificationDatasetMetadata())); + System.out.println(String.format("Dataset example count: %d", dataset.getExampleCount())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + // [END automl_natural_language_get_dataset] + + // [START automl_natural_language_import_data] + /** + * Import labeled items. + * + * @param projectId - Id of the project. + * @param computeRegion - Region name. + * @param datasetId - Id of the dataset into which the training content are to be imported. + * @param path - Google Cloud Storage URIs. Target files must be in AutoML Natural Language CSV + * format. + * @throws Exception on AutoML Client errors + */ + public static void importData( + String projectId, String computeRegion, String datasetId, String path) throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + GcsSource.Builder gcsSource = GcsSource.newBuilder(); + + // Get multiple training data files to be imported + String[] inputUris = path.split(","); + for (String inputUri : inputUris) { + gcsSource.addInputUris(inputUri); + } + + // Import data from the input URI + InputConfig inputConfig = InputConfig.newBuilder().setGcsSource(gcsSource).build(); + System.out.println("Processing import..."); + + Empty response = client.importDataAsync(datasetFullId, inputConfig).get(); + System.out.println(String.format("Dataset imported. %s", response)); + } + // [END automl_natural_language_import_data] + + // [START automl_natural_language_export_data] + /** + * Demonstrates using the AutoML client to export a dataset to a Google Cloud Storage bucket. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param datasetId the Id of the dataset. + * @param gcsUri the Destination URI (Google Cloud Storage) + * @throws Exception on AutoML Client errors + */ + public static void exportData( + String projectId, String computeRegion, String datasetId, String gcsUri) throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + // Set the output URI. + GcsDestination gcsDestination = GcsDestination.newBuilder().setOutputUriPrefix(gcsUri).build(); + + // Export the data to the output URI. + OutputConfig outputConfig = OutputConfig.newBuilder().setGcsDestination(gcsDestination).build(); + System.out.println(String.format("Processing export...")); + + Empty response = client.exportDataAsync(datasetFullId, outputConfig).get(); + System.out.println(String.format("Dataset exported. %s", response)); + } + // [END automl_natural_language_export_data] + + // [START automl_natural_language_delete_dataset] + /** + * Delete a dataset. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param datasetId the Id of the dataset. + * @throws Exception on AutoML Client errors + */ + public static void deleteDataset(String projectId, String computeRegion, String datasetId) + throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + // Delete a dataset. + Empty response = client.deleteDatasetAsync(datasetFullId).get(); + + System.out.println(String.format("Dataset deleted. %s", response)); + } + // [END automl_natural_language_delete_dataset] + + public static void main(String[] args) throws Exception { + DatasetApi datasetApi = new DatasetApi(); + datasetApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) throws Exception { + ArgumentParser parser = + ArgumentParsers.newFor("DatasetApi") + .build() + .defaultHelp(true) + .description("Dataset API operations."); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser createDatasetParser = subparsers.addParser("create_dataset"); + createDatasetParser.addArgument("datasetName"); + createDatasetParser + .addArgument("multiLabel") + .nargs("?") + .type(Boolean.class) + .choices(Boolean.FALSE, Boolean.TRUE) + .setDefault("False"); + + Subparser listDatasetsParser = subparsers.addParser("list_datasets"); + listDatasetsParser + .addArgument("filter") + .nargs("?") + .setDefault("textClassificationDatasetMetadata:*"); + + Subparser getDatasetParser = subparsers.addParser("get_dataset"); + getDatasetParser.addArgument("datasetId"); + + Subparser importDataParser = subparsers.addParser("import_data"); + importDataParser.addArgument("datasetId"); + importDataParser.addArgument("path"); + + Subparser exportDataParser = subparsers.addParser("export_data"); + exportDataParser.addArgument("datasetId"); + exportDataParser.addArgument("outputUri"); + + Subparser deleteDatasetParser = subparsers.addParser("delete_dataset"); + deleteDatasetParser.addArgument("datasetId"); + + 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("create_dataset")) { + createDataset( + projectId, computeRegion, ns.getString("datasetName"), ns.getBoolean("multiLabel")); + } + if (ns.get("command").equals("list_datasets")) { + listDatasets(projectId, computeRegion, ns.getString("filter")); + } + if (ns.get("command").equals("get_dataset")) { + getDataset(projectId, computeRegion, ns.getString("datasetId")); + } + if (ns.get("command").equals("import_data")) { + importData(projectId, computeRegion, ns.getString("datasetId"), ns.getString("path")); + } + if (ns.get("command").equals("export_data")) { + exportData(projectId, computeRegion, ns.getString("datasetId"), ns.getString("outputUri")); + } + if (ns.get("command").equals("delete_dataset")) { + deleteDataset(projectId, computeRegion, ns.getString("datasetId")); + } + + } catch (ArgumentParserException e) { + parser.handleError(e); + } + } +} diff --git a/language/automl/src/main/java/com/google/cloud/language/samples/ModelApi.java b/language/automl/src/main/java/com/google/cloud/language/samples/ModelApi.java new file mode 100644 index 00000000000..16b4841f290 --- /dev/null +++ b/language/automl/src/main/java/com/google/cloud/language/samples/ModelApi.java @@ -0,0 +1,428 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.language.samples; + +// Imports the Google Cloud client library +import com.google.api.gax.longrunning.OperationFuture; +import com.google.cloud.automl.v1beta1.AutoMlClient; +import com.google.cloud.automl.v1beta1.ClassificationProto.ClassificationEvaluationMetrics; +import com.google.cloud.automl.v1beta1.ClassificationProto.ClassificationEvaluationMetrics.ConfidenceMetricsEntry; +import com.google.cloud.automl.v1beta1.ListModelEvaluationsRequest; +import com.google.cloud.automl.v1beta1.ListModelsRequest; +import com.google.cloud.automl.v1beta1.LocationName; +import com.google.cloud.automl.v1beta1.Model; +import com.google.cloud.automl.v1beta1.ModelEvaluation; +import com.google.cloud.automl.v1beta1.ModelEvaluationName; +import com.google.cloud.automl.v1beta1.ModelName; +import com.google.cloud.automl.v1beta1.OperationMetadata; + +import com.google.cloud.automl.v1beta1.TextClassificationModelMetadata; +import com.google.longrunning.Operation; +import com.google.protobuf.Empty; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.List; +import java.util.concurrent.ExecutionException; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import net.sourceforge.argparse4j.inf.Subparsers; + +/** + * Google Cloud AutoML Natural Language API sample application. Example usage: mvn package exec:java + * -Dexec.mainClass ='com.google.cloud.vision.samples.automl.ModelApi' -Dexec.args='create_model + * [datasetId] test_model' + */ +public class ModelApi { + + // [START automl_natural_language_create_model] + /** + * Demonstrates using the AutoML client to create a model. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param dataSetId the Id of the dataset to which model is created. + * @param modelName the Name of the model. + * @throws Exception on AutoML Client errors + */ + public static void createModel( + String projectId, String computeRegion, String dataSetId, String modelName) + throws IOException, InterruptedException, ExecutionException { + + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Set model meta data + TextClassificationModelMetadata textClassificationModelMetadata = + TextClassificationModelMetadata.newBuilder().build(); + + // Set model name, dataset and metadata. + Model myModel = + Model.newBuilder() + .setDisplayName(modelName) + .setDatasetId(dataSetId) + .setTextClassificationModelMetadata(textClassificationModelMetadata) + .build(); + + // Create a model with the model metadata in the region. + OperationFuture response = + client.createModelAsync(projectLocation, myModel); + + System.out.println( + String.format("Training operation name: %s", response.getInitialFuture().get().getName())); + System.out.println("Training started..."); + } + // [END automl_natural_language_create_model] + + // [START automl_natural_language_get_operation_status] + /** + * Demonstrates using the AutoML client to get operation status. + * + * @param operationFullId the complete name of a operation. For example, the name of your + * operation is projects/[projectId]/locations/us-central1/operations/[operationId]. + * @throws IOException on Input/Output errors. + */ + public static void getOperationStatus(String operationFullId) throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the latest state of a long-running operation. + Operation response = client.getOperationsClient().getOperation(operationFullId); + + System.out.println(String.format("Operation status: %s", response)); + } + // [END automl_natural_language_get_operation_status] + + // [START automl_natural_language_list_models] + /** + * Demonstrates using the AutoML client to list all models. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param filter the filter expression. + * @throws IOException on Input/Output errors. + */ + public static void listModels(String projectId, String computeRegion, String filter) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Create list models request. + ListModelsRequest listModlesRequest = + ListModelsRequest.newBuilder() + .setParent(projectLocation.toString()) + .setFilter(filter) + .build(); + + System.out.println("List of models:"); + for (Model model : client.listModels(listModlesRequest).iterateAll()) { + // Display the model information. + System.out.println(String.format("Model name: %s", model.getName())); + System.out.println( + String.format( + "Model id: %s", model.getName().split("/")[model.getName().split("/").length - 1])); + System.out.println(String.format("Model display name: %s", model.getDisplayName())); + System.out.println("Model create time:"); + System.out.println(String.format("\tseconds: %s", model.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", model.getCreateTime().getNanos())); + System.out.println(String.format("Model deployment state: %s", model.getDeploymentState())); + } + } + // [END automl_natural_language_list_models] + + // [START automl_natural_language_get_model] + /** + * Demonstrates using the AutoML client to get model details. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @throws IOException on AutoML Client errors + */ + public static void getModel(String projectId, String computeRegion, String modelId) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Get complete detail of the model. + Model model = client.getModel(modelFullId); + + // Display the model information. + System.out.println(String.format("Model name: %s", model.getName())); + System.out.println( + String.format( + "Model id: %s", model.getName().split("/")[model.getName().split("/").length - 1])); + System.out.println(String.format("Model display name: %s", model.getDisplayName())); + System.out.println("Model create time:"); + System.out.println(String.format("\tseconds: %s", model.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", model.getCreateTime().getNanos())); + System.out.println(String.format("Model deployment state: %s", model.getDeploymentState())); + } + // END automl_natural_language_get_model] + + // [START automl_natural_language_list_model_evaluations] + /** + * Demonstrates using the AutoML client to list model evaluations. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @param filter the Filter expression. + * @throws IOException on Input/Output errors. + */ + public static void listModelEvaluations( + String projectId, String computeRegion, String modelId, String filter) throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Create list model evaluations request. + ListModelEvaluationsRequest modelEvaluationsRequest = + ListModelEvaluationsRequest.newBuilder() + .setParent(modelFullId.toString()) + .setFilter(filter) + .build(); + + // List all the model evaluations in the model by applying filter. + for (ModelEvaluation element : + client.listModelEvaluations(modelEvaluationsRequest).iterateAll()) { + System.out.println(element); + } + } + // [END automl_natural_language_list_model_evaluations] + + // [START automl_natural_language_get_model_evaluation] + /** + * Demonstrates using the AutoML client to get model evaluations. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @param modelEvaluationId the Id of your model evaluation. + * @throws IOException on Input/Output errors. + */ + public static void getModelEvaluation( + String projectId, String computeRegion, String modelId, String modelEvaluationId) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model evaluation. + ModelEvaluationName modelEvaluationFullId = + ModelEvaluationName.of(projectId, computeRegion, modelId, modelEvaluationId); + + // Get complete detail of the model evaluation. + ModelEvaluation response = client.getModelEvaluation(modelEvaluationFullId); + + System.out.println(response); + } + // [END automl_natural_language_get_model_evaluation] + + // [START automl_natural_language_display_evaluation] + /** + * Demonstrates using the AutoML client to display model evaluation. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @param filter the Filter expression. + * @throws IOException on Input/Output errors. + */ + public static void displayEvaluation( + String projectId, String computeRegion, String modelId, String filter) throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // List all the model evaluations in the model by applying. + ListModelEvaluationsRequest modelEvaluationsrequest = + ListModelEvaluationsRequest.newBuilder() + .setParent(modelFullId.toString()) + .setFilter(filter) + .build(); + + // Iterate through the results. + String modelEvaluationId = ""; + for (ModelEvaluation element : + client.listModelEvaluations(modelEvaluationsrequest).iterateAll()) { + if (element.getAnnotationSpecId() != null) { + modelEvaluationId = element.getName().split("/")[element.getName().split("/").length - 1]; + } + } + + // Resource name for the model evaluation. + ModelEvaluationName modelEvaluationFullId = + ModelEvaluationName.of(projectId, computeRegion, modelId, modelEvaluationId); + + // Get a model evaluation. + ModelEvaluation modelEvaluation = client.getModelEvaluation(modelEvaluationFullId); + + ClassificationEvaluationMetrics classMetrics = + modelEvaluation.getClassificationEvaluationMetrics(); + List confidenceMetricsEntries = + classMetrics.getConfidenceMetricsEntryList(); + + // Showing model score based on threshold of 0.5 + for (ConfidenceMetricsEntry confidenceMetricsEntry : confidenceMetricsEntries) { + if (confidenceMetricsEntry.getConfidenceThreshold() == 0.5) { + System.out.println("Precision and recall are based on a score threshold of 0.5"); + System.out.println( + String.format("Model Precision: %.2f ", confidenceMetricsEntry.getPrecision() * 100) + + '%'); + System.out.println( + String.format("Model Recall: %.2f ", confidenceMetricsEntry.getRecall() * 100) + '%'); + System.out.println( + String.format("Model F1 Score: %.2f ", confidenceMetricsEntry.getF1Score() * 100) + + '%'); + System.out.println( + String.format( + "Model Precision@1: %.2f ", confidenceMetricsEntry.getPrecisionAt1() * 100) + + '%'); + System.out.println( + String.format("Model Recall@1: %.2f ", confidenceMetricsEntry.getRecallAt1() * 100) + + '%'); + System.out.println( + String.format("Model F1 Score@1: %.2f ", confidenceMetricsEntry.getF1ScoreAt1() * 100) + + '%'); + } + } + } + // [END automl_natural_language_display_evaluation] + + // [START automl_natural_language_delete_model] + /** + * Demonstrates using the AutoML client to delete a model. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @throws Exception on AutoML Client errors + */ + public static void deleteModel(String projectId, String computeRegion, String modelId) + throws InterruptedException, ExecutionException, IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Delete a model. + Empty response = client.deleteModelAsync(modelFullId).get(); + + System.out.println("Model deletion started..."); + } + // [END automl_natural_language_delete_model] + + public static void main(String[] args) throws Exception { + ModelApi modelApi = new ModelApi(); + modelApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) throws Exception { + ArgumentParser parser = + ArgumentParsers.newFor("ModelApi") + .build() + .defaultHelp(true) + .description("Model API operations."); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser createModelParser = subparsers.addParser("create_model"); + createModelParser.addArgument("datasetId"); + createModelParser.addArgument("modelName"); + + Subparser listModelsParser = subparsers.addParser("list_models"); + listModelsParser + .addArgument("filter") + .nargs("?") + .setDefault("textClassificationModelMetadata:*"); + + Subparser getModelParser = subparsers.addParser("get_model"); + getModelParser.addArgument("modelId"); + + Subparser listModelEvaluationsParser = subparsers.addParser("list_model_evaluations"); + listModelEvaluationsParser.addArgument("modelId"); + listModelEvaluationsParser.addArgument("filter").nargs("?").setDefault(""); + + Subparser getModelEvaluationParser = subparsers.addParser("get_model_evaluation"); + getModelEvaluationParser.addArgument("modelId"); + getModelEvaluationParser.addArgument("modelEvaluationId"); + + Subparser displayEvaluationParser = subparsers.addParser("display_evaluation"); + displayEvaluationParser.addArgument("modelId"); + displayEvaluationParser.addArgument("filter").nargs("?").setDefault(""); + + Subparser deleteModelParser = subparsers.addParser("delete_model"); + deleteModelParser.addArgument("modelId"); + + Subparser getOperationStatusParser = subparsers.addParser("get_operation_status"); + getOperationStatusParser.addArgument("operationFullId"); + + 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("create_model")) { + createModel(projectId, computeRegion, ns.getString("datasetId"), ns.getString("modelName")); + } + if (ns.get("command").equals("list_models")) { + listModels(projectId, computeRegion, ns.getString("filter")); + } + if (ns.get("command").equals("get_model")) { + getModel(projectId, computeRegion, ns.getString("modelId")); + } + if (ns.get("command").equals("list_model_evaluations")) { + listModelEvaluations( + projectId, computeRegion, ns.getString("modelId"), ns.getString("filter")); + } + if (ns.get("command").equals("get_model_evaluation")) { + getModelEvaluation( + projectId, computeRegion, ns.getString("modelId"), ns.getString("modelEvaluationId")); + } + if (ns.get("command").equals("delete_model")) { + deleteModel(projectId, computeRegion, ns.getString("modelId")); + } + if (ns.get("command").equals("get_operation_status")) { + getOperationStatus(ns.getString("operationFullId")); + } + if (ns.get("command").equals("display_evaluation")) { + displayEvaluation( + projectId, computeRegion, ns.getString("modelId"), ns.getString("filter")); + } + + } catch (ArgumentParserException e) { + parser.handleError(e); + } + } +} diff --git a/language/automl/src/main/java/com/google/cloud/language/samples/PredictionApi.java b/language/automl/src/main/java/com/google/cloud/language/samples/PredictionApi.java new file mode 100644 index 00000000000..b374deded7e --- /dev/null +++ b/language/automl/src/main/java/com/google/cloud/language/samples/PredictionApi.java @@ -0,0 +1,121 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.language.samples; + +// Imports the Google Cloud client library +import com.google.cloud.automl.v1beta1.AnnotationPayload; +import com.google.cloud.automl.v1beta1.ExamplePayload; +import com.google.cloud.automl.v1beta1.ModelName; +import com.google.cloud.automl.v1beta1.PredictResponse; +import com.google.cloud.automl.v1beta1.PredictionServiceClient; +import com.google.cloud.automl.v1beta1.TextSnippet; + +import java.io.IOException; +import java.io.PrintStream; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import net.sourceforge.argparse4j.inf.Subparsers; + +/** + * Google Cloud AutoML Natural Language API sample application. Example usage: mvn package exec:java + * -Dexec.mainClass ='com.google.cloud.vision.samples.automl.PredictionApi' -Dexec.args='predict + * [modelId] [path-to-text-file] [scoreThreshold]' + */ +public class PredictionApi { + + // [START automl_natural_language_predict] + /** + * Demonstrates using the AutoML client to classify the text content + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model which will be used for text classification. + * @param filePath the Local text file path of the content to be classified. + * @throws IOException on Input/Output errors. + */ + public static void predict( + String projectId, String computeRegion, String modelId, String filePath) throws IOException { + + // Create client for prediction service. + PredictionServiceClient predictionClient = PredictionServiceClient.create(); + + // Get full path of model + ModelName name = ModelName.of(projectId, computeRegion, modelId); + + // Read the file content for prediction. + String content = new String(Files.readAllBytes(Paths.get(filePath))); + + // Set the payload by giving the content and type of the file. + TextSnippet textSnippet = + TextSnippet.newBuilder().setContent(content).setMimeType("text/plain").build(); + ExamplePayload payload = ExamplePayload.newBuilder().setTextSnippet(textSnippet).build(); + + // params is additional domain-specific parameters. + // currently there is no additional parameters supported. + Map params = new HashMap(); + PredictResponse response = predictionClient.predict(name, payload, params); + + System.out.println("Prediction results:"); + for (AnnotationPayload annotationPayload : response.getPayloadList()) { + System.out.println("Predicted Class name :" + annotationPayload.getDisplayName()); + System.out.println( + "Predicted Class Score :" + annotationPayload.getClassification().getScore()); + } + } + // [END automl_natural_language_predict] + + public static void main(String[] args) throws IOException { + PredictionApi predictionApi = new PredictionApi(); + predictionApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) throws IOException { + ArgumentParser parser = + ArgumentParsers.newFor("PredictionApi") + .build() + .defaultHelp(true) + .description("Prediction API Operation"); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser predictParser = subparsers.addParser("predict"); + predictParser.addArgument("modelId"); + predictParser.addArgument("filePath"); + + 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("predict")) { + predict(projectId, computeRegion, ns.getString("modelId"), ns.getString("filePath")); + } + + } catch (ArgumentParserException e) { + parser.handleError(e); + } + } +} diff --git a/language/automl/src/test/java/com/google/cloud/language/samples/DatasetApiIT.java b/language/automl/src/test/java/com/google/cloud/language/samples/DatasetApiIT.java new file mode 100644 index 00000000000..1b43dd04055 --- /dev/null +++ b/language/automl/src/test/java/com/google/cloud/language/samples/DatasetApiIT.java @@ -0,0 +1,108 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.language.samples; + +import static com.google.common.truth.Truth.assertThat; +import static java.lang.Boolean.FALSE; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for Automl natural language "Dataset API" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class DatasetApiIT { + + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String BUCKET = PROJECT_ID + "-vcm"; + private static final String COMPUTE_REGION = "us-central1"; + private static final String DATASET_NAME = "test_dataset"; + private ByteArrayOutputStream bout; + private PrintStream out; + private DatasetApi app; + private String datasetId; + private String getdatasetId = "8477830379477056918"; + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testCreateImportDeleteDataset() throws Exception { + // Act + DatasetApi.createDataset(PROJECT_ID, COMPUTE_REGION, DATASET_NAME, FALSE); + + // Assert + String got = bout.toString(); + datasetId = + bout.toString() + .split("\n")[0] + .split("/")[(bout.toString().split("\n")[0]).split("/").length - 1]; + assertThat(got).contains("Dataset id:"); + + // Act + DatasetApi.importData( + PROJECT_ID, COMPUTE_REGION, datasetId, "gs://" + BUCKET + "/happiness.csv"); + + // Assert + got = bout.toString(); + assertThat(got).contains("Dataset id:"); + + // Act + DatasetApi.deleteDataset(PROJECT_ID, COMPUTE_REGION, datasetId); + + // Assert + got = bout.toString(); + assertThat(got).contains("Dataset deleted."); + } + + @Test + public void testListDatasets() throws Exception { + // Act + DatasetApi.listDatasets(PROJECT_ID, COMPUTE_REGION, ""); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Dataset id:"); + } + + @Test + public void testGetDataset() throws Exception { + + // Act + DatasetApi.getDataset(PROJECT_ID, COMPUTE_REGION, getdatasetId); + + // Assert + String got = bout.toString(); + + assertThat(got).contains("Dataset id:"); + } +} diff --git a/language/automl/src/test/java/com/google/cloud/language/samples/ModelApiIT.java b/language/automl/src/test/java/com/google/cloud/language/samples/ModelApiIT.java new file mode 100644 index 00000000000..c142c3ef5b2 --- /dev/null +++ b/language/automl/src/test/java/com/google/cloud/language/samples/ModelApiIT.java @@ -0,0 +1,92 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.language.samples; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for vision "Model API" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class ModelApiIT { + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String COMPUTE_REGION = "us-central1"; + private ByteArrayOutputStream bout; + private PrintStream out; + private ModelApi app; + private String modelId; + private String modelIdGetevaluation = "342705131419266916"; + private String modelEvaluationId = "3666189665418739402"; + + @Before + public void setUp() { + + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testModelApi() throws Exception { + // Act + ModelApi.listModels(PROJECT_ID, COMPUTE_REGION, ""); + + // Assert + String got = bout.toString(); + modelId = got.split("\n")[1].split("/")[got.split("\n")[1].split("/").length - 1]; + assertThat(got).contains("Model id:"); + + // Act + ModelApi.getModel(PROJECT_ID, COMPUTE_REGION, modelId); + + // Assert + got = bout.toString(); + assertThat(got).contains("Model name:"); + + // Act + ModelApi.listModelEvaluations(PROJECT_ID, COMPUTE_REGION, modelId, ""); + + // Assert + got = bout.toString(); + assertThat(got).contains("name:"); + } + + @Test + public void testGetModelEvaluation() throws Exception { + + // Act + ModelApi.getModelEvaluation( + PROJECT_ID, COMPUTE_REGION, modelIdGetevaluation, modelEvaluationId); + + // Assert + String got = bout.toString(); + assertThat(got).contains("name:"); + } +} diff --git a/language/automl/src/test/java/com/google/cloud/language/samples/PredictionApiIT.java b/language/automl/src/test/java/com/google/cloud/language/samples/PredictionApiIT.java new file mode 100644 index 00000000000..3549eb244ee --- /dev/null +++ b/language/automl/src/test/java/com/google/cloud/language/samples/PredictionApiIT.java @@ -0,0 +1,63 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.language.samples; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for vision "PredictionAPI" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class PredictionApiIT { + private static final String COMPUTE_REGION = "us-central1"; + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String modelId = "342705131419266916"; + private static final String filePath = "./resources/input.txt"; + private ByteArrayOutputStream bout; + private PrintStream out; + private PredictionApi app; + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testPredict() throws Exception { + // Act + PredictionApi.predict(PROJECT_ID, COMPUTE_REGION, modelId, filePath); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Prediction results:"); + } +} From a2a6d91ca1612985414baf1b49faf3a5c5061430 Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Mon, 23 Jul 2018 15:25:26 -0700 Subject: [PATCH 07/10] Vision AutoML --- .../cloud/translate/automl/DatasetApiIT.java | 107 ++++++++++++++++++ .../cloud/translate/automl/ModelApiIT.java | 89 +++++++++++++++ .../translate/automl/PredictionApiIT.java | 64 +++++++++++ 3 files changed, 260 insertions(+) create mode 100644 translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java create mode 100644 translate/automl/src/test/java/com/google/cloud/translate/automl/ModelApiIT.java create mode 100644 translate/automl/src/test/java/com/google/cloud/translate/automl/PredictionApiIT.java diff --git a/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java b/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java new file mode 100644 index 00000000000..7ceda3e4445 --- /dev/null +++ b/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java @@ -0,0 +1,107 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.translate.automl; + +import static com.google.common.truth.Truth.assertThat; +import static java.lang.Boolean.FALSE; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for Automl translation "Dataset API" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class DatasetApiIT { + + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String BUCKET = PROJECT_ID + "-vcm"; + private static final String COMPUTE_REGION = "us-central1"; + private static final String DATASET_NAME = "test_dataset"; + private ByteArrayOutputStream bout; + private PrintStream out; + private DatasetApi app; + private String datasetId; + private String getdatasetId = "3946265060617537378"; + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testCreateImportDeleteDataset() throws Exception { + // Act + DatasetApi.createDataset(PROJECT_ID, COMPUTE_REGION, DATASET_NAME, "en", "ja"); + + // Assert + String got = bout.toString(); + datasetId = + bout.toString() + .split("\n")[0] + .split("/")[(bout.toString().split("\n")[0]).split("/").length - 1]; + assertThat(got).contains("Dataset id:"); + + // Act + DatasetApi.importData(PROJECT_ID, COMPUTE_REGION, datasetId, "gs://" + BUCKET + "/en-ja.csv"); + + // Assert + got = bout.toString(); + assertThat(got).contains("Dataset id:"); + + // Act + DatasetApi.deleteDataset(PROJECT_ID, COMPUTE_REGION, datasetId); + + // Assert + got = bout.toString(); + assertThat(got).contains("Dataset deleted."); + } + + @Test + public void testListDataset() throws Exception { + // Act + DatasetApi.listDatasets(PROJECT_ID, COMPUTE_REGION, "translation_dataset_metadata:*"); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Dataset id:"); + } + + @Test + public void testGetDataset() throws Exception { + + // Act + DatasetApi.getDataset(PROJECT_ID, COMPUTE_REGION, getdatasetId); + + // Assert + String got = bout.toString(); + + assertThat(got).contains("Dataset id:"); + } +} diff --git a/translate/automl/src/test/java/com/google/cloud/translate/automl/ModelApiIT.java b/translate/automl/src/test/java/com/google/cloud/translate/automl/ModelApiIT.java new file mode 100644 index 00000000000..0ebfeed339b --- /dev/null +++ b/translate/automl/src/test/java/com/google/cloud/translate/automl/ModelApiIT.java @@ -0,0 +1,89 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.translate.automl; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for translation "Model API" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class ModelApiIT { + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String COMPUTE_REGION = "us-central1"; + private ByteArrayOutputStream bout; + private PrintStream out; + private ModelApi app; + private String modelId; + private String modelEvaluationId; + + @Before + public void setUp() { + + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testModelApi() throws Exception { + // Act + ModelApi.listModels(PROJECT_ID, COMPUTE_REGION, ""); + + // Assert + String got = bout.toString(); + modelId = got.split("\n")[1].split("/")[got.split("\n")[1].split("/").length - 1]; + assertThat(got).contains("Model id:"); + + // Act + ModelApi.getModel(PROJECT_ID, COMPUTE_REGION, modelId); + + // Assert + got = bout.toString(); + assertThat(got).contains("Model name:"); + + // Act + ModelApi.listModelEvaluations(PROJECT_ID, COMPUTE_REGION, modelId, ""); + + // Assert + got = bout.toString(); + modelEvaluationId = got.split("List of model evaluations:")[1].split("\"")[1].split("/")[7]; + assertThat(got).contains("name:"); + + // Act + ModelApi.getModelEvaluation(PROJECT_ID, COMPUTE_REGION, modelId, modelEvaluationId); + + // Assert + got = bout.toString(); + assertThat(got).contains("name:"); + + } +} + diff --git a/translate/automl/src/test/java/com/google/cloud/translate/automl/PredictionApiIT.java b/translate/automl/src/test/java/com/google/cloud/translate/automl/PredictionApiIT.java new file mode 100644 index 00000000000..962a0fd0802 --- /dev/null +++ b/translate/automl/src/test/java/com/google/cloud/translate/automl/PredictionApiIT.java @@ -0,0 +1,64 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.translate.automl; + +import static com.google.common.truth.Truth.assertThat; +import static java.lang.Boolean.FALSE; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests for translation "PredictionAPI" sample. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class PredictionApiIT { + private static final String COMPUTE_REGION = "us-central1"; + private static final String PROJECT_ID = "java-docs-samples-testing"; + private static final String modelId = "2188848820815848149"; + private static final String filePath = "./resources/input.txt"; + private ByteArrayOutputStream bout; + private PrintStream out; + private PredictionApi app; + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + out = new PrintStream(bout); + System.setOut(out); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testPredict() throws Exception { + // Act + PredictionApi.predict(PROJECT_ID, COMPUTE_REGION, modelId, filePath,FALSE); + + // Assert + String got = bout.toString(); + assertThat(got).contains("Translated Content"); + } +} From d9216d5f27d49e42bab2c980879ffc72a66616d6 Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Mon, 23 Jul 2018 16:04:13 -0700 Subject: [PATCH 08/10] Translate AutoML files added --- .../cloud/translate/automl/DatasetApi.java | 314 ++++++++++++++++ .../cloud/translate/automl/ModelApi.java | 341 ++++++++++++++++++ .../cloud/translate/automl/PredictionApi.java | 140 +++++++ 3 files changed, 795 insertions(+) create mode 100644 translate/automl/src/main/java/com/google/cloud/translate/automl/DatasetApi.java create mode 100644 translate/automl/src/main/java/com/google/cloud/translate/automl/ModelApi.java create mode 100644 translate/automl/src/main/java/com/google/cloud/translate/automl/PredictionApi.java diff --git a/translate/automl/src/main/java/com/google/cloud/translate/automl/DatasetApi.java b/translate/automl/src/main/java/com/google/cloud/translate/automl/DatasetApi.java new file mode 100644 index 00000000000..03cc96aa45f --- /dev/null +++ b/translate/automl/src/main/java/com/google/cloud/translate/automl/DatasetApi.java @@ -0,0 +1,314 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.translate.automl; + +// Imports the Google Cloud client library +import com.google.cloud.automl.v1beta1.AutoMlClient; +import com.google.cloud.automl.v1beta1.Dataset; +import com.google.cloud.automl.v1beta1.DatasetName; +import com.google.cloud.automl.v1beta1.GcsSource; +import com.google.cloud.automl.v1beta1.GcsSource.Builder; +import com.google.cloud.automl.v1beta1.InputConfig; +import com.google.cloud.automl.v1beta1.ListDatasetsRequest; +import com.google.cloud.automl.v1beta1.LocationName; +import com.google.cloud.automl.v1beta1.TranslationDatasetMetadata; +import com.google.protobuf.Empty; + +import java.io.IOException; +import java.io.PrintStream; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import net.sourceforge.argparse4j.inf.Subparsers; + +/** + * Google Cloud AutoML Translate API sample application. Example usage: mvn package exec:java + * -Dexec.mainClass ='com.google.cloud.translate.samples.DatasetAPI' -Dexec.args='create_dataset + * test_dataset' + */ +public class DatasetApi { + + // [START automl_translate_create_dataset] + /** + * Demonstrates using the AutoML client to create a dataset + * + * @param projectId the Google Cloud Project ID. + * @param computeRegion the Region name. (e.g., "us-central1"). + * @param datasetName the name of the dataset to be created. + * @param source the Source language + * @param target the Target language + * @throws IOException on Input/Output errors. + */ + public static void createDataset( + String projectId, String computeRegion, String datasetName, String source, String target) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Specify the source and target language. + TranslationDatasetMetadata translationDatasetMetadata = + TranslationDatasetMetadata.newBuilder() + .setSourceLanguageCode(source) + .setTargetLanguageCode(target) + .build(); + + // Set dataset name and dataset metadata. + Dataset myDataset = + Dataset.newBuilder() + .setDisplayName(datasetName) + .setTranslationDatasetMetadata(translationDatasetMetadata) + .build(); + + // Create a dataset with the dataset metadata in the region. + Dataset dataset = client.createDataset(projectLocation, myDataset); + + // Display the dataset information. + System.out.println(String.format("Dataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Translation dataset Metadata:"); + System.out.println( + String.format( + "\tSource language code: %s", + dataset.getTranslationDatasetMetadata().getSourceLanguageCode())); + System.out.println( + String.format( + "\tTarget language code: %s", + dataset.getTranslationDatasetMetadata().getTargetLanguageCode())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + // [END automl_translation_create_dataset] + + // [START automl_translation_list_datasets] + /** + * Demonstrates using the AutoML client to list all datasets. + * + * @param projectId the Google Cloud Project ID. + * @param computeRegion the Region name. (e.g., "us-central1"). + * @param filter the Filter expression. + * @throws Exception on AutoML Client errors + */ + public static void listDatasets(String projectId, String computeRegion, String filter) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + ListDatasetsRequest request = + ListDatasetsRequest.newBuilder() + .setParent(projectLocation.toString()) + .setFilter(filter) + .build(); + + // List all the datasets available in the region by applying filter. + System.out.println("List of datasets:"); + for (Dataset dataset : client.listDatasets(request).iterateAll()) { + // Display the dataset information + System.out.println(String.format("\nDataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Translation dataset metadata:"); + System.out.println( + String.format( + "\tSource language code: %s", + dataset.getTranslationDatasetMetadata().getSourceLanguageCode())); + System.out.println( + String.format( + "\tTarget language code: %s", + dataset.getTranslationDatasetMetadata().getTargetLanguageCode())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + } + // [END automl_translation_list_datasets] + + // [START automl_translation_get_dataset] + /** + * Demonstrates using the AutoML client to get a dataset by ID. + * + * @param projectId the Google Cloud Project ID. + * @param computeRegion the Region name. (e.g., "us-central1"). + * @param datasetId the Id of the dataset. + * @throws Exception on AutoML Client errors + */ + public static void getDataset(String projectId, String computeRegion, String datasetId) + throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + // Get all the information about a given dataset. + Dataset dataset = client.getDataset(datasetFullId); + + // Display the dataset information + System.out.println(String.format("Dataset name: %s", dataset.getName())); + System.out.println( + String.format( + "Dataset id: %s", + dataset.getName().split("/")[dataset.getName().split("/").length - 1])); + System.out.println(String.format("Dataset display name: %s", dataset.getDisplayName())); + System.out.println("Translation dataset metadata:"); + System.out.println( + String.format( + "\tSource language code: %s", + dataset.getTranslationDatasetMetadata().getSourceLanguageCode())); + System.out.println( + String.format( + "\tTarget language code: %s", + dataset.getTranslationDatasetMetadata().getTargetLanguageCode())); + System.out.println("Dataset create time:"); + System.out.println(String.format("\tseconds: %s", dataset.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", dataset.getCreateTime().getNanos())); + } + // [END automl_translation_get_dataset] + + // [START automl_translation_import_data] + /** + * Import sentence pairs to the dataset. + * + * @param projectId the Google Cloud Project ID. + * @param computeRegion the Region name. (e.g., "us-central1"). + * @param datasetId the Id of the dataset. + * @param path the remote Path of the training data csv file. + * @throws Exception on AutoML Client errors + */ + public static void importData( + String projectId, String computeRegion, String datasetId, String path) throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the complete path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + Builder gcsSource = GcsSource.newBuilder(); + + // Get multiple Google Cloud Storage URIs to import data from + String[] inputUris = path.split(","); + for (String inputUri : inputUris) { + gcsSource.addInputUris(inputUri); + } + + // Import data from the input URI + InputConfig inputConfig = InputConfig.newBuilder().setGcsSource(gcsSource).build(); + System.out.println("Processing import..."); + + Empty response = client.importDataAsync(datasetFullId, inputConfig).get(); + System.out.println(String.format("Dataset imported. %s", response)); + } + // [END automl_translation_import_data] + + // [START automl_translation_delete_dataset] + /** + * Delete a dataset. + * + * @param projectId the Google Cloud Project ID. + * @param computeRegion the Region name. (e.g., "us-central1"). + * @param datasetId the Id of the dataset. + * @throws Exception on AutoML Client errors + */ + public static void deleteDataset(String projectId, String computeRegion, String datasetId) + throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the dataset. + DatasetName datasetFullId = DatasetName.of(projectId, computeRegion, datasetId); + + // Delete a dataset. + Empty response = client.deleteDatasetAsync(datasetFullId).get(); + + System.out.println(String.format("Dataset deleted. %s", response)); + } + // [END automl_translation_delete_dataset] + + public static void main(String[] args) throws Exception { + DatasetApi datasetApi = new DatasetApi(); + datasetApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) throws Exception { + ArgumentParser parser = ArgumentParsers.newFor("").build(); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser createDatasetParser = subparsers.addParser("create_dataset"); + createDatasetParser.addArgument("datasetName"); + createDatasetParser.addArgument("source"); + createDatasetParser.addArgument("target"); + + Subparser listDatasetParser = subparsers.addParser("list_datasets"); + listDatasetParser.addArgument("filter").nargs("?").setDefault("translation_dataset_metadata:*"); + + Subparser getDatasetParser = subparsers.addParser("get_dataset"); + getDatasetParser.addArgument("datasetId"); + + Subparser importDataParser = subparsers.addParser("import_data"); + importDataParser.addArgument("datasetId"); + importDataParser.addArgument("path"); + + Subparser deleteDatasetParser = subparsers.addParser("delete_dataset"); + deleteDatasetParser.addArgument("datasetId"); + + 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("create_dataset")) { + createDataset( + projectId, + computeRegion, + ns.getString("datasetName"), + ns.getString("source"), + ns.getString("target")); + } + if (ns.get("command").equals("list_datasets")) { + listDatasets(projectId, computeRegion, ns.getString("filter")); + } + if (ns.get("command").equals("get_dataset")) { + getDataset(projectId, computeRegion, ns.getString("datasetId")); + } + if (ns.get("command").equals("import_data")) { + importData(projectId, computeRegion, ns.getString("datasetId"), ns.getString("path")); + } + if (ns.get("command").equals("delete_dataset")) { + deleteDataset(projectId, computeRegion, ns.getString("datasetId")); + } + } catch (ArgumentParserException e) { + parser.handleError(e); + } + } +} diff --git a/translate/automl/src/main/java/com/google/cloud/translate/automl/ModelApi.java b/translate/automl/src/main/java/com/google/cloud/translate/automl/ModelApi.java new file mode 100644 index 00000000000..c720c3d5f40 --- /dev/null +++ b/translate/automl/src/main/java/com/google/cloud/translate/automl/ModelApi.java @@ -0,0 +1,341 @@ +/* + * Copyright 2018 Google Inc. + * + * 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.google.cloud.translate.automl; + +// Imports the Google Cloud client library +import com.google.api.gax.longrunning.OperationFuture; +import com.google.cloud.automl.v1beta1.AutoMlClient; +import com.google.cloud.automl.v1beta1.ListModelEvaluationsRequest; +import com.google.cloud.automl.v1beta1.ListModelsRequest; +import com.google.cloud.automl.v1beta1.LocationName; +import com.google.cloud.automl.v1beta1.Model; +import com.google.cloud.automl.v1beta1.ModelEvaluation; +import com.google.cloud.automl.v1beta1.ModelEvaluationName; +import com.google.cloud.automl.v1beta1.ModelName; +import com.google.cloud.automl.v1beta1.OperationMetadata; +import com.google.cloud.automl.v1beta1.TranslationModelMetadata; +import com.google.longrunning.Operation; +import com.google.protobuf.Empty; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.concurrent.ExecutionException; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import net.sourceforge.argparse4j.inf.Subparsers; + +/** + * Google Cloud AutoML Translate API sample application. Example usage: mvn package exec:java + * -Dexec.mainClass ='com.example.translate.ModelApi' -Dexec.args='create_model [datasetId] + * test_model' + */ +public class ModelApi { + + // [START automl_translation_create_model] + /** + * Demonstrates using the AutoML client to create a model. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param dataSetId the Id of the dataset to which model is created. + * @param modelName the Name of the model. + * @throws Exception on AutoML Client errors + */ + public static void createModel( + String projectId, String computeRegion, String dataSetId, String modelName) throws Exception { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Set model metadata. + TranslationModelMetadata translationModelMetadata = + TranslationModelMetadata.newBuilder().setBaseModel("").build(); + + // Set model name, dataset and metadata. + Model myModel = + Model.newBuilder() + .setDisplayName(modelName) + .setDatasetId(dataSetId) + .setTranslationModelMetadata(translationModelMetadata) + .build(); + + // Create a model with the model metadata in the region. + OperationFuture response = + client.createModelAsync(projectLocation, myModel); + + System.out.println( + String.format("Training operation name: %s", response.getInitialFuture().get().getName())); + System.out.println("Training started..."); + } + // [END automl_translation_create_model] + + // [START automl_translation_list_models] + /** + * Demonstrates using the AutoML client to list all models. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param filter the filter expression. + * @throws IOException on Input/Output errors. + */ + public static void listModels(String projectId, String computeRegion, String filter) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // A resource that represents Google Cloud Platform location. + LocationName projectLocation = LocationName.of(projectId, computeRegion); + + // Create list models request. + ListModelsRequest listModlesRequest = + ListModelsRequest.newBuilder() + .setParent(projectLocation.toString()) + .setFilter(filter) + .build(); + + // List all the models available in the region by applying filter. + System.out.println("List of models:"); + for (Model model : client.listModels(listModlesRequest).iterateAll()) { + // Display the model information. + System.out.println(String.format("Model name: %s", model.getName())); + System.out.println( + String.format( + "Model id: %s", model.getName().split("/")[model.getName().split("/").length - 1])); + System.out.println(String.format("Model display name: %s", model.getDisplayName())); + System.out.println("Model create time:"); + System.out.println(String.format("\tseconds: %s", model.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", model.getCreateTime().getNanos())); + System.out.println(String.format("Model deployment state: %s", model.getDeploymentState())); + } + } + // [END automl_translation_list_models] + + // [START automl_translation_get_model] + /** + * Demonstrates using the AutoML client to get model details. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @throws IOException on Input/Output errors. + */ + public static void getModel(String projectId, String computeRegion, String modelId) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Get complete detail of the model. + Model model = client.getModel(modelFullId); + + // Display the model information. + System.out.println(String.format("Model name: %s", model.getName())); + System.out.println( + String.format( + "Model id: %s", model.getName().split("/")[model.getName().split("/").length - 1])); + System.out.println(String.format("Model display name: %s", model.getDisplayName())); + System.out.println("Model create time:"); + System.out.println(String.format("\tseconds: %s", model.getCreateTime().getSeconds())); + System.out.println(String.format("\tnanos: %s", model.getCreateTime().getNanos())); + System.out.println(String.format("Model deployment state: %s", model.getDeploymentState())); + } + // [END automl_translation_get_model] + + // [START automl_translation_list_model_evaluations] + /** + * Demonstrates using the AutoML client to list model evaluations. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @param filter the filter expression. + * @throws IOException on Input/Output errors. + */ + public static void listModelEvaluations( + String projectId, String computeRegion, String modelId, String filter) throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Create list model evaluations request + ListModelEvaluationsRequest modelEvaluationsrequest = + ListModelEvaluationsRequest.newBuilder() + .setParent(modelFullId.toString()) + .setFilter(filter) + .build(); + + // List all the model evaluations in the model by applying filter. + System.out.println("List of model evaluations:"); + for (ModelEvaluation element : + client.listModelEvaluations(modelEvaluationsrequest).iterateAll()) { + System.out.println(element); + } + } + // [END automl_translation_list_model_evaluations] + + // [START automl_translation_get_model_evaluation] + /** + * Demonstrates using the AutoML client to get model evaluations. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @param modelEvaluationId the Id of your model evaluation. + * @throws IOException on Input/Output errors. + */ + public static void getModelEvaluation( + String projectId, String computeRegion, String modelId, String modelEvaluationId) + throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model evaluation. + ModelEvaluationName modelEvaluationFullId = + ModelEvaluationName.of(projectId, computeRegion, modelId, modelEvaluationId); + + // Get complete detail of the model evaluation. + ModelEvaluation response = client.getModelEvaluation(modelEvaluationFullId); + + System.out.println(response); + } + // [END automl_translation_get_model_evaluation] + + // [START automl_translation_delete_model] + /** + * Demonstrates using the AutoML client to delete a model. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model. + * @throws Exception on AutoML Client errors + */ + public static void deleteModel(String projectId, String computeRegion, String modelId) + throws InterruptedException, ExecutionException, IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the full path of the model. + ModelName modelFullId = ModelName.of(projectId, computeRegion, modelId); + + // Delete a model. + Empty response = client.deleteModelAsync(modelFullId).get(); + + System.out.println("Model deletion started..."); + } + // [END automl_translation_delete_model] + + // [START automl_translation_get_operation_status] + /** + * Demonstrates using the AutoML client to get operation status. + * + * @param operationFullId Full name of a operation. For example, the name of your operation is + * projects/[projectId]/locations/us-central1/operations/[operationId]. + * @throws IOException on Input/Output errors. + */ + private static void getOperationStatus(String operationFullId) throws IOException { + // Instantiates a client + AutoMlClient client = AutoMlClient.create(); + + // Get the latest state of a long-running operation. + Operation response = client.getOperationsClient().getOperation(operationFullId); + + System.out.println(String.format("Operation status: %s", response)); + } + // [END automl_translation_get_operation_status] + + public static void main(String[] args) throws Exception { + ModelApi modelApi = new ModelApi(); + modelApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) throws Exception { + + ArgumentParser parser = + ArgumentParsers.newFor("ModelApi") + .build() + .defaultHelp(true) + .description("Model API operations"); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser createModelParser = subparsers.addParser("create_model"); + createModelParser.addArgument("datasetId"); + createModelParser.addArgument("modelName"); + + Subparser listModelParser = subparsers.addParser("list_models"); + listModelParser.addArgument("filter").nargs("?").setDefault(""); + + Subparser getModelParser = subparsers.addParser("get_model"); + getModelParser.addArgument("modelId"); + + Subparser listModelEvaluationsParser = subparsers.addParser("list_model_evaluations"); + listModelEvaluationsParser.addArgument("modelId"); + listModelEvaluationsParser.addArgument("filter").nargs("?").setDefault(""); + + Subparser getModelEvaluationParser = subparsers.addParser("get_model_evaluation"); + getModelEvaluationParser.addArgument("modelId"); + getModelEvaluationParser.addArgument("modelEvaluationId"); + + Subparser deleteModelParser = subparsers.addParser("delete_model"); + deleteModelParser.addArgument("modelId"); + + Subparser getOperationStatusParser = subparsers.addParser("get_operation_status"); + getOperationStatusParser.addArgument("operationFullId"); + + 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("create_model")) { + createModel(projectId, computeRegion, ns.getString("datasetId"), ns.getString("modelName")); + } + if (ns.get("command").equals("list_models")) { + listModels(projectId, computeRegion, ns.getString("filter")); + } + if (ns.get("command").equals("get_model")) { + getModel(projectId, computeRegion, ns.getString("modelId")); + } + if (ns.get("command").equals("list_model_evaluations")) { + listModelEvaluations( + projectId, computeRegion, ns.getString("modelId"), ns.getString("filter")); + } + if (ns.get("command").equals("get_model_evaluation")) { + getModelEvaluation( + projectId, computeRegion, ns.getString("modelId"), ns.getString("modelEvaluationId")); + } + if (ns.get("command").equals("delete_model")) { + deleteModel(projectId, computeRegion, ns.getString("modelId")); + } + if (ns.get("command").equals("get_operation_status")) { + getOperationStatus(ns.getString("operationFullId")); + } + } catch (ArgumentParserException e) { + parser.handleError(e); + } + } +} diff --git a/translate/automl/src/main/java/com/google/cloud/translate/automl/PredictionApi.java b/translate/automl/src/main/java/com/google/cloud/translate/automl/PredictionApi.java new file mode 100644 index 00000000000..d3b1170897f --- /dev/null +++ b/translate/automl/src/main/java/com/google/cloud/translate/automl/PredictionApi.java @@ -0,0 +1,140 @@ +/* + * Copyright 2018 Google Inc. + * + * 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. + */ + +/* + * This application demonstrates how to perform basic operations on prediction + * with the Google AutoML Vision API. + * + * For more information, the documentation at + * https://cloud.google.com/vision/automl/docs. + */ + +package com.google.cloud.translate.automl; + +// Imports the Google Cloud client library +import com.google.cloud.automl.v1beta1.ExamplePayload; +import com.google.cloud.automl.v1beta1.ModelName; +import com.google.cloud.automl.v1beta1.PredictResponse; +import com.google.cloud.automl.v1beta1.PredictionServiceClient; + +import com.google.cloud.automl.v1beta1.TextSnippet; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.ArgumentParserException; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; +import net.sourceforge.argparse4j.inf.Subparsers; + +/** + * Google Cloud AutoML Translate API sample application. Example usage: mvn package exec:java + * -Dexec.mainClass ='com.google.cloud.vision.samples.automl.PredictionApi' -Dexec.args='predict + * [modelId] [path-to-image] [scoreThreshold]' + */ +public class PredictionApi { + + // [START automl_translation_predict] + + /** + * Demonstrates using the AutoML client to predict an image. + * + * @param projectId the Id of the project. + * @param computeRegion the Region name. + * @param modelId the Id of the model which will be used for text classification. + * @param filePath the Local text file path of the content to be classified. + * @param translationAllowFallback set to true to use a Google translation. + * @throws IOException on Input/Output errors. + */ + public static void predict( + String projectId, + String computeRegion, + String modelId, + String filePath, + boolean translationAllowFallback) + throws IOException { + // Instantiate client for prediction service. + PredictionServiceClient predictionClient = PredictionServiceClient.create(); + + // Get the full path of the model. + ModelName name = ModelName.of(projectId, computeRegion, modelId); + + // Read the file content for translation. + String content = new String(Files.readAllBytes(Paths.get(filePath))); + + TextSnippet textSnippet = TextSnippet.newBuilder().setContent(content).build(); + + // Set the payload by giving the content of the file. + ExamplePayload payload = ExamplePayload.newBuilder().setTextSnippet(textSnippet).build(); + + // Additional parameters that can be provided for prediction + Map params = new HashMap<>(); + if (translationAllowFallback) { + params.put("translation_allow_fallback", "True");//Allow Google Translation Model + } + + PredictResponse response = predictionClient.predict(name, payload, params); + TextSnippet translatedContent = response.getPayload(0).getTranslation().getTranslatedContent(); + + System.out.println(String.format("Translated Content: %s", translatedContent.getContent())); + } + // [END automl_translation_predict] + + public static void main(String[] args) throws IOException { + PredictionApi predictApi = new PredictionApi(); + predictApi.argsHelper(args, System.out); + } + + public static void argsHelper(String[] args, PrintStream out) throws IOException { + ArgumentParser parser = ArgumentParsers.newFor("PredictionApi") + .build() + .defaultHelp(true) + .description("Prediction API Operation"); + Subparsers subparsers = parser.addSubparsers().dest("command"); + + Subparser predictParser = subparsers.addParser("predict"); + predictParser.addArgument("modelId"); + predictParser.addArgument("filePath"); + predictParser + .addArgument("translationAllowFallback") + .nargs("?") + .type(Boolean.class) + .setDefault(Boolean.FALSE); + + 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("predict")) { + predict( + projectId, + computeRegion, + ns.getString("modelId"), + ns.getString("filePath"), + ns.getBoolean("translationAllowFallback")); + } + } catch (ArgumentParserException e) { + parser.handleError(e); + } + } +} From 4578cc5863371021306f9333c7b943df2199980d Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Mon, 23 Jul 2018 16:25:35 -0700 Subject: [PATCH 09/10] Triggering tests --- .../java/com/google/cloud/translate/automl/DatasetApiIT.java | 1 - 1 file changed, 1 deletion(-) diff --git a/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java b/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java index 7ceda3e4445..1741fd70bde 100644 --- a/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java +++ b/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java @@ -17,7 +17,6 @@ package com.google.cloud.translate.automl; import static com.google.common.truth.Truth.assertThat; -import static java.lang.Boolean.FALSE; import java.io.ByteArrayOutputStream; import java.io.PrintStream; From 17f1b5df4eb57046010141f970006900034d76ea Mon Sep 17 00:00:00 2001 From: nirupa-kumar Date: Mon, 23 Jul 2018 16:42:52 -0700 Subject: [PATCH 10/10] Triggering tests --- .../java/com/google/cloud/language/samples/DatasetApiIT.java | 2 +- .../java/com/google/cloud/translate/automl/DatasetApiIT.java | 2 +- .../com/google/cloud/vision/samples/automl/DatasetApiIT.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/language/automl/src/test/java/com/google/cloud/language/samples/DatasetApiIT.java b/language/automl/src/test/java/com/google/cloud/language/samples/DatasetApiIT.java index 1b43dd04055..35f2dbf2f71 100644 --- a/language/automl/src/test/java/com/google/cloud/language/samples/DatasetApiIT.java +++ b/language/automl/src/test/java/com/google/cloud/language/samples/DatasetApiIT.java @@ -36,7 +36,7 @@ public class DatasetApiIT { private static final String PROJECT_ID = "java-docs-samples-testing"; private static final String BUCKET = PROJECT_ID + "-vcm"; private static final String COMPUTE_REGION = "us-central1"; - private static final String DATASET_NAME = "test_dataset"; + private static final String DATASET_NAME = "test_language_dataset"; private ByteArrayOutputStream bout; private PrintStream out; private DatasetApi app; diff --git a/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java b/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java index 1741fd70bde..2f47e55968a 100644 --- a/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java +++ b/translate/automl/src/test/java/com/google/cloud/translate/automl/DatasetApiIT.java @@ -35,7 +35,7 @@ public class DatasetApiIT { private static final String PROJECT_ID = "java-docs-samples-testing"; private static final String BUCKET = PROJECT_ID + "-vcm"; private static final String COMPUTE_REGION = "us-central1"; - private static final String DATASET_NAME = "test_dataset"; + private static final String DATASET_NAME = "test_translate_dataset"; private ByteArrayOutputStream bout; private PrintStream out; private DatasetApi app; diff --git a/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/DatasetApiIT.java b/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/DatasetApiIT.java index 1a45326169a..41cf9dec9a5 100644 --- a/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/DatasetApiIT.java +++ b/vision/automl/src/test/java/com/google/cloud/vision/samples/automl/DatasetApiIT.java @@ -36,7 +36,7 @@ public class DatasetApiIT { private static final String PROJECT_ID = "java-docs-samples-testing"; private static final String BUCKET = PROJECT_ID + "-vcm"; private static final String COMPUTE_REGION = "us-central1"; - private static final String DATASET_NAME = "test_dataset"; + private static final String DATASET_NAME = "test_vision_dataset"; private ByteArrayOutputStream bout; private PrintStream out; private DatasetApi app;