From bcb189ad70e4b8a968bc510e005cf8e7e0e1e907 Mon Sep 17 00:00:00 2001 From: R1k91 <57228476+R1k91@users.noreply.github.com> Date: Tue, 26 Aug 2025 18:36:51 +0200 Subject: [PATCH 1/3] Add Power BI semantic model refresh notebook --- power-bi-semantic-model-refresh.ipynb | 147 ++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 power-bi-semantic-model-refresh.ipynb diff --git a/power-bi-semantic-model-refresh.ipynb b/power-bi-semantic-model-refresh.ipynb new file mode 100644 index 0000000..5e66e75 --- /dev/null +++ b/power-bi-semantic-model-refresh.ipynb @@ -0,0 +1,147 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "c81e9b8a", + "metadata": {}, + "source": [ + "# Refresh Power BI Semantic Model via REST endpoint\n", + "\n", + "Power BI allows the refresh of a published model via the executeQueries endpoint.\n", + "\n", + "[Datasets - Refresh Dataset In Group](https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/refresh-dataset-in-group?wt.mc_id=MVP_449122&source=post_page-----1e52165e36ab---------------------------------------)\n", + "\n", + "Authetication can be done via SPN (Microsoft Entra Application)." + ] + }, + { + "cell_type": "markdown", + "id": "016f5c1e", + "metadata": {}, + "source": [ + "# Prerequisites\n", + "\n", + "To trigger the refresh, we first need to collect the following information:\n", + "- The tenant ID that hosts the semantic model\n", + "- The client ID of the SPN object\n", + "- The secret of the SPN object\n", + "- The semantic model ID\n", + "- The workspace ID" + ] + }, + { + "cell_type": "markdown", + "id": "f0addc61", + "metadata": {}, + "source": [ + "# Get Oauth2 Token for the SPN\n", + "\n", + "We can request for a token for our SPN leveraging **sp_invoke_external_rest_endpoint** and we save it an @access_token variable." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7eeee18b", + "metadata": { + "vscode": { + "languageId": "sql" + } + }, + "outputs": [], + "source": [ + "\n", + "DECLARE @tenant_id NVARCHAR(100) = N''\n", + " ,@client_id NVARCHAR(100) = N''\n", + " ,@client_secret NVARCHAR(200) = N''\n", + " ,@workspace_id NVARCHAR(100) = N''\n", + " ,@dataset_id NVARCHAR(100) = N''\n", + "\n", + "DECLARE @scope NVARCHAR(200) = \n", + " N'https://analysis.windows.net/powerbi/api/.default';\n", + "\n", + "DECLARE @response NVARCHAR(MAX);\n", + "\n", + "DECLARE @url NVARCHAR(400) = \n", + " N'https://login.microsoftonline.com/' \n", + " + @tenant_id \n", + " + N'/oauth2/v2.0/token';\n", + "\n", + "DECLARE @headers NVARCHAR(MAX) = \n", + " N'{\"Content-Type\":\"application/x-www-form-urlencoded\"}';\n", + "\n", + "DECLARE @body NVARCHAR(MAX) =\n", + " N'client_id=' + @client_id \n", + " + N'&scope=' + @scope \n", + " + N'&client_secret=' + @client_secret \n", + " + N'&grant_type=client_credentials';\n", + " \n", + "EXEC sp_invoke_external_rest_endpoint\n", + " @method = 'POST'\n", + " ,@url = @url\n", + " ,@headers = @headers\n", + " ,@payload = @body\n", + " ,@credential = NULL\n", + " ,@response = @response OUTPUT;\n", + " \n", + "DECLARE @access_token NVARCHAR(MAX) = \n", + " JSON_VALUE(@response, N'$.result.access_token');" + ] + }, + { + "cell_type": "markdown", + "id": "ae9bc94d", + "metadata": {}, + "source": [ + "# Refresh the semantic model\n", + "\n", + "Once you have the token stored in the @access_token variable, you can use it to call the Power BI Refresh API." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0dcaf0b0", + "metadata": { + "vscode": { + "languageId": "sql" + } + }, + "outputs": [], + "source": [ + "DECLARE @refreshUrl NVARCHAR(400) =\n", + " N'https://api.powerbi.com/v1.0/myorg/groups/' \n", + " + @workspace_id \n", + " + N'/datasets/' \n", + " + @dataset_id \n", + " + N'/refreshes';\n", + "\n", + "DECLARE @refreshHeaders NVARCHAR(MAX) =\n", + " N'{\"Authorization\":\"Bearer ' \n", + " + @access_token \n", + " + N'\",\"Content-Type\":\"application/json\"}';\n", + "\n", + "DECLARE @refreshBody NVARCHAR(MAX) = N'{\"notifyOption\": \"NoNotification\"}';\n", + "\n", + "DECLARE @refreshResponse NVARCHAR(MAX);\n", + "\n", + "EXEC sp_invoke_external_rest_endpoint\n", + " @method = 'POST'\n", + " ,@url = @refreshUrl\n", + " ,@headers = @refreshHeaders\n", + " ,@payload = @refreshBody\n", + " ,@credential = NULL\n", + " ,@response = @refreshResponse OUTPUT; \n", + "\n", + "SELECT @refreshResponse;" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a1bf5fd1bdd5bb5c3a407bec28c43b59ff11269f Mon Sep 17 00:00:00 2001 From: R1k91 <57228476+R1k91@users.noreply.github.com> Date: Tue, 26 Aug 2025 18:44:11 +0200 Subject: [PATCH 2/3] Update endpoint reference for Power BI model refresh --- power-bi-semantic-model-refresh.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power-bi-semantic-model-refresh.ipynb b/power-bi-semantic-model-refresh.ipynb index 5e66e75..9ec35cb 100644 --- a/power-bi-semantic-model-refresh.ipynb +++ b/power-bi-semantic-model-refresh.ipynb @@ -7,7 +7,7 @@ "source": [ "# Refresh Power BI Semantic Model via REST endpoint\n", "\n", - "Power BI allows the refresh of a published model via the executeQueries endpoint.\n", + "Power BI allows the refresh of a published model via the refreshes endpoint.\n", "\n", "[Datasets - Refresh Dataset In Group](https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/refresh-dataset-in-group?wt.mc_id=MVP_449122&source=post_page-----1e52165e36ab---------------------------------------)\n", "\n", From 36ed16866d5d355445f2480404b957cab9e61b65 Mon Sep 17 00:00:00 2001 From: R1k91 <57228476+R1k91@users.noreply.github.com> Date: Tue, 26 Aug 2025 18:46:11 +0200 Subject: [PATCH 3/3] Revise Power BI documentation for clarity adjusted the Power BI section of the readme adding the a link to the new notebook and updating naming convention - dataset -> semantic model --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c910a81..dc2c75c 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,12 @@ The notebook contains samples on how to send messages to [Azure Event Hubs](http - Send events using a SAS Token - Send events using a Managed Identity -### [Power BI](./power-bi.ipynb) +### Power BI -The notebook shows how DAX queries can be executed from Azure SQL DB using the `executeQueries` REST endpoint provided by Power BI datasets - -- Execute DAX queries in Power BI +- [Execute DAX queries in Power BI](./power-bi.ipynb) + The notebook shows how DAX queries can be executed from Azure SQL DB using the `executeQueries` REST endpoint provided by Power BI semantic models +- [Refresh a semantic model](./power-bi-semantic-model-refresh.ipynb) + The notebook shows how a semantic model can be refreshed from Azure SQL DB & SQL Server using the `refreshes` REST endpoint provided by Power BI semantic models ### [Azure Cognitive Services](./azure-cognitive-services.ipynb)