1. Introducción
Descripción general
Las funciones remotas de BigQuery te permiten implementar una función en lenguajes distintos de SQL y JavaScript, o con las bibliotecas y los servicios no permitidos en las funciones definidas por el usuario de BigQuery. Las funciones remotas de BigQuery proporcionan una integración directa con Cloud Run Functions y Cloud Run. Puedes invocar una función remota de BigQuery dentro de una consulta en SQL tomando una o más columnas como entrada y, luego, devolviendo un solo valor como resultado.
Cloud Run Functions es una solución de procesamiento ligera que permite a los desarrolladores crear funciones independientes y de un solo propósito que se pueden activar con HTTPS o responder a CloudEvents sin necesidad de administrar un servidor o un entorno de ejecución. Cloud Run Functions admite Node.js, Python, Go, Java, .NET, Ruby y PHP.
En este codelab, aprenderás a crear una función remota de BigQuery para obtener respuestas a una pregunta sobre imágenes almacenadas en Cloud Storage con la búsqueda de respuestas visuales (VQA) de Vertex AI. Tu consulta en SQL recuperará un URI para una imagen de una tabla en BigQuery. Luego, con una función remota de BigQuery, enviarás el URI de la imagen a una Cloud Run Function que responderá con respuestas de VQA sobre la imagen.
Ilustración

Desde una perspectiva de desarrollo, estos son los pasos que completarás en este codelab:
- Crea el extremo HTTP en Cloud Run Functions
- Crea una conexión de tipo CLOUD_RESOURCE
- Crea una tabla de objetos de BigQuery para el bucket de Cloud Storage
- Crea la función remota
- Usa la función remota en una consulta como cualquier otra función definida por el usuario
Qué aprenderás
- Cómo crear una función de HTTP de Cloud Run en Python
- Cómo crear y usar una función remota de BigQuery en una consulta en SQL
- Cómo crear una tabla de objetos de BigQuery
- Cómo usar el SDK de Vertex AI para Python para usar la búsqueda de respuestas visuales (VQA)
2. Configuración y requisitos
Requisitos previos
- Accediste a la consola de Cloud.
- Ya implementaste una función de HTTP de Cloud Run. Consulta la guía de inicio rápido de Python.
- Ya creaste un bucket en Cloud Storage. Consulta la guía de inicio rápido de Cloud Storage.
- Tienes los roles adecuados para crear un conjunto de datos, una tabla y una función remota en BigQuery. Consulta la guía de inicio rápido Carga y consulta datos en BigQuery.
Activar Cloud Shell
- En la consola de Cloud, haz clic en Activar Cloud Shell
.

Si es la primera vez que inicias Cloud Shell, aparecerá una pantalla intermedia en la que se describirá qué es. Si apareció una pantalla intermedia, haz clic en Continuar.

El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.

