Instructivo: Analiza una tabla de objetos con una función remota

En este instructivo, se muestra cómo crear una tabla de objetos basada en las imágenes del conjunto de datos de flores, cómo crear una función remota que etiquete imágenes mediante la API de Cloud Vision y, luego, revisar las imágenes en la tabla de objetos con la función remota.

Permisos necesarios

  • Para crear el conjunto de datos, necesitas el permiso bigquery.datasets.create.
  • Para crear el recurso de conexión, necesitas los siguientes permisos:

    • bigquery.connections.create
    • bigquery.connections.get
  • Para otorgar permisos a la cuenta de servicio de la conexión, necesitas el siguiente permiso:

    • resourcemanager.projects.setIamPolicy
  • Para crear la tabla de objetos, necesitas los siguientes permisos:

    • bigquery.tables.create
    • bigquery.tables.update
    • bigquery.connections.delegate
  • Para crear la función remota, necesitas los permisos asociados con el función Desarrollador de Cloud Functions.

  • Para invocar la función remota, necesitas el función Invocador de Cloud Run.

  • Para analizar la tabla de objetos con la función remota, necesitas el permiso bigquery.tables.getData en la tabla de objetos.

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

  • BigQuery: se generan costos de almacenamiento para el objeto de tabla que creas en BigQuery.
  • Cloud Functions: Generas costos por invocar la función remota y por cualquier recurso de procesamiento que use, incluidas las llamadas a la API de Cloud Vision.

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Para obtener más información, consulta la página Precios de Cloud Storage.

Para obtener más información sobre los precios de almacenamiento de BigQuery, consulta los Precios de almacenamiento en la documentación de BigQuery.

Para obtener más información sobre los precios de Cloud Functions, consulta Precios de Cloud Functions.

Para obtener más información sobre los precios de la API de Vision, consulta Precios de Cloud Vision en la documentación de Vision.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  4. Habilita las API de BigQuery, BigQuery Connection API, and Cloud Functions.

    Habilita las API

  5. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  6. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  7. Habilita las API de BigQuery, BigQuery Connection API, and Cloud Functions.

    Habilita las API

Crea una función de Cloud Functions

Para crear una función, sigue estos pasos:

  1. Ve a la página de Cloud Functions.

    Ir a Cloud Functions

  2. Haga clic en Crear función.

  3. En Entorno, selecciona 2ª gen..

  4. En Nombre de la función, escribe vision-ai.

  5. Haz clic en Siguiente.

  6. Para Entorno de ejecución, selecciona Python 3.9.

  7. En Punto de entrada, escribe label_detection.

  8. Seleccione main.py. Copia y pega el siguiente código:

    Python

    import urllib.request
    
    import flask
    import functions_framework
    from google.cloud import vision
    
    @functions_framework.http
    def label_detection(request: flask.Request) -> flask.Response:
        """BigQuery remote function to label input images.
        Args:
            request: HTTP request from BigQuery
            https://cloud.google.com/bigquery/docs/reference/standard-sql/remote-functions#input_format
        Returns:
            HTTP response to BigQuery
            https://cloud.google.com/bigquery/docs/reference/standard-sql/remote-functions#output_format
        """
        try:
            client = vision.ImageAnnotatorClient()
            calls = request.get_json()["calls"]
            replies = []
            for call in calls:
                content = urllib.request.urlopen(call[0]).read()
                results = client.label_detection({"content": content})
                replies.append(vision.AnnotateImageResponse.to_dict(results))
            return flask.make_response(flask.jsonify({"replies": replies}))
        except Exception as e:
            return flask.make_response(flask.jsonify({"errorMessage": str(e)}), 400)
    
    

  9. Seleccione requirements.txt. Copia y pega el siguiente texto:

    Flask==2.2.2
    functions-framework==3.5.0
    google-cloud-vision==3.4.2
    Werkzeug==2.3.7
    

  10. Haga clic en Implementar.

  11. Cuando la función termine de implementarse, haz clic en la pestaña Activador.

  12. Copia el valor de la URL del activador y guárdalo en algún lugar. Necesitas esta información cuando creas la función remota.

Crea un conjunto de datos

Crea un conjunto de datos llamado remote_function_test:

SQL

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Editor, ejecuta la siguiente instrucción de SQL:

    CREATE SCHEMA `PROJECT_ID.remote_function_test`;
    

    Reemplaza PROJECT_ID con el ID del proyecto.

bq

  1. En la consola de Google Cloud, activa Cloud Shell.

    Activar Cloud Shell

  2. Ejecuta el comando bq mk para crear el conjunto de datos.

      bq mk --dataset --location=us PROJECT_ID:remote_function_test
      

    Reemplaza PROJECT_ID con el ID del proyecto.

