Power BI DocuTIPS I

Sara Alonso B
7 min readFeb 7, 2024

--

Tip 1: Generando descripciones con Azure Open AI

¡Hola! Hace tiempo que no me pasaba por aquí, pero hoy vuelvo para hablaros de un tema que no suele gustar demasiado: Documentación. Tema apasionante, ¿verdad?😅

Da igual de qué sea el proyecto, da igual la tecnología, a nadie nos gusta documentar. Y es por ello que estoy poniendo foco en cómo documentar nuestros proyectos de Power BI de una forma rápida, amena y productiva.

L@s que me habéis visto en los últimos eventos de comunidades técnicas os habréis fijado que las últimas sesiones que he presentado han sido sobre esto, y ahora quiero plasmar en varios artículos todos los “Tips” que se me ocurran para ayudaros a que el documentar proyectos deje de ser una labor tediosa, larga y aburrida.

Como he buscado bastante info sobre este tema, os voy a compartir todas las maneras que conozco de documentar proyectos de Power BI. ¿Cuál es la mejor manera? Me encanta la típica respuesta de mis queridos primos-hermanos, los gallegos: “Depende” 😋 . Y es que depende de tantas cosas, de cómo quiera el cliente la documentación, de la automatización, de los recursos de los que dispongamos… Yo intentaré contaros varias maneras de documentar, que espero os puedan resultar de ayuda.

Hoy vamos a empezar esta serie de “Power BI DocuTIPS” con el recurso que tengo más explotado y utilizado: Generar descripciones con la ayuda de la IA de “Azure OpenAI”.

¡Vamos a ello!

Necesitaremos, además de Azure OpenAI, la ayuda de Tabular Editor 2, una herramientas externa de Power BI gratuita.

Herramientas necesarias para la generación de descripciones

En el siguiente post completaremos la documentación con otra herramienta externa de Power BI, también gratuita: Model Documenter. Asi que si no tenéis instaladas las herramientas Tabular Editor 2 y Model Documenter, que como os digo, son gratuitas (¡qué gusto de comunidad!), os dejo aquí los enlaces:

Una vez las tengáis instaladas os aparecerán en el menú de Herramientas externas de Power BI.

Paso 1: Power BI -> Tenemos terminado nuestro informe en Power BI Desktop con sus tablas, columnas y medidas. Vamos a la vista de Modelo y nos fijamos si hemos rellenado el cuadro de las descripciones para cada objeto:

Por supuesto que no. Me atrevería a decir que el 99,9% de los desarrolladores de Power BI no ponen la descripción del objeto. Cosa que entiendo cuando tienes un modelo semántico con 87567459 tablas, 3979846754 columnas y 9483574875 medidas con KPIs de negocio (así, sin exagerar).

Cuando instalé Model Documenter (antes del boom de la IA) me di cuenta de que si tenía el campo de descripción cubierto para cada objeto me generaría un informe nuevo con toda la documentación del proyecto, herramienta automática y maravillosa sin ninguna duda. Pero claro, esto no me libraba de tener que rellenar cada campo de descripción.

Hasta que llegó el maravilloso servicio de “Azure Open AI”, que hará por nosotros las descripciones de cada objeto, es decir, la parte más pesada y aburrida del proceso. ¿Cómo? Veamos el paso 2.

Paso 2: Abrimos Tabular Editor 2 -> Tabular Editor es una herramienta para diseñar y editar modelos tabulares, aplicando cualquier cambio a los metadatos, por lo que al no trabajar con el conjunto de datos, cualquier cambio que hagamos se aplica de forma inmediata al informe de Power BI.

Observamos que aquí también tenemos todos los objetos del modelo de datos. Si pulsamos sobre cualquiera de ellos vemos en la parte inferior que tenemos el campo de “descripción” también vacío.

En esta herramienta contamos con una pestaña con un espacio para ejecutar Scripts de C#. Pulsamos sobre ella.

Tabular Editor

Como tengo la gran suerte de contar con mi compañero de trabajo y de vida, Diego Álvarez Allas , Manager & Arquitecto de Software en Tokiota, se ha currado el siguiente script de C# y ha sido tan generoso de compartirlo conmigo y con la comunidad. ¡Gracias! En el cual, hacemos la llamada a la API de Azure Open AI Service.

Algun@s os estaréis preguntando, ¿cómo levanto el servicio de Azure Open AI? Actualmente está solo disponible a nivel empresarial y bajo formulario de suscripción. Pregunta en tu empresa si ya cuentan con este recurso. En cuanto a costes, que son muy bajitos, puedes consultarlos aquí .

Vamos a pegar el siguiente Script de C# de Diego en el espacio que tenemos disponible en Tabular Editor:

#r "System.Net.Http"
using System.Net.Http;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Threading;