Esta máquina virtual está cargada con todas las herramientas de desarrollo necesarias. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer con un navegador.
Una vez que te conectes a Cloud Shell, deberías ver que te autenticaste y que el proyecto se configuró con tu ID del proyecto.
- En Cloud Shell, ejecuta el siguiente comando para confirmar que tienes la autenticación:
gcloud auth list
Resultado del comando
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- En Cloud Shell, ejecuta el siguiente comando para confirmar que el comando gcloud conoce tu proyecto:
gcloud config list project
Resultado del comando
[core] project = <PROJECT_ID>
De lo contrario, puedes configurarlo con el siguiente comando:
gcloud config set project <PROJECT_ID>
Resultado del comando
Updated property [core/project].
3. Configura variables de entorno locales
En este código, crearás algunas variables de entorno para mejorar la legibilidad de los comandos gcloud que se usan en este codelab.
PROJECT_ID=$(gcloud config get-value project) # Cloud Function variables FUNCTION_NAME="imagen-vqa" FUNCTION_REGION="us-central1" # Cloud Function variables BUCKET_NAME=$PROJECT_ID-imagen-vqa # BigQuery variables DATASET_ID="remote_function_codelab" TABLE_NAME="images" BQ_REGION="US" CONNECTION_ID="imagen_vqa_connection"
4. Crea la función de Cloud Run
Para crear una función remota de BigQuery, primero debes crear un extremo HTTP con Cloud Run Function. El extremo debe poder procesar un lote de filas en una sola solicitud POST HTTP y mostrar los resultados para el lote como una respuesta HTTP.
Esta función de Cloud Run recibirá la URI de almacenamiento de la imagen y la instrucción de la pregunta como entrada de tu consulta de SQL, y devolverá la respuesta de la búsqueda de respuestas visuales (VQA).
En este codelab, se usa un ejemplo del tiempo de ejecución de Python 3.11 con el SDK de Vertex AI para Python.
Crea el código fuente de la función
Primero, crea un directorio y ábrelo con el comando cd.
mkdir imagen-vqa && cd $_
Luego, crea un archivo requirements.txt.
google-cloud-aiplatform[preview] google-cloud-storage functions-framework==3.*
A continuación, crea un archivo fuente main.py.
from vertexai.preview.vision_models import ImageQnAModel
from vertexai.preview.vision_models import Image
from flask import jsonify
from google.cloud import storage
from urllib.parse import urlparse
import functions_framework
# This is the entry point for the cloud function
@functions_framework.http
def imagen_vqa(request):
try:
# See if you can parse the incoming JSON
return_value = []
request_json = request.get_json()
# This grabs the input into the function as called from the SQL function
calls = request_json['calls']
for call in calls:
# We call the VQA function here in another function defined below
ai_result = vqa(call)
# The result to BigQuery is in the order it was prepared in
return_value.append(ai_result[0])
# Prepare the response back to BigQuery
return_json = jsonify( { "replies": return_value } )
return return_json
except Exception as e:
return jsonify( { "errorMessage": str(e) } ), 400
# Helper function to split apart the GCS URI
def decode_gcs_url(url):
# Read the URI and parse it
p = urlparse(url)
bucket = p.netloc
file_path = p.path[0:].split('/', 1)
# Return the relevant objects (bucket, path to object)
return bucket, file_path[1]
# We can't use the image load from local file since it expects a local path
# We use a GCS URL and get the bytes of the image
def read_file(object_path):
# Parse the path
bucket, file_path = decode_gcs_url(object_path)
storage_client = storage.Client()
bucket = storage_client.bucket(bucket)
blob = bucket.blob(file_path)
# Return the object as bytes
return blob.download_as_bytes()
# This is the function that calls the VQA function
def vqa (parameters):
# This is the model we want to use
image_qna_model = ImageQnAModel.from_pretrained("imagetext@001")
# The location is the first parameter
image_loc = parameters[0]
# Get the bytes
image_bytes = read_file(image_loc)
# Load the bytes into the Image handler
input_image = Image(image_bytes)
# Ask the VQA the question
results = image_qna_model.ask_question(
image=input_image,
# The prompt was the second parameter
question=parameters[1],
number_of_results=1
)
return results
Implementa la Cloud Run function
Ahora puedes implementar tu función de Cloud Run para el entorno de ejecución de Python 3.11.
Para implementar una función de Cloud Run directamente en Cloud Run, ejecuta el siguiente comando:
gcloud beta run deploy $FUNCTION_NAME \
--source . \
--function imagen_vqa \
--region $FUNCTION_REGION \
--no-allow-unauthenticated
Si prefieres realizar la implementación como Cloud Functions 2nd gen, usa el siguiente comando:
gcloud functions deploy $FUNCTION_NAME \ --gen2 \ --region=$FUNCTION_REGION \ --runtime=python311 \ --trigger-http \ --source=. \ --no-allow-unauthenticated
Luego, puedes guardar la URL de la función como una variable de entorno para usarla más adelante.
ENDPOINT_URL="$(gcloud beta run services describe $FUNCTION_NAME --region $FUNCTION_REGION --format='value(status.url)')"
5. Crea el bucket de Cloud Storage
Primero, crea un bucket de Cloud Storage para almacenar tus imágenes.
gcloud storage buckets create gs://$BUCKET_NAME
A continuación, sube una imagen para que la use la VQA. En este codelab, se usa la imagen de ejemplo de la documentación de VQA.
Puedes usar la consola de Cloud para Cloud Storage y subir la imagen directamente a tu bucket. También puedes ejecutar los siguientes comandos para descargar la imagen de ejemplo en tu directorio actual de Cloud Shell.
wget -O image.jpg -o /dev/null https://unsplash.com/photos/QqN25A3iF9w/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjk1NzYxMjY2fA&force=true
y, luego, súbelo a tu bucket de Cloud Storage.
gcloud storage cp image.jpg gs://$BUCKET_NAME
6. Crea una conexión de recurso de Cloud en BigQuery
BigQuery usa una conexión CLOUD_RESOURCE para interactuar con tu Cloud Function. Ejecuta el siguiente comando para crear esta conexión.
bq mk --connection --location=$BQ_REGION --project_id=$PROJECT_ID \ --connection_type=CLOUD_RESOURCE $CONNECTION_ID
A continuación, muestra los detalles de la nueva conexión de BigQuery.
bq show --connection $PROJECT_ID.$BQ_REGION.$CONNECTION_ID
Guarda el nombre de la cuenta de servicio de conexión de BigQuery en una variable, como se muestra a continuación.
CONNECTION_SA="<YOUR-SERVICE-ACCOUNT-ID>@gcp-sa-bigquery-condel.iam.gserviceaccount.com"
Otorga acceso a la cuenta de servicio para que pueda acceder a tu bucket de Cloud Storage.
gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME
7. Crea una tabla de objetos de BigQuery
Las tablas de objetos de BigQuery son tablas de solo lectura sobre objetos de datos no estructurados que residen en Cloud Storage.
Las tablas de objetos te permiten analizar datos no estructurados en Cloud Storage. Puedes realizar análisis con funciones remotas y, luego, unir los resultados de estas operaciones con el resto de tus datos estructurados en BigQuery.
Primero, crea un conjunto de datos.
bq --location=$BQ_REGION mk \
--dataset \
$DATASET_ID
El siguiente comando crea una tabla de objetos basada en tu bucket de imágenes de Cloud Storage. La tabla resultante contendrá los URIs de todas las imágenes de ese bucket.
bq mk --table \ --external_table_definition=gs://$BUCKET_NAME/*@$BQ_REGION.$CONNECTION_ID \ --object_metadata=SIMPLE \ $PROJECT_ID:$DATASET_ID.$TABLE_NAME
8. Crea la función remota de BigQuery
El último paso es configurar la función remota de BigQuery.
Primero, otorga permisos a la cuenta de servicio de conexión de BigQuery para invocar la función de Cloud Run. No se recomienda permitir la invocación no autenticada para el servicio de funciones de Cloud Run.
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --member=serviceAccount:$CONNECTION_SA \ --role="roles/run.invoker" \ --region $FUNCTION_REGION
A continuación, guarda la consulta en SQL en una variable.
SQL_CREATE_FUNCTION="CREATE FUNCTION \`$PROJECT_ID.$DATASET_ID\`.vqa(uri STRING, image_prompt STRING) RETURNS STRING REMOTE WITH CONNECTION \`$PROJECT_ID.$BQ_REGION.$CONNECTION_ID\` OPTIONS ( endpoint = '$ENDPOINT_URL' )"
Ahora, ejecuta la consulta.
bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION
Después de ejecutar la consulta para crear la función remota, verás Created <your-project-id>.remote_function_codelab.vqa.
9. Llama a la función remota de BigQuery en una consulta de SQL
Ya completaste los pasos de desarrollo para crear la función remota. Ahora puedes llamar a tu función de Cloud Run desde una consulta en SQL.
Primero, guarda tu pregunta y consulta en SQL en una variable. En este codelab, se usa el ejemplo de la documentación de Visual Question Answering. Esta consulta usa la imagen más reciente que se agregó a tu bucket de almacenamiento.
export SQL_QUERY="DECLARE question STRING DEFAULT 'What objects are in the image?'; SELECT uri, image_prompt ,\`$DATASET_ID\`.vqa(uri, image_prompt) as result FROM ( SELECT *, dense_rank() over (order by updated) as rnk , question as image_prompt FROM \`$PROJECT_ID.$DATASET_ID.images\`) as innertable WHERE rnk = 1; "
Luego, ejecuta la consulta de SQL para mostrar la respuesta del servicio de búsqueda de respuestas visuales (VQA) de Vertex AI.
bq query --nouse_legacy_sql $SQL_QUERY
Los resultados deberían ser similares al siguiente ejemplo:
+---------------------------------+--------------------------------+----------+ | uri | image_prompt | result | +---------------------------------+--------------------------------+----------+ | gs://<YOUR_BUCKET>/image.jpg | What objects are in the image? | marbles | +---------------------------------+--------------------------------+----------+
10. Solución de problemas
Cuando crees la tabla de BigQuery, si recibes un error BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME, asegúrate de haber incluido la ruta de acceso /* después de $BUCKET_NAME en el comando.
Cuando ejecutes tu consulta SQL, si recibes un error Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint>, espera entre 1 y 2 minutos a que el permiso del rol de Cloud Function Invoker se propague a la cuenta de servicio de conexión de BigQuery antes de volver a intentarlo.
11. ¡Felicitaciones!
¡Felicitaciones por completar el codelab!
Te recomendamos que revises la documentación sobre las funciones remotas de BigQuery y la búsqueda de respuestas visuales (VQA).
Temas abordados
- Cómo configurar la autenticación en una Cloud Run Function y verificar que se haya configurado correctamente
- Invoca una función autenticada desde un entorno de desarrollo local proporcionando el token de tu identidad de gcloud
- Cómo crear una cuenta de servicio y otorgarle el rol adecuado para invocar una función
- Cómo suplantar la identidad de un servicio desde un entorno de desarrollo local que tiene los roles adecuados para invocar una función
12. Limpia
Para evitar cargos involuntarios (por ejemplo, si esta función de Cloud Run se invoca de forma involuntaria más veces que tu asignación mensual de invocaciones de funciones de Cloud Run en el nivel gratuito), puedes borrar la Cloud Function o el proyecto que creaste en el paso 2.
Para borrar la función de Cloud Run, ve a la consola de Cloud Run en https://console.cloud.google.com/functions/ y borra la función imagen-vqa (o $FUNCTION_NAME en caso de que hayas usado otro nombre).
Si decides borrar todo el proyecto, puedes ir a https://console.cloud.google.com/cloud-resource-manager, seleccionar el proyecto que creaste en el paso 2 y elegir Borrar. Si borras el proyecto, deberás cambiar de proyecto en el SDK de Cloud. Para ver la lista de todos los proyectos disponibles, ejecuta gcloud projects list.