Search code examples
pythongoogle-cloud-platformtypeerrorgoogle-cloud-vision

Assigning multiple labels to product in GCP Vision


I'm using GCP Cloud Vision to catalogue products. After i've created a product, i have to update it to add labels to the product.

If i upload products via a CSV bulk import, labels can be formatted in the CSV as "color=black,style=formal" or "color=black,style=formal,style=mens". However when adding them to a specific product outside of the bulk import via the API, the example in the documentation asks for key and value as variables.

https://cloud.google.com/vision/product-search/docs/update-resources

How can i assign multiple lables (the docs say it is supported) into the product via this API?

I've tried adding them as a list in the following format but i'm getting an error:

GCP Example: def update_product_labels(product_id, key, value):

Attempt: update_product_labels('axel-arigato-1',['category', 'colour'], ['shoes', 'black'])

Error: TypeError: ['category', 'colour'] has type list, but expected one of: bytes, unicode


Solution

  • Using the sample code in the link you provided. It can be updated to create a list of KeyValue() and then pass that to create your vision.Product() object. See updated code below:

    
    from google.cloud import vision
    from google.protobuf import field_mask_pb2 as field_mask
    
    def update_product_labels(
            project_id, location, product_id, key, value):
        """Update the product labels.
        Args:
            project_id: Id of the project.
            location: A compute region name.
            product_id: Id of the product.
            key: The key of the label.
            value: The value of the label.
        """
        client = vision.ProductSearchClient()
    
        # Get the name of the product.
        product_path = client.product_path(
            project=project_id, location=location, product=product_id)
    
        # Set product name, product label and product display name.
        # Multiple labels are also supported.
    
        key_len = len(key)
        value_len = len(value)
        key_value = []
    
        if key_len != value_len:
            print("Please enter equal indices for key and value")
        else:
            for n in range(key_len):
                key_value.append(vision.Product.KeyValue(key=key[n], value=value[n]))
            product = vision.Product(
                    name=product_path,
                    product_labels=key_value)
    
            # Updating only the product_labels field here.
            update_mask = field_mask.FieldMask(paths=['product_labels'])
    
            # This overwrites the product_labels.
            updated_product = client.update_product(
                product=product, update_mask=update_mask)
    
            # Display the updated product information.
            print('Product name: {}'.format(updated_product.name))
            print('Updated product labels: {}'.format(product.product_labels))
    
    update_product_labels(
            project_id = "your-project-id",
            location = "us-east1", #used this location for testing
            product_id = "product_id0", #used this product_id for testing
            key = ['category', 'colour'],
            value = ['shoes', 'black'],
            )
    
    

    Sample run:

    enter image description here

    Check the product if it was really applied. I sent a GET at the endpoint below:

    curl -X GET \
    -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
    "https://vision.googleapis.com/v1/projects/your-project-id/locations/us-east1/products/product_id0"
    
    

    Output when for get product:

    enter image description here

    NOTE: Updating the key value pair in this manner overwrites the previous data. So for example if you want to add a new key value pair, you should include the old data. When calling the function, your input should be key = ['category', 'colour','new_key'], value = ['shoes', 'black', 'new_value'].