From 9424ea9ca91a0726a4402bd30eac7d49dc735487 Mon Sep 17 00:00:00 2001 From: Yu-Han Liu Date: Fri, 16 Aug 2019 16:06:12 -0700 Subject: [PATCH 1/8] add vision_product_search_purge_products_in_product_set --- .../product_in_product_set_management.py | 48 +++++++++++++++++++ .../product_in_product_set_management_test.py | 20 +++++++- .../product_search/requirements.txt | 2 +- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/vision/cloud-client/product_search/product_in_product_set_management.py b/vision/cloud-client/product_search/product_in_product_set_management.py index 8c08c8a05e78..59fcd3078b66 100755 --- a/vision/cloud-client/product_search/product_in_product_set_management.py +++ b/vision/cloud-client/product_search/product_in_product_set_management.py @@ -25,10 +25,12 @@ # [START vision_product_search_add_product_to_product_set] # [START vision_product_search_remove_product_from_product_set] +# [START vision_product_search_purge_products_in_product_set] from google.cloud import vision # [END vision_product_search_add_product_to_product_set] # [END vision_product_search_remove_product_from_product_set] +# [END vision_product_search_purge_products_in_product_set] # [START vision_product_search_add_product_to_product_set] @@ -117,6 +119,44 @@ def remove_product_from_product_set( # [END vision_product_search_remove_product_from_product_set] +# [START vision_product_search_purge_products_in_product_set] +def purge_products_in_product_set( + project_id, location, product_set_id, force): + """Delete all products in a product set. + Args: + project_id: Id of the project. + location: A compute region name. + product_set_id: Id of the product set. + force: Perform the purge only when force is set to True. + """ + client = vision.ProductSearchClient() + + parent = client.location_path( + project=project_id, location=location) + + product_set_purge_config = vision.types.ProductSetPurgeConfig( + product_set_id=product_set_id) + + # The purge operation is async. + operation = client.purge_products( + parent=parent, + product_set_purge_config=product_set_purge_config, + # The operation is irreversible and removes multiple products. The user is required to pass in force=True to actually perform the purge. + # If force is not set to True, the service raises an error. + force=force) + + # TODO: replace with operation.result(timeout=60) + import time + for _ in range(60): + if operation.done(): + break + time.sleep(1) + + if force: + print('Products removed from product set.') +# [END vision_product_search_purge_products_in_product_set] + + if __name__ == '__main__': parser = argparse.ArgumentParser( description=__doc__, @@ -147,6 +187,12 @@ def remove_product_from_product_set( remove_product_from_product_set_parser.add_argument('product_id') remove_product_from_product_set_parser.add_argument('product_set_id') + purge_products_in_product_set_parser = subparsers.add_parser( + 'purge_products_in_product_set', + help=purge_products_in_product_set.__doc__) + purge_products_in_product_set_parser.add_argument('product_set_id') + purge_products_in_product_set_parser.add_argument('--force', action='store_true') + args = parser.parse_args() if args.command == 'add_product_to_product_set': @@ -160,3 +206,5 @@ def remove_product_from_product_set( remove_product_from_product_set( args.project_id, args.location, args.product_id, args.product_set_id) + elif args.command == 'purge_products_in_product_set': + purge_products_in_product_set(args.project_id, args.location, args.product_set_id, args.force) diff --git a/vision/cloud-client/product_search/product_in_product_set_management_test.py b/vision/cloud-client/product_search/product_in_product_set_management_test.py index 21a23bdb7744..8da78352c2e0 100644 --- a/vision/cloud-client/product_search/product_in_product_set_management_test.py +++ b/vision/cloud-client/product_search/product_in_product_set_management_test.py @@ -18,8 +18,8 @@ from product_in_product_set_management import ( add_product_to_product_set, list_products_in_product_set, - remove_product_from_product_set) -from product_management import create_product, delete_product + remove_product_from_product_set, purge_products_in_product_set) +from product_management import create_product, delete_product, list_products from product_set_management import ( create_product_set, delete_product_set) @@ -75,3 +75,19 @@ def test_remove_product_from_product_set(capsys, product_and_product_set): list_products_in_product_set(PROJECT_ID, LOCATION, PRODUCT_SET_ID) out, _ = capsys.readouterr() assert 'Product id: {}'.format(PRODUCT_ID) not in out + + +def test_purge_products_in_product_set(capsys, product_and_product_set): + add_product_to_product_set( + PROJECT_ID, LOCATION, PRODUCT_ID, PRODUCT_SET_ID) + list_products(PROJECT_ID, LOCATION) + out, _ = capsys.readouterr() + assert 'Product id: {}'.format(PRODUCT_ID) in out + + purge_products_in_product_set(PROJECT_ID, LOCATION, PRODUCT_SET_ID, force=True) + + list_products(PROJECT_ID, LOCATION) + out, _ = capsys.readouterr() + assert 'Product id: {}'.format(PRODUCT_ID) not in out + + print(out) diff --git a/vision/cloud-client/product_search/requirements.txt b/vision/cloud-client/product_search/requirements.txt index dad4a99e19c5..aab93a3560cb 100644 --- a/vision/cloud-client/product_search/requirements.txt +++ b/vision/cloud-client/product_search/requirements.txt @@ -1 +1 @@ -google-cloud-vision==0.35.2 +google-cloud-vision==0.39.0 From 5d09861d51a546890c704e8f4c0d748818846471 Mon Sep 17 00:00:00 2001 From: Yu-Han Liu Date: Fri, 16 Aug 2019 16:43:52 -0700 Subject: [PATCH 2/8] add vision_product_search_purge_orphan_products --- .../product_in_product_set_management.py | 3 +- .../product_search/product_management.py | 39 +++++++++++++++++++ .../product_search/product_management_test.py | 16 +++++++- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/vision/cloud-client/product_search/product_in_product_set_management.py b/vision/cloud-client/product_search/product_in_product_set_management.py index 59fcd3078b66..937be7ea3a80 100755 --- a/vision/cloud-client/product_search/product_in_product_set_management.py +++ b/vision/cloud-client/product_search/product_in_product_set_management.py @@ -152,8 +152,7 @@ def purge_products_in_product_set( break time.sleep(1) - if force: - print('Products removed from product set.') + print('Products removed from product set.') # [END vision_product_search_purge_products_in_product_set] diff --git a/vision/cloud-client/product_search/product_management.py b/vision/cloud-client/product_search/product_management.py index 62e95dbabb01..d56d152093cd 100755 --- a/vision/cloud-client/product_search/product_management.py +++ b/vision/cloud-client/product_search/product_management.py @@ -28,6 +28,7 @@ # [START vision_product_search_list_products] # [START vision_product_search_get_product] # [START vision_product_search_update_product_labels] +# [START vision_product_search_purge_orphan_products] from google.cloud import vision # [END vision_product_search_create_product] @@ -35,6 +36,7 @@ # [END vision_product_search_list_products] # [END vision_product_search_get_product] # [END vision_product_search_update_product_labels] +# [END vision_product_search_purge_orphan_products] # [START vision_product_search_create_product] @@ -181,6 +183,37 @@ def delete_product(project_id, location, product_id): # [END vision_product_search_delete_product] +# [START vision_product_search_purge_orphan_products] +def purge_orphan_products(project_id, location, force): + """Delete all products not in any product sets. + Args: + project_id: Id of the project. + location: A compute region name. + """ + client = vision.ProductSearchClient() + + parent = client.location_path( + project=project_id, location=location) + + # The purge operation is async. + operation = client.purge_products( + parent=parent, + delete_orphan_products=True, + # The operation is irreversible and removes multiple products. The user is required to pass in force=True to actually perform the purge. + # If force is not set to True, the service raises an error. + force=force) + + # TODO: replace with operation.result(timeout=60) + import time + for _ in range(60): + if operation.done(): + break + time.sleep(1) + + print('Orphan products deleted.') +# [END vision_product_search_purge_orphan_products] + + if __name__ == '__main__': parser = argparse.ArgumentParser( description=__doc__, @@ -219,6 +252,10 @@ def delete_product(project_id, location, product_id): 'delete_product', help=delete_product.__doc__) delete_product_parser.add_argument('product_id') + purge_orphan_products_parser = subparsers.add_parser( + 'purge_orphan_products', help=purge_orphan_products.__doc__) + purge_orphan_products_parser.add_argument('--force', action='store_true') + args = parser.parse_args() if args.command == 'create_product': @@ -235,3 +272,5 @@ def delete_product(project_id, location, product_id): args.key, args.value) elif args.command == 'delete_product': delete_product(args.project_id, args.location, args.product_id) + elif args.command == 'purge_orphan_products': + purge_orphan_products(args.project_id, args.location, args.force) diff --git a/vision/cloud-client/product_search/product_management_test.py b/vision/cloud-client/product_search/product_management_test.py index fd1ad24aeb61..23326fe5a57f 100644 --- a/vision/cloud-client/product_search/product_management_test.py +++ b/vision/cloud-client/product_search/product_management_test.py @@ -18,7 +18,9 @@ from product_management import ( create_product, delete_product, get_product, list_products, - update_product_labels) + update_product_labels, purge_orphan_products) + +from product_in_product_set_management_test import product_and_product_set PROJECT_ID = os.getenv('GCLOUD_PROJECT') @@ -83,3 +85,15 @@ def test_update_product_labels(capsys, product): assert VALUE in out delete_product(PROJECT_ID, LOCATION, PRODUCT_ID) + + +def test_purge_orphan_products(capsys, product): + list_products(PROJECT_ID, LOCATION) + out, _ = capsys.readouterr() + assert PRODUCT_ID in out + + purge_orphan_products(PROJECT_ID, LOCATION, force=True) + + list_products(PROJECT_ID, LOCATION) + out, _ = capsys.readouterr() + assert PRODUCT_ID not in out From 0d5b79175bb3e26e90c27eb22c61a4ce34e317a0 Mon Sep 17 00:00:00 2001 From: Yu-Han Liu Date: Mon, 19 Aug 2019 08:40:51 -0700 Subject: [PATCH 3/8] update comment --- .../product_search/product_in_product_set_management.py | 2 +- vision/cloud-client/product_search/product_management.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vision/cloud-client/product_search/product_in_product_set_management.py b/vision/cloud-client/product_search/product_in_product_set_management.py index 937be7ea3a80..aa6292890ba8 100755 --- a/vision/cloud-client/product_search/product_in_product_set_management.py +++ b/vision/cloud-client/product_search/product_in_product_set_management.py @@ -142,7 +142,7 @@ def purge_products_in_product_set( parent=parent, product_set_purge_config=product_set_purge_config, # The operation is irreversible and removes multiple products. The user is required to pass in force=True to actually perform the purge. - # If force is not set to True, the service raises an error. + # If force is not set to True, the service raises an exception. force=force) # TODO: replace with operation.result(timeout=60) diff --git a/vision/cloud-client/product_search/product_management.py b/vision/cloud-client/product_search/product_management.py index d56d152093cd..943e9a2ae8ab 100755 --- a/vision/cloud-client/product_search/product_management.py +++ b/vision/cloud-client/product_search/product_management.py @@ -200,7 +200,7 @@ def purge_orphan_products(project_id, location, force): parent=parent, delete_orphan_products=True, # The operation is irreversible and removes multiple products. The user is required to pass in force=True to actually perform the purge. - # If force is not set to True, the service raises an error. + # If force is not set to True, the service raises an exception. force=force) # TODO: replace with operation.result(timeout=60) From 4f18e9cd502e9d8d68ab018d5e3f90cd7496f2a2 Mon Sep 17 00:00:00 2001 From: Yu-Han Liu Date: Mon, 19 Aug 2019 11:41:40 -0700 Subject: [PATCH 4/8] flake --- .../product_in_product_set_management.py | 12 ++++++++---- .../product_in_product_set_management_test.py | 5 +++-- .../product_search/product_management.py | 6 ++++-- .../product_search/product_management_test.py | 4 +--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/vision/cloud-client/product_search/product_in_product_set_management.py b/vision/cloud-client/product_search/product_in_product_set_management.py index aa6292890ba8..f3ff707ac1c9 100755 --- a/vision/cloud-client/product_search/product_in_product_set_management.py +++ b/vision/cloud-client/product_search/product_in_product_set_management.py @@ -141,10 +141,12 @@ def purge_products_in_product_set( operation = client.purge_products( parent=parent, product_set_purge_config=product_set_purge_config, - # The operation is irreversible and removes multiple products. The user is required to pass in force=True to actually perform the purge. + # The operation is irreversible and removes multiple products. + # The user is required to pass in force=True to actually perform the + # purge. # If force is not set to True, the service raises an exception. force=force) - + # TODO: replace with operation.result(timeout=60) import time for _ in range(60): @@ -190,7 +192,8 @@ def purge_products_in_product_set( 'purge_products_in_product_set', help=purge_products_in_product_set.__doc__) purge_products_in_product_set_parser.add_argument('product_set_id') - purge_products_in_product_set_parser.add_argument('--force', action='store_true') + purge_products_in_product_set_parser.add_argument( + '--force', action='store_true') args = parser.parse_args() @@ -206,4 +209,5 @@ def purge_products_in_product_set( args.project_id, args.location, args.product_id, args.product_set_id) elif args.command == 'purge_products_in_product_set': - purge_products_in_product_set(args.project_id, args.location, args.product_set_id, args.force) + purge_products_in_product_set( + args.project_id, args.location, args.product_set_id, args.force) diff --git a/vision/cloud-client/product_search/product_in_product_set_management_test.py b/vision/cloud-client/product_search/product_in_product_set_management_test.py index 8da78352c2e0..8d93f2e0e729 100644 --- a/vision/cloud-client/product_search/product_in_product_set_management_test.py +++ b/vision/cloud-client/product_search/product_in_product_set_management_test.py @@ -18,7 +18,7 @@ from product_in_product_set_management import ( add_product_to_product_set, list_products_in_product_set, - remove_product_from_product_set, purge_products_in_product_set) + purge_products_in_product_set, remove_product_from_product_set) from product_management import create_product, delete_product, list_products from product_set_management import ( create_product_set, delete_product_set) @@ -84,7 +84,8 @@ def test_purge_products_in_product_set(capsys, product_and_product_set): out, _ = capsys.readouterr() assert 'Product id: {}'.format(PRODUCT_ID) in out - purge_products_in_product_set(PROJECT_ID, LOCATION, PRODUCT_SET_ID, force=True) + purge_products_in_product_set( + PROJECT_ID, LOCATION, PRODUCT_SET_ID, force=True) list_products(PROJECT_ID, LOCATION) out, _ = capsys.readouterr() diff --git a/vision/cloud-client/product_search/product_management.py b/vision/cloud-client/product_search/product_management.py index 943e9a2ae8ab..379db5a6349a 100755 --- a/vision/cloud-client/product_search/product_management.py +++ b/vision/cloud-client/product_search/product_management.py @@ -199,10 +199,12 @@ def purge_orphan_products(project_id, location, force): operation = client.purge_products( parent=parent, delete_orphan_products=True, - # The operation is irreversible and removes multiple products. The user is required to pass in force=True to actually perform the purge. + # The operation is irreversible and removes multiple products. + # The user is required to pass in force=True to actually perform the + # purge. # If force is not set to True, the service raises an exception. force=force) - + # TODO: replace with operation.result(timeout=60) import time for _ in range(60): diff --git a/vision/cloud-client/product_search/product_management_test.py b/vision/cloud-client/product_search/product_management_test.py index 23326fe5a57f..1019c52f4171 100644 --- a/vision/cloud-client/product_search/product_management_test.py +++ b/vision/cloud-client/product_search/product_management_test.py @@ -18,9 +18,7 @@ from product_management import ( create_product, delete_product, get_product, list_products, - update_product_labels, purge_orphan_products) - -from product_in_product_set_management_test import product_and_product_set + purge_orphan_products, update_product_labels) PROJECT_ID = os.getenv('GCLOUD_PROJECT') From ad76d9a94dde014ed4b972aa7b008cba80671536 Mon Sep 17 00:00:00 2001 From: Yu-Han Liu Date: Thu, 22 Aug 2019 13:00:53 -0700 Subject: [PATCH 5/8] update print message --- .../product_search/product_in_product_set_management.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vision/cloud-client/product_search/product_in_product_set_management.py b/vision/cloud-client/product_search/product_in_product_set_management.py index f3ff707ac1c9..d737312ddd79 100755 --- a/vision/cloud-client/product_search/product_in_product_set_management.py +++ b/vision/cloud-client/product_search/product_in_product_set_management.py @@ -154,7 +154,7 @@ def purge_products_in_product_set( break time.sleep(1) - print('Products removed from product set.') + print('Deleted products in product set.') # [END vision_product_search_purge_products_in_product_set] From 4ee53e697b26ba52615627604bb75c37cbf0ec91 Mon Sep 17 00:00:00 2001 From: Yu-Han Liu Date: Wed, 11 Sep 2019 09:52:23 -0700 Subject: [PATCH 6/8] update python sample to use operation.result --- .../product_search/product_in_product_set_management.py | 7 +------ vision/cloud-client/product_search/product_management.py | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/vision/cloud-client/product_search/product_in_product_set_management.py b/vision/cloud-client/product_search/product_in_product_set_management.py index d737312ddd79..f8c5a5c709a6 100755 --- a/vision/cloud-client/product_search/product_in_product_set_management.py +++ b/vision/cloud-client/product_search/product_in_product_set_management.py @@ -147,12 +147,7 @@ def purge_products_in_product_set( # If force is not set to True, the service raises an exception. force=force) - # TODO: replace with operation.result(timeout=60) - import time - for _ in range(60): - if operation.done(): - break - time.sleep(1) + result = operation.result(timeout=60) print('Deleted products in product set.') # [END vision_product_search_purge_products_in_product_set] diff --git a/vision/cloud-client/product_search/product_management.py b/vision/cloud-client/product_search/product_management.py index 379db5a6349a..cc6f00210089 100755 --- a/vision/cloud-client/product_search/product_management.py +++ b/vision/cloud-client/product_search/product_management.py @@ -205,12 +205,7 @@ def purge_orphan_products(project_id, location, force): # If force is not set to True, the service raises an exception. force=force) - # TODO: replace with operation.result(timeout=60) - import time - for _ in range(60): - if operation.done(): - break - time.sleep(1) + operation.result(timeout=90) print('Orphan products deleted.') # [END vision_product_search_purge_orphan_products] From d79a02905c67a7d1d2d5516fe23dd9dc72c0c23a Mon Sep 17 00:00:00 2001 From: Yu-Han Liu Date: Wed, 11 Sep 2019 09:55:07 -0700 Subject: [PATCH 7/8] longer timeout --- .../product_search/product_in_product_set_management.py | 2 +- vision/cloud-client/product_search/product_management.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vision/cloud-client/product_search/product_in_product_set_management.py b/vision/cloud-client/product_search/product_in_product_set_management.py index f8c5a5c709a6..ebc42236cf67 100755 --- a/vision/cloud-client/product_search/product_in_product_set_management.py +++ b/vision/cloud-client/product_search/product_in_product_set_management.py @@ -147,7 +147,7 @@ def purge_products_in_product_set( # If force is not set to True, the service raises an exception. force=force) - result = operation.result(timeout=60) + result = operation.result(timeout=120) print('Deleted products in product set.') # [END vision_product_search_purge_products_in_product_set] diff --git a/vision/cloud-client/product_search/product_management.py b/vision/cloud-client/product_search/product_management.py index cc6f00210089..8e96ee9e75d6 100755 --- a/vision/cloud-client/product_search/product_management.py +++ b/vision/cloud-client/product_search/product_management.py @@ -205,7 +205,7 @@ def purge_orphan_products(project_id, location, force): # If force is not set to True, the service raises an exception. force=force) - operation.result(timeout=90) + operation.result(timeout=120) print('Orphan products deleted.') # [END vision_product_search_purge_orphan_products] From c400c021633a34119c98b371393cb895c8fe0f91 Mon Sep 17 00:00:00 2001 From: Yu-Han Liu Date: Wed, 11 Sep 2019 09:55:59 -0700 Subject: [PATCH 8/8] remove unused variable --- .../product_search/product_in_product_set_management.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vision/cloud-client/product_search/product_in_product_set_management.py b/vision/cloud-client/product_search/product_in_product_set_management.py index ebc42236cf67..fcf4fa6179de 100755 --- a/vision/cloud-client/product_search/product_in_product_set_management.py +++ b/vision/cloud-client/product_search/product_in_product_set_management.py @@ -147,7 +147,7 @@ def purge_products_in_product_set( # If force is not set to True, the service raises an exception. force=force) - result = operation.result(timeout=120) + operation.result(timeout=120) print('Deleted products in product set.') # [END vision_product_search_purge_products_in_product_set]