Esta página lo guía a través del uso de Python para realizar solicitudes HTTP a la API de análisis conversacional (a la que se accede a través de geminidataanalytics.googleapis.com
).
El código Python de muestra en esta página muestra cómo completar las siguientes tareas:
- Configurar los ajustes iniciales y la autenticación
- Conectarse a una fuente de datos de Looker, BigQuery o Looker Studio
- Crear un agente de datos
- Crear una conversación
- Utilice la API para hacer preguntas
También puedes ejecutar los ejemplos de código de esta página en el cuaderno de colaboración HTTP de la API de análisis conversacional .
Se incluye una versión completa del código de muestra al final de la página, junto con las funciones auxiliares que se utilizan para transmitir la respuesta de la API.
Configurar los ajustes iniciales y la autenticación
El siguiente código Python de ejemplo realiza estas tareas:
- Importa las bibliotecas de Python necesarias
- Define variables para el proyecto de facturación, instrucciones del sistema y una pregunta para el agente de datos.
- Obtiene un token de acceso para la autenticación HTTP mediante la CLI de Google Cloud
from pygments import highlight, lexers, formatters
import pandas as pd
import json as json_lib
import requests
import json
import altair as alt
import IPython
from IPython.display import display, HTML
import google.auth
from google.auth.transport.requests import Request
from google.colab import auth
auth.authenticate_user()
billing_project = 'YOUR-BILLING-PROJECT'
system_description = 'YOUR-SYSTEM-INSTRUCTIONS'
question = 'YOUR-QUESTION-HERE'
access_token = !gcloud auth application-default print-access-token
headers = {
"Authorization": f"Bearer {access_token[0]}",
"Content-Type": "application/json",
}
Reemplace los valores de muestra de la siguiente manera:
- YOUR-BILLING-PROJECT : El ID del proyecto de facturación donde ha habilitado las API requeridas .
- YOUR-SYSTEM-INSTRUCTIONS : Instrucciones del sistema para guiar el comportamiento del agente y permitirle personalizarlo según sus necesidades. Por ejemplo, puede usar las instrucciones del sistema para definir términos comerciales (como qué constituye un "cliente fiel"), controlar la longitud de la respuesta ("resumir en menos de 20 palabras") o configurar el formato de los datos ("adaptarse a los estándares de la empresa"). Reemplace el texto del marcador de posición con instrucciones relevantes para sus datos y caso de uso.
- YOUR-QUESTION-HERE : Una pregunta en lenguaje natural para enviar al agente de datos.
Autenticarse en Looker
Si planea conectarse a una fuente de datos de Looker, deberá autenticarse en la instancia de Looker.
Uso de claves API
El siguiente ejemplo de código Python demuestra cómo autenticar su agente en una instancia de Looker usando claves API.
looker_credentials = {
"oauth": {
"secret": {
"client_id": "YOUR-LOOKER-CLIENT-ID",
"client_secret": "YOUR-LOOKER-CLIENT-SECRET",
}
}
}
Reemplace los valores de muestra de la siguiente manera:
- YOUR-LOOKER-CLIENT-ID : El ID de cliente de su clave API de Looker generada.
- YOUR-LOOKER-CLIENT-SECRET : El secreto del cliente de su clave API de Looker generada.
Uso de tokens de acceso
El siguiente ejemplo de código Python demuestra cómo autenticar su agente en una instancia de Looker usando tokens de acceso.
looker_credentials = {
"oauth": {
"token": {
"access_token": "YOUR-TOKEN",
}
}
}
Reemplace los valores de muestra de la siguiente manera:
- YOUR-TOKEN : El valor de
access_token
que genera para autenticarse en Looker.
Conectarse a una fuente de datos
Los siguientes ejemplos de código de Python demuestran cómo definir la fuente de datos Looker , BigQuery o Looker Studio para que los use su agente.
Conectarse a los datos de Looker
El siguiente código de ejemplo define una conexión con Looker Explore. Para establecer una conexión con una instancia de Looker, verifique que haya generado las claves de API de Looker, como se describe en Autenticar y conectarse a una fuente de datos con la API de Conversational Analytics .
looker_data_source = {
"looker": {
"explore_references": {
"looker_instance_uri": "https://your_company.looker.com",
"lookml_model": "your_model",
"explore": "your_explore",
},
}
}
Reemplace los valores de muestra de la siguiente manera:
- https://your_company.looker.com : la URL completa de su instancia de Looker.
- your_model : el nombre del modelo LookML que incluye el Explore al que desea conectarse.
- your_explore : el nombre del Looker Explore que desea que el agente de datos consulte.
Conectarse a los datos de BigQuery
El siguiente código de muestra define una conexión a una tabla de BigQuery.
bigquery_data_sources = {
"bq" : {
"tableReferences": [
{
"projectId": "bigquery-public-data",
"datasetId": "san_francisco",
"tableId": "street_trees",
}
]
}
}
Reemplace los valores de muestra de la siguiente manera:
- bigquery-public-data : El ID de la Google Cloud Proyecto que contiene el conjunto de datos y la tabla de BigQuery a los que desea conectarse. Para conectarse a un conjunto de datos público , especifique
bigquery-public-data
. - san_francisco : el ID del conjunto de datos de BigQuery.
- street_trees : el ID de la tabla de BigQuery.
Conectarse a los datos de Looker Studio
El siguiente código de muestra define una conexión a una fuente de datos de Looker Studio.
looker_studio_data_source = {
"studio":{
"studio_references":
[
{
"studio_datasource_id": "studio_datasource_id"
}
]
}
}
Reemplace studio_datasource_id con el ID de la fuente de datos.
Crear un agente de datos
El siguiente código de ejemplo muestra cómo crear el agente de datos mediante el envío de una solicitud HTTP POST
al punto de conexión de creación del agente de datos. La carga útil de la solicitud incluye los siguientes detalles:
- El nombre completo del recurso del agente. Este valor incluye el ID del proyecto, la ubicación y un identificador único del agente.
- Descripción del agente de datos.
- El contexto del agente de datos, incluida la descripción del sistema (definida en Configurar ajustes iniciales y autenticación ) y la fuente de datos que utiliza el agente (definida en Conectarse a una fuente de datos ).
También puede habilitar opcionalmente el análisis avanzado con Python incluyendo el parámetro options
en la carga útil de la solicitud.
data_agent_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}/dataAgents"
data_agent_id = "data_agent_1"
data_agent_payload = {
"name": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}", # Optional
"description": "This is the description of data_agent_1.", # Optional
"data_analytics_agent": {
"published_context": {
"datasource_references": bigquery_data_sources,
"system_instruction": system_instruction,
# Optional: To enable advanced analysis with Python, include the following options block:
"options": {
"analysis": {
"python": {
"enabled": True
}
}
}
}
}
}
params = {"data_agent_id": data_agent_id} # Optional
data_agent_response = requests.post(
data_agent_url, params=params, json=data_agent_payload, headers=headers
)
if data_agent_response.status_code == 200:
print("Data Agent created successfully!")
print(json.dumps(data_agent_response.json(), indent=2))
else:
print(f"Error creating Data Agent: {data_agent_response.status_code}")
print(data_agent_response.text)
Reemplace los valores de muestra de la siguiente manera:
- data_agent_1 : Un identificador único para el agente de datos. Este valor se utiliza en el nombre del recurso del agente y como parámetro de consulta URL
data_agent_id
. - This is the description of data_agent_1. : Una descripción para el agente de datos.
Crear una conversación
El siguiente código de muestra demuestra cómo crear una conversación con su agente de datos.
conversation_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}/conversations"
data_agent_id = "data_agent_1"
conversation_id = "conversation_1"
conversation_payload = {
"agents": [
f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}"
],
"name": f"projects/{billing_project}/locations/{location}/conversations/{conversation_id}"
}
params = {
"conversation_id": conversation_id
}
conversation_response = requests.post(conversation_url, headers=headers, params=params, json=conversation_payload)
if conversation_response.status_code == 200:
print("Conversation created successfully!")
print(json.dumps(conversation_response.json(), indent=2))
else:
print(f"Error creating Conversation: {conversation_response.status_code}")
print(conversation_response.text)
Reemplace los valores de muestra de la siguiente manera:
- data_agent_1 : el ID del agente de datos, como se define en el bloque de código de muestra en Crear un agente de datos .
- conversation_1 : Un identificador único para la conversación.
Utilice la API para hacer preguntas
Después de haber creado un agente de datos y una conversación , puede realizar preguntas sobre sus datos mediante uno de los siguientes métodos:
- Chat con estado : Google Cloud Almacena y gestiona el historial de conversaciones. Solo necesitas enviar el mensaje actual en cada turno.
- Chat sin estado : su aplicación es responsable de mantener el historial de conversaciones. Google Cloud No se almacena el historial de conversaciones entre solicitudes. Debes incluir los mensajes anteriores relevantes junto con el nuevo mensaje de cada turno.
Para obtener más información sobre las conversaciones multiturno, consulte Crear una conversación multiturno .
Chat con estado
Enviar una solicitud de chat con estado con una referencia de conversación
El siguiente código de ejemplo muestra cómo formular preguntas a la API mediante la conversación definida en los pasos anteriores. Este ejemplo utiliza la función auxiliar get_stream
para transmitir la respuesta.
chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}:chat"
data_agent_id = "data_agent_1"
conversation_id = "conversation_1"
# Construct the payload
chat_payload = {
"parent": f"projects/{billing_project}/locations/global",
"messages": [
{
"userMessage": {
"text": "Make a bar graph for the top 5 states by the total number of airports"
}
}
],
"conversation_reference": {
"conversation": f"projects/{billing_project}/locations/{location}/conversations/{conversation_id}",
"data_agent_context": {
"data_agent": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}",
# "credentials": looker_credentials
}
}
}
# Call the get_stream function to stream the response
get_stream(chat_url, chat_payload)
Reemplace los valores de muestra de la siguiente manera:
- data_agent_1 : el ID del agente de datos, como se define en el bloque de código de muestra en Crear un agente de datos .
- conversation_1 : Un identificador único para la conversación.
- Se utilizó como ejemplo
Make a bar graph for the top 5 states by the total number of airports
.
Chat sin estado
Enviar una solicitud de chat sin estado con una referencia de agente de datos
El siguiente código de ejemplo muestra cómo formular una pregunta sin estado a la API mediante el agente de datos definido en los pasos anteriores. Este ejemplo utiliza la función auxiliar get_stream
para transmitir la respuesta.
chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}:chat"
data_agent_id = "data_agent_1"
# Construct the payload
chat_payload = {
"parent": f"projects/{billing_project}/locations/global",
"messages": [
{
"userMessage": {
"text": "Make a bar graph for the top 5 states by the total number of airports"
}
}
],
"data_agent_context": {
"data_agent": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}",
# "credentials": looker_credentials
}
}
# Call the get_stream function to stream the response
get_stream(chat_url, chat_payload)
Reemplace los valores de muestra de la siguiente manera:
- data_agent_1 : el ID del agente de datos, como se define en el bloque de código de muestra en Crear un agente de datos .
- Se utilizó como ejemplo
Make a bar graph for the top 5 states by the total number of airports
.
Enviar una solicitud de chat sin estado con contexto en línea
El siguiente código de ejemplo muestra cómo formular una pregunta sin estado a la API mediante contexto en línea. Este ejemplo utiliza una función auxiliar get_stream
para transmitir la respuesta y utiliza una fuente de datos de BigQuery como ejemplo.
También puede habilitar opcionalmente el análisis avanzado con Python incluyendo el parámetro options
en la carga útil de la solicitud.
chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/global:chat"
# Construct the payload
chat_payload = {
"parent": f"projects/{billing_project}/locations/global",
"messages": [
{
"userMessage": {
"text": "Make a bar graph for the top 5 states by the total number of airports"
}
}
],
"inline_context": {
"datasource_references": bigquery_data_sources,
# Optional: To enable advanced analysis with Python, include the following options block:
"options": {
"analysis": {
"python": {
"enabled": True
}
}
}
}
}
# Call the get_stream function to stream the response
get_stream(chat_url, chat_payload)
Ejemplo de código de extremo a extremo
El siguiente ejemplo de código expansible contiene todas las tareas que se tratan en esta guía.
Construya un agente de datos usando HTTP y Python
from pygments import highlight, lexers, formatters import pandas as pd import json as json_lib import requests import json import altair as alt import IPython from IPython.display import display, HTML import requests import google.auth from google.auth.transport.requests import Request from google.colab import auth auth.authenticate_user() access_token = !gcloud auth application-default print-access-token headers = { "Authorization": f"Bearer {access_token[0]}", "Content-Type": "application/json", } ################### Data source details ################### billing_project = "your_billing_project" location = "global" system_instruction = "Help the user in analyzing their data" # BigQuery data source bigquery_data_sources = { "bq": { "tableReferences": [ { "projectId": "bigquery-public-data", "datasetId": "san_francisco", "tableId": "street_trees" } ] } } # Looker data source looker_credentials = { "oauth": { "secret": { "client_id": "your_looker_client_id", "client_secret": "your_looker_client_secret", } } } # # To use access_token for authentication, uncomment the following looker_credentials code block and comment out the previous looker_credentials code block. # looker_credentials = { # "oauth": { # "token": { # "access_token": "your_looker_access_token", # } # } # } looker_data_source = { "looker": { "explore_references": { "looker_instance_uri": "https://my_company.looker.com", "lookml_model": "my_model", "explore": "my_explore", }, # "credentials": looker_credentials # Uncomment this when using looker as datasource in stateless chat } } # Looker Studio data source looker_studio_data_source = { "studio":{ "studio_references": [ { "datasource_id": "your_studio_datasource_id" } ] } } ################### Create data agent ################### data_agent_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}/dataAgents" data_agent_id = "data_agent_1" data_agent_payload = { "name": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}", # Optional "description": "This is the description of data_agent.", # Optional "data_analytics_agent": { "published_context": { "datasource_references": bigquery_data_sources, "system_instruction": system_instruction, # Optional: To enable advanced analysis with Python, include the following options block: "options": { "analysis": { "python": { "enabled": True } } } } } } params = {"data_agent_id": data_agent_id} # Optional data_agent_response = requests.post( data_agent_url, params=params, json=data_agent_payload, headers=headers ) if data_agent_response.status_code == 200: print("Data Agent created successfully!") print(json.dumps(data_agent_response.json(), indent=2)) else: print(f"Error creating Data Agent: {data_agent_response.status_code}") print(data_agent_response.text) ################### Create conversation ################### conversation_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}/conversations" data_agent_id = "data_agent_1" conversation_id = "conversation _1" conversation_payload = { "agents": [ f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}" ], "name": f"projects/{billing_project}/locations/{location}/conversations/{conversation_id}" } params = { "conversation_id": conversation_id } conversation_response = requests.post(conversation_url, headers=headers, params=params, json=conversation_payload) if conversation_response.status_code == 200: print("Conversation created successfully!") print(json.dumps(conversation_response.json(), indent=2)) else: print(f"Error creating Conversation: {conversation_response.status_code}") print(conversation_response.text) ################### Chat with the API by using conversation (stateful) #################### chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}:chat" data_agent_id = "data_agent_1" conversation_id = "conversation _1" # Construct the payload chat_payload = { "parent": f"projects/{billing_project}/locations/global", "messages": [ { "userMessage": { "text": "Make a bar graph for the top 5 states by the total number of airports" } } ], "conversation_reference": { "conversation": f"projects/{billing_project}/locations/{location}/conversations/{conversation_id}", "data_agent_context": { "data_agent": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}", # "credentials": looker_credentials #Uncomment this if your dataAgent contains looker dataSource } } } # Call the get_stream function to stream the response get_stream(chat_url, chat_payload) ################### Chat with the API by using dataAgents (stateless) #################### chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/{location}:chat" data_agent_id = "data_agent_1" # Construct the payload chat_payload = { "parent": f"projects/{billing_project}/locations/global", "messages": [ { "userMessage": { "text": "Make a bar graph for the top 5 states by the total number of airports" } } ], "data_agent_context": { "data_agent": f"projects/{billing_project}/locations/{location}/dataAgents/{data_agent_id}", # "credentials": looker_credentials #Uncomment this if your dataAgent contains looker as dataSource } } # Call the get_stream function to stream the response get_stream(chat_url, chat_payload) ################### Chat with the API by using inline context (stateless) #################### chat_url = f"https://geminidataanalytics.googleapis.com/v1alpha/projects/{billing_project}/locations/global:chat" # Construct the payload chat_payload = { "parent": f"projects/{billing_project}/locations/global", "messages": [ { "userMessage": { "text": "Make a bar graph for the top 5 states by the total number of airports" } } ], "inline_context": { "datasource_references": bigquery_data_sources, # Optional - if wanting to use advanced analysis with python "options": { "analysis": { "python": { "enabled": True } } } } } # Call the get_stream function to stream the response get_stream(chat_url, chat_payload)
El siguiente ejemplo de código expansible contiene las funciones auxiliares de Python que se utilizan para transmitir respuestas de chat.
Funciones auxiliares de Python para transmitir respuestas de chat
def is_json(str): try: json_object = json_lib.loads(str) except ValueError as e: return False return True def handle_text_response(resp): parts = resp['parts'] print(''.join(parts)) def get_property(data, field_name, default = ''): return data[field_name] if field_name in data else default def display_schema(data): fields = data['fields'] df = pd.DataFrame({ "Column": map(lambda field: get_property(field, 'name'), fields), "Type": map(lambda field: get_property(field, 'type'), fields), "Description": map(lambda field: get_property(field, 'description', '-'), fields), "Mode": map(lambda field: get_property(field, 'mode'), fields) }) display(df) def display_section_title(text): display(HTML('<h2>{}</h2>'.format(text))) def format_bq_table_ref(table_ref): return '{}.{}.{}'.format(table_ref['projectId'], table_ref['datasetId'], table_ref['tableId']) def format_looker_table_ref(table_ref): return 'lookmlModel: {}, explore: {}, lookerInstanceUri: {}'.format(table_ref['lookmlModel'], table_ref['explore'], table_ref['lookerInstanceUri']) def display_datasource(datasource): source_name = '' if 'studioDatasourceId' in datasource: source_name = datasource['studioDatasourceId'] elif 'lookerExploreReference' in datasource: source_name = format_looker_table_ref(datasource['lookerExploreReference']) else: source_name = format_bq_table_ref(datasource['bigqueryTableReference']) print(source_name) display_schema(datasource['schema']) def handle_schema_response(resp): if 'query' in resp: print(resp['query']['question']) elif 'result' in resp: display_section_title('Schema resolved') print('Data sources:') for datasource in resp['result']['datasources']: display_datasource(datasource) def handle_data_response(resp): if 'query' in resp: query = resp['query'] display_section_title('Retrieval query') print('Query name: {}'.format(query['name'])) print('Question: {}'.format(query['question'])) print('Data sources:') for datasource in query['datasources']: display_datasource(datasource) elif 'generatedSql' in resp: display_section_title('SQL generated') print(resp['generatedSql']) elif 'result' in resp: display_section_title('Data retrieved') fields = map(lambda field: get_property(field, 'name'), resp['result']['schema']['fields']) dict = {} for field in fields: dict[field] = map(lambda el: get_property(el, field), resp['result']['data']) display(pd.DataFrame(dict)) def handle_chart_response(resp): if 'query' in resp: print(resp['query']['instructions']) elif 'result' in resp: vegaConfig = resp['result']['vegaConfig'] alt.Chart.from_json(json_lib.dumps(vegaConfig)).display(); def handle_error(resp): display_section_title('Error') print('Code: {}'.format(resp['code'])) print('Message: {}'.format(resp['message'])) def get_stream(url, json): s = requests.Session() acc = '' with s.post(url, json=json, headers=headers, stream=True) as resp: for line in resp.iter_lines(): if not line: continue decoded_line = str(line, encoding='utf-8') if decoded_line == '[{': acc = '{' elif decoded_line == '}]': acc += '}' elif decoded_line == ',': continue else: acc += decoded_line if not is_json(acc): continue data_json = json_lib.loads(acc) if not 'systemMessage' in data_json: if 'error' in data_json: handle_error(data_json['error']) continue if 'text' in data_json['systemMessage']: handle_text_response(data_json['systemMessage']['text']) elif 'schema' in data_json['systemMessage']: handle_schema_response(data_json['systemMessage']['schema']) elif 'data' in data_json['systemMessage']: handle_data_response(data_json['systemMessage']['data']) elif 'chart' in data_json['systemMessage']: handle_chart_response(data_json['systemMessage']['chart']) else: colored_json = highlight(acc, lexers.JsonLexer(), formatters.TerminalFormatter()) print(colored_json) print('\n') acc = ''