Crear una conexión

Crea una conexión llamada lake-connection:

Consola

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. Haz clic en Agregar datos y, luego, en Fuente de datos externa.

  3. En la lista Tipo de conexión, selecciona BigLake y funciones remotas (Cloud Resource).

  4. En el campo ID de conexión, escribe lake-connection.

  5. Haga clic en Crear conexión.

  6. En el panel Información de conexión, copia el valor del campo ID de cuenta de servicio y guárdalo en algún lugar. Necesitarás esta información para otorgar permisos a la cuenta de servicio de la conexión.

bq

  1. En Cloud Shell, ejecuta el comando bq mk para crear la conexión:

    bq mk --connection --location=us --connection_type=CLOUD_RESOURCE \
    lake-connection
    
  2. Ejecuta el comando bq show para recuperar información sobre la conexión:

    bq show --connection us.lake-connection
    
  3. En la columna properties, copia el valor de la propiedad serviceAccountId y guárdalo en algún lugar. Necesitarás esta información para otorgar permisos a la cuenta de servicio de la conexión.

Crea un bucket de Cloud Storage

Crea un bucket de Cloud Storage para contener el conjunto de datos de flores.

Otorga permisos a la cuenta de servicio de las conexiones

Para otorgar permisos a la cuenta de servicio, sigue estos pasos:

  1. Ir a la página IAM y administración

    Ir a IAM y administración

  2. Haz clic en Otorgar acceso.

    Se abre el cuadro de diálogo Agregar principales.

  3. En el campo Principales nuevas (New principals), ingresa el ID de la cuenta de servicio que copiaste antes.

  4. En el campo Selecciona una función, selecciona Cloud Run y, luego, Invocador de Cloud Run.

  5. Haz clic en Agregar otra función.

  6. En el campo Elige una función, elige Cloud Storage y, luego,Visualizador de objetos de Storage.

  7. Haz clic en Guardar.

Sube el conjunto de datos a Cloud Storage

Obtén los archivos de conjuntos de datos y haz que estén disponibles en Cloud Storage:

  1. Descarga el conjunto de datos de flores a tu máquina local.
  2. Sube el conjunto de datos al bucket que creaste antes.

Crea una tabla de objetos

Crea una tabla de objetos llamada sample_images basada en el conjunto de datos de flores que subiste:

SQL

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Editor, ejecuta la siguiente instrucción de SQL:

    CREATE EXTERNAL TABLE remote_function_test.sample_images
    WITH CONNECTION `us.lake-connection`
    OPTIONS(
      object_metadata = 'SIMPLE',
      uris = ['gs://BUCKET_NAME/*']);
    

    Reemplaza BUCKET_NAME por el nombre del bucket que creaste previamente.

bq

En Cloud Shell, ejecuta el comando bq mk para crear la conexión:

bq mk --table \
--external_table_definition=gs:"//BUCKET_NAME/*@us.lake-connection" \
--object_metadata=SIMPLE \
remote_function_test.sample_images

Reemplaza BUCKET_NAME por el nombre del bucket que creaste previamente.

Crea la función remota de BigQuery

Crea una función remota llamada label_detection:

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Editor, ejecuta la siguiente instrucción de SQL:

    CREATE OR REPLACE FUNCTION `remote_function_test.label_detection` (signed_url_ STRING) RETURNS JSON
    REMOTE WITH CONNECTION `us.lake-connection`
    OPTIONS(
    endpoint = 'TRIGGER_URL',
    max_batching_rows = 1
    );
    

    Reemplaza TRIGGER_URL por la URL del activador que guardaste antes. La URL debe ser similar a https://vision-ai-1abcd2efgh-uc.a.run.app.

Llama a la función remota

