1. Introduction
Présentation
Les fonctions distantes BigQuery vous permettent d'implémenter une fonction dans d'autres langages que SQL et JavaScript, ou avec des bibliothèques et des services non autorisés dans les fonctions définies par l'utilisateur BigQuery. Les fonctions distantes BigQuery offrent une intégration directe avec les fonctions Cloud Run et Cloud Run. Vous pouvez appeler une fonction distante BigQuery dans une requête SQL en prenant une ou plusieurs colonnes comme entrée, puis en renvoyant une seule valeur comme sortie.
Les fonctions Cloud Run sont une solution de calcul légère permettant aux développeurs de créer des fonctions autonomes à usage unique qui peuvent être déclenchées à l'aide de HTTPS ou répondre aux CloudEvents sans avoir à gérer de serveur ni d'environnement d'exécution. Les fonctions Cloud Run sont compatibles avec Node.js, Python, Go, Java, .NET, Ruby et PHP.
Dans cet atelier de programmation, vous apprendrez à créer une fonction distante BigQuery pour obtenir des réponses à une question concernant des images stockées dans Cloud Storage à l'aide de Vertex AI Visual Question Answering (VQA). Votre requête SQL récupérera un URI pour une image à partir d'une table dans BigQuery. Ensuite, à l'aide d'une fonction distante BigQuery, vous enverrez l'URI de l'image à une fonction Cloud Run qui répondra avec les réponses de VQA concernant l'image.
Illustration

Du point de vue du développement, voici les étapes que vous allez suivre dans cet atelier de programmation :
- Créer le point de terminaison HTTP dans les fonctions Cloud Run
- Créer une connexion de type CLOUD_RESOURCE
- Créer une table d'objets BigQuery pour le bucket Cloud Storage
- Créer la fonction distante
- Utiliser la fonction distante dans une requête comme n'importe quelle autre fonction définie par l'utilisateur
Points abordés
- Créer une fonction HTTP Cloud Run en Python
- Créer et utiliser une fonction distante BigQuery dans une requête SQL
- Créer une table d'objets BigQuery
- Utiliser le SDK Vertex AI pour Python afin d'utiliser Visual Question Answering (VQA)
2. Préparation
Prérequis
- Vous êtes connecté à la console Cloud.
- Vous avez déjà déployé une fonction HTTP Cloud Run. Consultez le guide de démarrage rapide Python.
- Vous avez déjà créé un bucket dans Cloud Storage. Consultez le guide de démarrage rapide Cloud Storage.
- Vous disposez des rôles appropriés pour créer un ensemble de données, une table et une fonction distante dans BigQuery. Consultez le guide de démarrage rapide Charger et interroger des données dans BigQuery.
Activer Cloud Shell
- Dans Cloud Console, cliquez sur Activer Cloud Shell
.

Si vous démarrez Cloud Shell pour la première fois, un écran intermédiaire s'affiche pour vous expliquer de quoi il s'agit. Si cet écran s'affiche, cliquez sur Continuer.

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

