Existen diversos escenarios donde PowerBi nos va a exigir un gateway para actualizar nuestra información. A veces es muy necesario y tiene sentido, pero otras veces no y resulta hasta molesto.
Puede que haya muchos escenarios más que los que voy a mencionar pero normalmente al escrapear un sitio web (funcion Web.Pages de power query) se exige un gateway. Tal vez tenes alguna operación tan compleja que se te ocurre usar Python para resolverla porque esta dentro de Power Bi, pero con eso también te exige Gateway.
Este artículo mostrará como podemos usar Azure Functions para realizar una operación simple con Python para luego leerlo desde PowerBi como un simple Get Request de API.
Primero que nada un poco de teoría. Existen escenarios web los cuales requeiren de Gateway para su tratamiento. Aun si estamos en power query online (dataflows) necesitaremos uno. Hay tres funciones cláscias que son de interés y funcionan distinto. WebContent, WebPages y WebContentBrowser. Si quieren conocer la diferencia y entender cual pide gateway y cual no, pueden leer la siguiente doc: https://learn.microsoft.com/en-us/power-query/connectors/web/web-troubleshoot
Me gustaría comenzar aclarando que no voy a hacer una introducción a Azure Functions. No voy a explicar que es, cómo funciona y cómo setear el entorno. Para eso ya hay excelentes videos en internet o podemos leer más en la siguiente doc de microsoft:
Para este post necesitamos conocimientos previos en Python básico y Visual Studio Code. Asumiendo que ya tenemos el entorno seteado con las extensiones de Visual Studio code, vamos a comenzar con un ejemplo sencillo conectando a una API. Ya logueados en el apartado de Azure y con visibilidad a nuestra suscripción, vamos a crear una Function App. Podemos pensarlo como el servidor de procesamiento de muchas Azure Functions. En ese espacio podemos tener muchas functions, pensemos a cada una como un request.
Al momento de crearla tenemos 4 pasos

Ese nombre será participe de la URL de la API que estamos generando.
Ahora podremos crear la función. Se almacenará en la carpeta que tengamos apuntando el Visual Studio Code. Clickeamos el rayito para crear una función dentro de la Function App

La aplicación creada se verá así:

Lo que necesitamos saber es que tenemos una función main donde se ejecutará el código principal. Luego depende si llamamos a la función con get o post si podemos capturar items de parametros de url o body. Eso nos ayudaría a incrementar la seguridad puesto que sin los parametros correctos o autenticación no podríamos obtener la respuesta. A modo de ejemplo vamos a hacer una simple lógica para que la url retorne el resultado cada vez que sea llamada sin necesidad de nada más puesto que considero que no es sensible la data del nombre de los workspaces en mi tenant de demo.
Veamos que simple es escribir código dentro de main devolviendo un dict o json en el return bajo el status_code deseado. Podemos aprovecharnos de los mensajes para ser claros en fallas para recibirlas en Power Bi.

Código de la imagen en mi Github.
Usando SimplePBI para obtener grupos, pueden ver que simplemente generamos token, creamos objeto de grupo (workspaces) y llamamos a los workspaces que nuestro Service Principal puede ver.
Luego agregue al return una aclaración adicional para cuando lo que queremos devolver no es un "texto" literal sino un dict o json que es el "mimetype".
NOTA: Si no sabes que es SimplePBI podes pasar por aqui.
IMPORTANTE: aclaro que tenemos un secret expuesto en este código, lo mejor para una azure function así sería usar un Azure KeyVault a nuestras contraseñas y secretos para que no queden expuestos.
Si vamos a usar una librería importada tendremos que buscar el archivo requirements.txt en el panel de recursos y agregarla. Yo lo hice para SimplePBI.
Si necesitamos utilizar pandas para tomar datos de un origen estructurado, podemos utilizar " DataFrame.to_dict(orient="records") " en el json.dumps del return para convertir nuestro frame al formato de mimetype json.
Get data
Mucho sobre python y funciones, vamos a PowerBi Desktop a conectarnos. Usaremos el conector web para traer la información con credenciales anónimas.

Dependiendo como orientamos nuestro json devuelto en la API que nos generamos en Azure Functions vamos a tener que efectuar transformaciones en power query. En este caso la devuelta por SimplePBI es muy uniforme y el motor practicamente lo resuelve solo.
Veamos como queda:

Ahora tenemos nuestra data cargada en Power Bi usando python sin necesidad de un gateway personal. Ya podemos publicar nuestro informe al servicio de power bi y configurar las credenciales como anónimas.
ACLARACIÓN: las Azure Functions tiene un límte de uso (timeout) en 5 minutos. Nuestra ejecución no puede durar más de eso o fallaría y nuestro propósito quedaría perdido.
Conclusión
Esta metodología puede ayudarnos a dar más velocidad a pequeños desarrollos, scrappings u origenes cloud complicados que PowerBi no tenga connector sin driver (ejemplo: oracle o mysql). Con una Azure Function construir rápido y fácilmente una API que responda. Para aumentar la seguridad es necesario utilizar Azure KeyVaults en nuestro código y en caso de necesitar disponibilizar data más sensible, lo mejor sería pedir un parámetro o body con alguna clase de key (que puede ser inventada por nosotros) para que no todo quede sobre una URL pública. Espero que este ejemplo les despierte nuevas ideas.