Skip to content

Commit

Permalink
Purge products (#2349)
Browse files Browse the repository at this point in the history
* add vision_product_search_purge_products_in_product_set

* add vision_product_search_purge_orphan_products

* update comment

* flake

* update print message

* update python sample to use operation.result

* longer timeout

* remove unused variable
  • Loading branch information
dizcology authored Sep 21, 2019
1 parent db332fd commit 9e8ac90
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -117,6 +119,40 @@ 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 exception.
force=force)

operation.result(timeout=120)

print('Deleted products in product set.')
# [END vision_product_search_purge_products_in_product_set]


if __name__ == '__main__':
parser = argparse.ArgumentParser(
description=__doc__,
Expand Down Expand Up @@ -147,6 +183,13 @@ 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':
Expand All @@ -160,3 +203,6 @@ 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)
Original file line number Diff line number Diff line change
Expand Up @@ -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
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)

Expand Down Expand Up @@ -75,3 +75,20 @@ 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)
36 changes: 36 additions & 0 deletions vision/cloud-client/product_search/product_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@
# [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]
# [END vision_product_search_delete_product]
# [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]
Expand Down Expand Up @@ -181,6 +183,34 @@ 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 exception.
force=force)

operation.result(timeout=120)

print('Orphan products deleted.')
# [END vision_product_search_purge_orphan_products]


if __name__ == '__main__':
parser = argparse.ArgumentParser(
description=__doc__,
Expand Down Expand Up @@ -219,6 +249,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':
Expand All @@ -235,3 +269,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)
14 changes: 13 additions & 1 deletion vision/cloud-client/product_search/product_management_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from product_management import (
create_product, delete_product, get_product, list_products,
update_product_labels)
purge_orphan_products, update_product_labels)


PROJECT_ID = os.getenv('GCLOUD_PROJECT')
Expand Down Expand Up @@ -83,3 +83,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
2 changes: 1 addition & 1 deletion vision/cloud-client/product_search/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
google-cloud-vision==0.35.2
google-cloud-vision==0.39.0

0 comments on commit 9e8ac90

Please sign in to comment.