const string apiKey = "[API key here]";
const string deploymentName = "gpt-35-turbo";
const string AzureOpenaiEndpoint= "https://[your endpoint].openai.azure.com/";
const string url = AzureOpenaiEndpoint + "openai/deployments/" + deploymentName + "/chat/completions?api-version=2023-05-15";
const string questionTable = "Explain the following table in Spanish in a few sentences in simple business terms: \n\n";
const string questionMeasure = "Explain the following calculation in Spanish in a few sentences in simple business terms without using DAX function names: \n\n";
const string questionTableColumns = "Explain the following column in Spanish in a few sentences in simple business terms: \n\n";
var contar = 0;
const bool processMeasures = true;
const bool processTableColumns = true;
const bool processTable = true;

using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("api-key", apiKey);

foreach(var t in Model.Tables)
{
if(processTable)
{
if(contar == 30)
{
contar = 0;
Thread.Sleep(10000);
}

if(t.Description == "")
{
try
{
var body = "{\"messages\": [{\"role\": \"user\", \"content\": " + JsonConvert.SerializeObject(questionTable + t.Name ) + "}]}";
body.Output();
var res = client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json"));
res.Result.EnsureSuccessStatusCode();
var result = res.Result.Content.ReadAsStringAsync().Result;
var obj = JObject.Parse(result);
var desc = obj["choices"][0]["message"]["content"].ToString().Trim();
t.Description = desc;
contar++;
}
catch(Exception ex)
{
ex.Message.Output();
}
}
}

contar = 0;

//proceamos las medidas
if(processMeasures)
{
foreach(var m in t.Measures)
{
if(contar == 30)
{
contar = 0;
Thread.Sleep(10000);
}

if(m.Description == "")
{
try
{
var body = "{\"messages\": [{\"role\": \"user\", \"content\": " + JsonConvert.SerializeObject(questionMeasure + m.Expression.Replace("\"", "'") ) + "}]}";
body.Output();
var res = client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json"));
res.Result.EnsureSuccessStatusCode();
var result = res.Result.Content.ReadAsStringAsync().Result;
var obj = JObject.Parse(result);
var desc = obj["choices"][0]["message"]["content"].ToString().Trim();
m.Description = desc;
contar++;
}
catch(Exception ex)
{
ex.Message.Output();
}
}
}
}

//reinicializamos la variable de control
contar = 0;

//Procesamos las columnas
if(processTableColumns)
{
//recorremos las columnas de la tabla.
foreach(var c in t.Columns)
{
if(contar == 30)
{
contar = 0;
Thread.Sleep(10000);
}

if(c.Description == "")
{
try
{
var body = "{\"messages\": [{\"role\": \"user\", \"content\": " + JsonConvert.SerializeObject(questionTableColumns + t.Name+ "-" + c.Name) + "}]}";
body.Output();
var res = client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json"));
res.Result.EnsureSuccessStatusCode();
var result = res.Result.Content.ReadAsStringAsync().Result;
var obj = JObject.Parse(result);
var desc = obj["choices"][0]["message"]["content"].ToString().Trim();
c.Description = desc;
contar++;
}
catch(Exception ex)
{
ex.Message.Output();
}
}
}
}
}
}

A tener en cuenta:

  • “API key” y “Endpoint” : Introdúcelas en el espacio “[API key here]” y “https://[your endpoint].openai.azure.com/”
  • Prompts: Son las instrucciones que le damos a Azure Open AI para que haga las descripciones de las tablas, columnas y medidas por nosotros:

Es importante saber que cuanto más específic@s seamos con la instrucción más preciso será el resultado. Para las medidas, que suelen ser KPIs de negocio, es importante indicar que nos devuelva definiciones en términos de negocio sin usar funciones DAX. También podemos indicar un máximo de caracteres para cada definición.

Cuando lo tengamos listo me damos al botón de ejecutar y listo.

Botón de ejecutar

Cuando deje de salir la rueda será que ha terminado la ejecución y veremos los campos de descripción de cada objeto, cubiertos 😊. Y aquí está la magia.

Si vamos pulsando cada tabla, columna y medida vemos que Azure Open AI ha generado una descripción de la misma.

Solo nos quedaría guardar los cambios, que se aplicarán inmediatamente al informe de Power BI, ya que desde Tabular Editor trabajamos únicamente con los metadatos.

Botón de guardar en Tabular Editor

Cerramos la herramienta y vovlemos a Power BI.

Observamos que los campos de descripción de cada objeto están cubiertos desde que le dimos al botón de guardar de Tabular Editor.

Power BI

Podremos ver las descripciones, tanto en la vista de modelo seleccionando el objeto y leyendo el campo de Descripción, como pasando el ratón por encima de cualquier objeto, que nos mostrará un “tooltip” con toda la descripción.

¿Qué os ha parecido esta magia? Nos hemos ahorrado un gran trabajo evitando describir cada uno de los objetos de nuestro modelo semántico. En este ejemplo el modelo es pequeño pero, ¿qué me decís de cuando tenemos un modelo de 30 tablas con 40 columnas y 200 KPIs de negocio? ¡Calculad la cantidad de horas de trabajo que nos hemos ahorrado!

No os perdáis el próximo post, en el que generaremos la documentación, también de forma automática, a partir de estas descripciones que nos ha generado Azure Open AI.

¡Os leo en comentarios! Muchas gracias 😊

--

--