Llama a la función remota label_detection en la tabla de objetos sample_images:

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. En el panel Editor, ejecuta la siguiente instrucción de SQL:

    SELECT uri, remote_function_test.label_detection(signed_url)
    FROM EXTERNAL_OBJECT_TRANSFORM(
    TABLE remote_function_test.sample_images,
    ["SIGNED_URL"]
    )
    LIMIT 100;
    

    Los resultados debería ser similar al siguiente:

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    | uri                                                           | f0_                                                                                                            |
    —---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    |  gs://bq_huron_demo/flowers/daisy/100080576_f52e8ee070_n.jpg  |  {"face_annotations":[],"label_annotations":[{"confidence":0.0,"description":"Flower",                         |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0c9ph5","properties":[],"score":0.9785631,"topicality":0.9785631},       |
    |                                                               |  {"confidence":0.0,"description":"Plant","locale":"","locations":[],"mid":"/m/05s2s","properties":[],          |
    |                                                               |  "Score":0.9635679,"topicality":0.9635679},{"confidence":0.0,"description":"camomile","locale":"",             |
    |                                                               |  "locations":[],"mid":"/m/011bc8hg","properties":[],"score":0.9110366,"topicality":0.9110366},                 |
    |                                                               |  {"confidence":0.0,"description":"Petal","locale":"","locations":[],"mid":"/m/016q19","properties":[],         |
    |                                                               |  "score":0.8927441,"topicality":0.8927441},{"confidence":0.0,"description":"Chamaemelum nobile","locale":"",   |
    |                                                               |  "locations":[],"mid":"/m/05cmcg","properties":[],"score":0.8460995,"topicality":0.8460995},                   |
    |                                                               |   {"confidence":0.0,"description":"Flowering plant","locale":"","locations":[],"mid":"/m/04sjm",               |
    |                                                               |  "properties":[],"score":0.7642974,"topicality":0.7642974},{"confidence":0.0,"description":"Annual plant",     |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0jqb","properties":[],"score":0.7478164,                                 |
    |                                                               |  "topicality":0.7478164},{"confidence":0.0,"description":"Close-up","locale":"","locations":[],                |
    |                                                               |  "mid":"/m/02cqfm","properties":[],"score":0.7207553,"topicality":0.7207553},{"confidence":0.0,                |
    |                                                               |  "description":"Oxeye daisy","locale":"","locations":[],"mid":"/m/02qvnf","properties":[],                     |
    |                                                               |  "score":0.71786934,"topicality":0.71786934},{"confidence":0.0,"description":"Daisy family","locale":"",       |
    |                                                               |  "locations":[],"mid":"/m/0l5r","properties":[],"score":0.7164383,"topicality":0.7164383}],                    |
    |                                                               |  "landmark_annotations":[],"localized_object_annotations":[],"logo_annotations":[],"text_annotations":[]}      |
    —---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    | gs://bq_huron_demo/flowers/daisy/10140303196_b88d3d6cec.jpg   |  {"face_annotations":[],"label_annotations":[{"confidence":0.0,"description":"Flower","locale":"",             |
    |                                                               |  "locations":[],"mid":"/m/0c9ph5","properties":[],"score":0.9770426,"topicality":0.9770426},                   |
    |                                                               |  {"confidence":0.0,"description":"Plant","locale":"","locations":[],"mid":"/m/05s2s",                          |
    |                                                               |  "Properties":[],"score":0.95798975,"topicality":0.95798975},{"confidence":0.0,                                |
    |                                                               |  "description":"Petal","locale":"","locations":[],"mid":"/m/016q19","properties":[],                           |
    |                                                               |  "score":0.88984144,"topicality":0.88984144},{"confidence":0.0,"description":"Yellow",                         |
    |                                                               |  "locale":"","locations":[],"mid":"/m/088fh","properties":[],"score":0.84456813,                               |
    |                                                               |  "Topicality":0.84456813},{"confidence":0.0,"description":"camomile","locale":"",                              |
    |                                                               |  "locations":[],"mid":"/m/011bc8hg","properties":[],"score":0.7926449, "topicality":0.7926449},                |
    |                                                               |  {"confidence":0.0,"description":"Annual plant","locale":"","locations":[],"mid":"/m/0jqb",                    |
    |                                                               |  "Properties":[],"score":0.75020844, "topicality":0.75020844},{"confidence":0.0,                               |
    |                                                               |  "description":"Flowering plant","locale":"","locations":[],"mid":"/m/04sjm",                                  |
    |                                                               |  "Properties":[],"score":0.7403478,"topicality":0.7403478},{"confidence":0.0,                                  |
    |                                                               |  "description":"Chamaemelum nobile","locale":"","locations":[],"mid":"/m/05cmcg",                              |
    |                                                               |  "Properties":[],"score":0.7264577,"topicality":0.7264577},{"confidence":0.0,                                  |
    |                                                               |  "description":"Close-up","locale":"","locations":[],"mid":"/m/02cqfm","properties":[],                        |
    |                                                               |  "score":0.721242,"topicality":0.721242},{"confidence":0.0,"description":"Daisy family",                       |
    |                                                               |  "locale":"","locations":[],"mid":"/m/0l5r","properties":[],"score":0.7012979,                                 |
    |                                                               |  "Topicality":0.7012979}],"landmark_annotations":[],"localized_object_annotations":[],                         |
    |                                                               |  "logo_annotations":[],"text_annotations":[]}                                                                  |
    —------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------
    
    

Realiza una limpieza

  1. En la consola de Google Cloud, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.