Creazione di richieste batch HTTP per Data Catalog

Ogni connessione HTTP effettuata dall'applicazione richiede un certo overhead. Le richieste API Data Catalog supportano i batch, in modo da combinare diverse chiamate API in un'unica richiesta HTTP. Puoi utilizzare il raggruppamento HTTP in batch se devi effettuare molte richieste di piccole dimensioni e vuoi ridurre al minimo l'overhead delle richieste HTTP. Tieni presente che il raggruppamento in batch riduce l'overhead, ma le richieste all'interno di un batch vengono comunque conteggiate come più richieste ai fini della quota API.

Per la documentazione generica sull'utilizzo del batch HTTP con Google Cloud, consulta la documentazione del client Python dell'API di Google.

Creazione di richieste batch HTTP in Python

Per utilizzare le richieste batch per creare o manipolare le voci in Data Catalog, devi prima cercare le voci che vuoi modificare utilizzando catalog.search() o entries.lookup().

Successivamente, segui questi passaggi per creare una richiesta batch HTTP utilizzando l'API Python di Google:

  1. Crea un oggetto BatchHttpRequest chiamando new_batch_http_request() o con il costruttore BatchHttpRequest(). Puoi passare una richiamata, che verrà chiamata in risposta a ogni richiesta.
  2. Richiama add() sull'oggetto BatchHttpRequest per ogni richiesta da eseguire. Se hai passato un callback durante la creazione dell'oggetto BatchHttpRequest, ogni add() potrebbe includere parametri da trasmettere al callback.
  3. Dopo aver aggiunto le richieste, chiama execute() sull'oggetto BatchHttpRequest per eseguirle. La funzione execute() viene bloccata fino a quando non vengono richiamate tutte le richiamate.

Le richieste in BatchHttpRequest possono essere eseguite in parallelo e non ci sono garanzie in merito all'ordine di esecuzione. Ciò significa che le richieste nello stesso batch non devono dipendere l'una dall'altra. Ad esempio, non devi creare un elemento EntryGroup e un elemento Entry appartenenti all'elemento nella stessa richiesta, poiché la creazione dell'elemento Entry potrebbe essere eseguita prima della creazione dell'elemento EntryGroup (causando la mancata esecuzione dell'esecuzione).

Richieste batch con endpoint a livello di regione

Quando utilizzi le richieste batch HTTP con gli endpoint API a livello di regione di Data Catalog, tutte le richieste API in un batch devono appartenere alla stessa regione. Durante l'esecuzione del batch, devi chiamare l'endpoint a livello di regione corretto. Ad esempio, se le tue risorse si trovano in us-central1, chiama https://us-central1-datacatalog.googleapis.com/batch.

API indipendenti dalla regione

Le API indipendenti dalla regione (come catalog.lookup() e entries.search()) possono essere raggruppate tra loro, ma non devono essere raggruppate con API che dipendono dalla regione. Per le API indipendenti dalla regione, utilizza l'endpoint: https://datacatalog.googleapis.com/batch.

Esempio

Questa applicazione Python di esempio mostra come utilizzare una richiesta batch HTTP per creare più tag da un modello di tag utilizzando l'API Data Catalog.

 
from googleapiclient.discovery import build
from googleapiclient.http import BatchHttpRequest
from oauth2client.service_account import ServiceAccountCredentials
import uuid

#-------------------------------------------------------------#
# 0. Helper and initialization logic
#-------------------------------------------------------------#

# Set the environment configuration.
service_key_file_location = '[SA_PATH]'

project_id = '[MY_PROJECT_ID]'

# Helper container to store results.
class DataContainer:
    def __init__(self):
        self.data = {}

    def callback(self, request_id, response, exception):
        if exception is not None:
            print('request_id: {}, exception: {}'.format(request_id, str(exception)))
            pass
        else:
            print(request_id)
            self.data[request_id] = response

# Helper function to build the Discovery Service config.
def get_service(api_name, api_version, scopes, key_file_location):
    """
    Get a service that communicates to a Google API.

    Args:
        api_name: The name of the API to connect to.
        api_version: The API version to connect to.
        scopes: A list auth scopes to authorize for the application.
        key_file_location: The path to a valid service account JSON key file.

    Returns:
        A service that is connected to the specified API.
    """
    credentials = ServiceAccountCredentials.from_json_keyfile_name(
        key_file_location, scopes=scopes)

    # Build the service object.
    service = build(api_name, api_version, credentials=credentials)

    return service

# Helper function to create a UUID for each request
def generated_uui():
    return str(uuid.uuid4())

def create_batch_request(callback):
    # For more info on supported regions
    # check: https://cloud.google.com/data-catalog/docs/concepts/regions

    region='us-datacatalog.googleapis.com'

    return BatchHttpRequest(batch_uri='https://{}/batch'.format(region), callback=callback)

container = DataContainer()

# Scope to set up the Discovery Service config.
scope = 'https://www.googleapis.com/auth/cloud-platform'

# Create service.
service = get_service(
    api_name='datacatalog',
    api_version='v1',
    scopes=[scope],
    key_file_location=service_key_file_location)

# Create the batch request config.
batch = create_batch_request(container.callback)

#-------------------------------------------------------------#
# 1. Start by fetching a list of entries using search call
#-------------------------------------------------------------#

# Create the search request body.
# This example searches for all BigQuery tables in a project.
search_request_body = {
  'query': 'type=TABLE system=BIGQUERY',
  'scope': {'includeProjectIds': [project_id]}
}

# Generated a unique ID for the request.
request_id = generated_uui()

# Add the request to the batch client.
batch.add(service.catalog().search(body=search_request_body), request_id=request_id)

# Execute the batch request.
batch.execute()

# Uncomment to verify the full response from search.
# print(container.data)

response = container.data[request_id]

results = response['results']

first_table = results[0]

# Verify that a first table is present.
print(first_table)

second_table = results[1]

# Verify that a second table is present
print(second_table)

#-------------------------------------------------------------------#
# 2. Send the batch request to attach tags over the entire result set
#-------------------------------------------------------------------#

# Create a new container
container = DataContainer()

# Create a new batch request
batch = create_batch_request(container.callback)

# Set the template name config
template_name = 'projects/[MY_PROJECT_ID]/locations/[MY-LOCATION]/tagTemplates/[MY-TEMPLATE-NAME]'

for result in results:
    # Generated a unique id for request.
    request_id = generated_uui()

    # Add the entry name as the tag parent.
    parent=result['relativeResourceName']

    # Create the tag request body.
    create_tag_request_body = {
      'template': template_name,
       # CHANGE for your template field values.
      'fields': {'etl_score': {'doubleValue': 0.5}}
    }

    # Add requests to the batch client.
    batch.add(service.projects().locations().
              entryGroups().entries().tags().
              create(body=create_tag_request_body,
                     parent=parent),
              request_id=request_id)

# Execute the batch request.

# Since the Batch Client works with regions
# If you receive [HttpError 400 errors]
# 1. Verify the region you used to create the Batch client
# 2. Verify the region where the Entry is located.
# 3. verify the region of the parent tag template used by the tag.

batch.execute()

# Uncomment to verify the full response from tag creation.
# print(container)