Cette machine virtuelle est chargée avec tous les outils de développement nécessaires. Elle offre un répertoire personnel persistant de 5 Go et s'exécute dans Google Cloud, ce qui améliore considérablement les performances réseau et l'authentification. Vous pouvez réaliser une grande partie, voire la totalité, des activités de cet atelier de programmation dans un navigateur.
Une fois connecté à Cloud Shell, vous êtes en principe authentifié, et le projet est défini avec votre ID de projet.
- Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list
Résultat de la commande
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud reconnaît votre projet :
gcloud config list project
Résultat de la commande
[core] project = <PROJECT_ID>
Si vous obtenez un résultat différent, exécutez cette commande :
gcloud config set project <PROJECT_ID>
Résultat de la commande
Updated property [core/project].
3. Configurer des variables d'environnement locales
Dans ce code, vous allez créer quelques variables d'environnement pour améliorer la lisibilité des commandes gcloud utilisées dans cet atelier de programmation.
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. Créer la fonction Cloud Run
Pour créer une fonction distante BigQuery, vous devez d'abord créer un point de terminaison HTTP à l'aide de la fonction Cloud Run. Le point de terminaison doit pouvoir traiter un lot de lignes dans une seule requête HTTP POST et renvoyer les résultats du lot sous forme de réponse HTTP.
Cette fonction Cloud Run recevra l'URI de stockage de l'image et l'invite de question comme entrée de votre requête SQL, et renverra la réponse de Visual Question Answering (VQA).
Cet atelier de programmation utilise un exemple pour l'environnement d'exécution python311 à l'aide du SDK Vertex AI pour Python.
Créer le code source de la fonction
Commencez par créer un répertoire et à vous y déplacer.
mkdir imagen-vqa && cd $_
Créez ensuite un fichier requirements.txt.
google-cloud-aiplatform[preview] google-cloud-storage functions-framework==3.*
Créez ensuite un fichier source 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
Déployer la fonction Cloud Run
Vous pouvez maintenant déployer votre fonction Cloud Run pour l'environnement d'exécution python311.
Pour déployer une fonction Cloud Run directement sur Cloud Run, exécutez la commande suivante :
gcloud beta run deploy $FUNCTION_NAME \
--source . \
--function imagen_vqa \
--region $FUNCTION_REGION \
--no-allow-unauthenticated
Si vous préférez déployer en tant que Cloud Functions 2nd gen, utilisez la commande suivante :
gcloud functions deploy $FUNCTION_NAME \ --gen2 \ --region=$FUNCTION_REGION \ --runtime=python311 \ --trigger-http \ --source=. \ --no-allow-unauthenticated
Vous pouvez ensuite enregistrer l'URL de la fonction en tant que variable d'environnement pour l'utiliser ultérieurement.
ENDPOINT_URL="$(gcloud beta run services describe $FUNCTION_NAME --region $FUNCTION_REGION --format='value(status.url)')"
5. Créer le bucket Cloud Storage
Commencez par créer un bucket Cloud Storage pour stocker vos images.
gcloud storage buckets create gs://$BUCKET_NAME
Ensuite, importez une image à utiliser pour VQA. Cet atelier de programmation utilise l' exemple d'image de la documentation VQA.
Vous pouvez utiliser Cloud Console pour Cloud Storage afin d'importer l'image directement dans votre bucket. Vous pouvez également exécuter les commandes suivantes pour télécharger l' exemple d'image dans votre répertoire Cloud Shell actuel
wget -O image.jpg -o /dev/null https://unsplash.com/photos/QqN25A3iF9w/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjk1NzYxMjY2fA&force=true
puis l'importer dans votre bucket Cloud Storage.
gcloud storage cp image.jpg gs://$BUCKET_NAME
6. Créer une connexion aux ressources Cloud BigQuery
BigQuery utilise une connexion CLOUD_RESOURCE pour interagir avec votre fonction Cloud. Exécutez la commande suivante pour créer cette connexion.
bq mk --connection --location=$BQ_REGION --project_id=$PROJECT_ID \ --connection_type=CLOUD_RESOURCE $CONNECTION_ID
Affichez ensuite les détails de la nouvelle connexion BigQuery.
bq show --connection $PROJECT_ID.$BQ_REGION.$CONNECTION_ID
Enregistrez le nom du compte de service de connexion BigQuery dans une variable, comme indiqué.
CONNECTION_SA="<YOUR-SERVICE-ACCOUNT-ID>@gcp-sa-bigquery-condel.iam.gserviceaccount.com"
Accordez l'accès au compte de service pour accéder à votre bucket Cloud Storage.
gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME
7. Créer une table d'objets BigQuery
Les tables d'objets BigQuery sont des tables en lecture seule sur des objets de données non structurés stockés dans Cloud Storage.
Les tables d'objets vous permettent d'analyser des données non structurées dans Cloud Storage. Vous pouvez effectuer une analyse avec des fonctions distantes, puis joindre les résultats de ces opérations aux autres données structurées dans BigQuery.
Commencez par créer un ensemble de données.
bq --location=$BQ_REGION mk \
--dataset \
$DATASET_ID
La commande suivante crée une table d'objets basée sur votre bucket d'images Cloud Storage. La table résultante contiendra les URI de toutes les images de ce bucket.
bq mk --table \ --external_table_definition=gs://$BUCKET_NAME/*@$BQ_REGION.$CONNECTION_ID \ --object_metadata=SIMPLE \ $PROJECT_ID:$DATASET_ID.$TABLE_NAME
8. Créer la fonction distante BigQuery
La dernière étape consiste à configurer la fonction distante BigQuery.
Commencez par accorder au compte de service de connexion BigQuery les autorisations nécessaires pour appeler la fonction Cloud Run. Il n'est pas recommandé d'autoriser l'appel non authentifié pour votre service de fonction Cloud Run.
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --member=serviceAccount:$CONNECTION_SA \ --role="roles/run.invoker" \ --region $FUNCTION_REGION
Ensuite, enregistrez la requête SQL dans une 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' )"
Exécutez maintenant la requête.
bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION
Après avoir exécuté la requête pour créer la fonction distante, vous verrez Created <your-project-id>.remote_function_codelab.vqa.
9. Appeler la fonction distante BigQuery dans une requête SQL
Vous avez maintenant terminé les étapes de développement pour créer la fonction distante. Vous pouvez maintenant appeler votre fonction Cloud Run à partir d'une requête SQL.
Commencez par enregistrer votre question et votre requête SQL dans une variable. Cet atelier de programmation utilise l'exemple de la documentation Visual Question Answering. Cette requête utilise la dernière image ajoutée à votre bucket de stockage.
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; "
Exécutez ensuite la requête SQL pour afficher la réponse du service Vertex AI Visual Question Answering (VQA).
bq query --nouse_legacy_sql $SQL_QUERY
Les résultats doivent ressembler à l'exemple de sortie ci-dessous :
+---------------------------------+--------------------------------+----------+ | uri | image_prompt | result | +---------------------------------+--------------------------------+----------+ | gs://<YOUR_BUCKET>/image.jpg | What objects are in the image? | marbles | +---------------------------------+--------------------------------+----------+
10. Dépannage
Lorsque vous créez la table BigQuery, si vous recevez une erreur BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME, assurez-vous d'avoir inclus le chemin d'accès /* après $BUCKET_NAME dans la commande.
Lorsque vous exécutez votre requête SQL, si vous obtenez une erreur Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint>, essayez d'attendre environ 1 à 2 minutes que l'autorisation du rôle Invoker de Cloud Functions se propage au compte de service de connexion BigQuery avant de réessayer.
11. Félicitations !
Bravo ! Vous avez terminé cet atelier de programmation.
Nous vous recommandons de consulter la documentation sur les fonctions distantes BigQuery et Visual Question Answering (VQA).
Points abordés
- Configurer l'authentification sur une fonction Cloud Run et vérifier qu'elle est correctement configurée
- Appeler une fonction authentifiée à partir d'un environnement de développement local en fournissant le jeton de votre identité gcloud
- Créer un compte de service et lui accorder le rôle approprié pour appeler une fonction
- Emprunter l'identité d'un service à partir d'un environnement de développement local disposant des rôles appropriés pour appeler une fonction
12. Effectuer un nettoyage
Pour éviter des frais involontaires (par exemple, si cette fonction Cloud Run est appelée par inadvertance plus de fois que votre allocation mensuelle d'appels de fonction Cloud Run dans le niveau sans frais), vous pouvez supprimer la fonction Cloud ou le projet que vous avez créé à l'étape 2.
Pour supprimer la fonction Cloud Run, accédez à Cloud Console Cloud Run sur https://console.cloud.google.com/functions/, puis supprimez la fonction imagen-vqa (ou $FUNCTION_NAME si vous avez utilisé un autre nom).
Si vous choisissez de supprimer l'ensemble du projet, vous pouvez accéder à https://console.cloud.google.com/cloud-resource-manager, sélectionner le projet que vous avez créé à l'étape 2, puis choisir "Supprimer". Si vous supprimez le projet, vous devrez modifier les projets dans votre SDK Cloud. Vous pouvez afficher la liste de tous les projets disponibles en exécutant gcloud projects list.