[PowerBi][Fabric] Scanner API

Antes de la existencia de una área de administración que nos permita navegar recursos, solía estar el problema de "que hay en mi tenant?". Si no habíamos gobernado desde el primer momento, puede que se creara mucho más contenido del esperado.

En ese entonces Microsoft creo un request de API que permite entrar al máximo nivel de detalle de absolutamente todo lo que hay en el tenant. Este request tiene la más profundidad que lo que podemos encontrar en reportes y herramientas automáticas.

En este artículo, vamos a mostrar como obtener los resultados más finos de el total contenido desplegado en el tenant usando la librería de python para la power bi rest api, SimplePBI.

Vamos a comenzar escribiendo como Microsoft define a la Scanner API:

La Scanner API es parte de la Power BI Rest API de administración. Permite a los administradores recuperar de manera eficiente y automática información valiosa sobre los activos de Power BI de su organización, como inventario, metadatos y linaje. A su vez, pueden aprovechar esta información para sus propias soluciones personalizadas.

La API fue desarrollada con el objetivo de mejorar la eficiencia y el rendimiento del escaneo de Power BI (ahora también Fabric), de manera que pueda soportar grandes cantidades de activos de datos, mientras sigue cumpliendo con las prácticas de seguridad de las organizaciones. El Scanner soporta la autenticación de Service Principal y el escaneo incremental, y devuelve metadatos como el estado de respaldo, la etiqueta de sensibilidad, etc.

Dado que la API contiene un gran volumen de información, vamos a necesitar ejecutar más de un request y prerequisitos. Vamos a asumir que usaremos Service Principal. Para iniciarnos debemos registrar una app en Azure con los permisos sin permiso puntual (a menos que autentiquemos con master user que exigiría Tenant.Read.All o Tenant.ReadWrite.All) y permitirle a Fabric el paso de Service Principals. Si no sabes hacerlo podes leer aqui. Luego hay que permitirle en el mismo admin portal de Fabric que el service principal pueda leer la admin API como indica la imagen

Con dicha configuraciones podemos comenzar los cuatro pasos de ejecución. Lo primero que vamos a hacer es autenticarnos. Para ello necesitaremos TenantID, AppID o ClientID y el Secret Value. Importaremos la librería y comenzaremos.

# Import library
from simplepbi import token
from simplepbi import admin
# Service Principal auth
tok = token.Token(tenant_id, app_client_id, None, None, app_secret_key, use_service_principal=True)
# Creating admin category request
ad = admin.Admin(tok.token)

Con "ad" podremos ejecutar acciones que correspondan a esta doc: https://learn.microsoft.com/en-us/rest/api/power-bi/admin

En la misma podremos encontrar 4 requests correspondientes a workspace info que nos ayudaran en el paso a paso.

1- Obtener los espacios de trabajo que deseas rastrear

Lo primero será recolectar las áreas de trabajo que queres escanear para obtener la información fina. La sugerencia de proceso será usar un request que permite traerlos a todos, o filtrar por desuso pasado una fecha o quitar los personales. El request es el siguiente:

response = ad.get_modified_workspaces_preview(excludePersonalWorkspaces=True, modifiedSince=None)

Obtiene una lista de IDs de áreas de trabajo en la organización. Debido a que el siguiente request en el proceso solo pueden manejar 100 grupos por solicitud, hemos adaptado la respuesta del request para que este primer paso sea una lista de listas. La respuesta es una lista de listas con 100 áreas por lista. Esto quiere decir que si tenemos 226 áreas, el resultado será una lista que tiene dentro 3 listas, una lista con 100, otra lista con 100 y la última lista con 26 áreas de trabajo. Automáticamente preparará la lista de listas para que puedas recorrer los siguientes pasos por ti mismo. Recuerda que puedes verificar la longitud de una lista con el siguiente código:

# Verificar el número de listas de 100 espacios de trabajo.
len(response)
# Mostrar áreas de trabajo, [0] es un ejemplo de la primera lista de 100
response[0]

Más información del request: https://learn.microsoft.com/en-us/rest/api/power-bi/admin/workspace-info-get-modified-workspaces

2- Delimitar información del área de trabajo

Seleccionadas las áreas, vamos a delimitar la granularidad de información, es decir, cuanto detalle realmente queremos.

scan_id = ad.post_workspace_info(response[0], lineage=True, datasourceDetails=True, datasetSchema=True, datasetExpressions=True, getArtifactUsers=True)

  • datasetSchema: Si quieren devolver el esquema del conjunto de datos (tablas, columnas y medidas). Si ponen el parámetro en verdadero, deben habilitar completamente el "análisis de metadatos" para que se devuelvan los datos. Esta configuración se encuentra en el portal de administración en apartado de inquilino/tenant. Buscar la opción relacionada a análisis de metadatos.
  • datasourceDetails: Si quieren devolver los detalles del origen de datos
  • getArtifactUsers: Si quieren devolver los detalles de usuarios para elementos de Power BI (como un informe o un panel)
  • lineage: Si quieren devolver información de linaje (flujos de datos ascendentes, mosaicos, ID de origen de datos)

El request devuelve un ID de escaneo (scan_id) en formato UUID. Inicia una llamada para recibir los metadatos de la lista solicitada de áreas de trabajo. El parámetro de áreas de trabajo es una lista de máximo 100 espacios de trabajo. Puedes ejecutar esta solicitud recorriendo la lista de listas de la respuesta anterior. De manera predeterminada, devolverá todos los datos posibles. Puedes cambiar a false los parámetros en el detalle del método que no desees obtener o para mejorar la performance de la llamada.

3- Obtener el estado del escaneo

ad.get_scan_status_preview(scan_id)

Obtiene el estado del escaneo para la llamada solicitada recientemente. Antes de obtener toda la estructura para los 100 espacios de trabajo, necesitamos pedir a la API que apruebe el escaneo. Esta solicitud devolverá el mismo ID y un estado. Si la respuesta para el estado es "Succeeded" (Exitoso), podrás completar la solicitud del escáner en el último paso. Si no, espera e inténtalo más tarde.

4- Obtener el resultado del escaneo

ad.get_scan_result_preview(scan_id)

Obtiene el resultado del escaneo para el scan_id especificado. Esta solicitud finalmente devolverá un enorme diccionario de Python con todos los datos que solicitamos para los 100 espacios de trabajo listados en el escaneo. La respuesta se vería así:

Podemos ver pintada cada categoría de items que recorrería por cada workspace desplegando más o menos información, según los parámetros del segundo paso.

NOTA: Fabric se está incorporando a esta dinámica mostrando sus items como salen en reports. Ahi encontraría algo como "warehouses" o "SQLAnalyticsEndpoint".

Así llegamos al final del artículo en donde aprendimos como relevar toda la información más fina de lo que hay creado a nivel organización. Esto puede ser de gran utilidad para automatizar relevamientos por secciones o en totalidad y armar nuestros propios informes/aplicaciones que lean la información a modo de monitoreo.