diff --git a/.changes/unreleased/docs-20260216-084028.yaml b/.changes/unreleased/docs-20260216-084028.yaml new file mode 100644 index 00000000..987417e5 --- /dev/null +++ b/.changes/unreleased/docs-20260216-084028.yaml @@ -0,0 +1,6 @@ +kind: docs +body: Created refresh semantic model using API command example +time: 2026-02-16T08:40:28.503495133Z +custom: + Author: may-hartov + AuthorLink: https://github.com/may-hartov diff --git a/docs/examples/api_examples.md b/docs/examples/api_examples.md index 2adbc90e..fa7d688b 100644 --- a/docs/examples/api_examples.md +++ b/docs/examples/api_examples.md @@ -109,4 +109,8 @@ Retrieve Power BI workspace details. ``` fab api -A powerbi groups/00000000-0000-0000-0000-000000000000 -``` \ No newline at end of file +``` + +### Refresh Semantic Model + +For detailed examples on triggering and monitoring semantic model refresh using the API command, see the [Semantic Model Refresh Example](refresh_semantic_model_example.md). \ No newline at end of file diff --git a/docs/examples/item_examples.md b/docs/examples/item_examples.md index 48ab6c96..9b1b280e 100644 --- a/docs/examples/item_examples.md +++ b/docs/examples/item_examples.md @@ -380,9 +380,13 @@ fab stop ws1.Workspace/mir1.MirroredDatabase Stop mirrored database without confirmation. ``` -fab stop ws1.Workspacemir1.MirroredDatabase -f +fab stop ws1.Workspace/mir1.MirroredDatabase -f ``` +### Semantic Model Refresh + +For detailed examples on triggering and monitoring semantic model refresh using the API command, see the [Semantic Model Refresh Example](refresh_semantic_model_example.md). + ### Open in Browser #### Open Item in Web Interface diff --git a/docs/examples/refresh_semantic_model_example.md b/docs/examples/refresh_semantic_model_example.md new file mode 100644 index 00000000..617e380e --- /dev/null +++ b/docs/examples/refresh_semantic_model_example.md @@ -0,0 +1,214 @@ +# Semantic Model Refresh + +This guide shows how to trigger and monitor Power BI semantic model refresh using the Fabric CLI `api` command. + +## Run Refresh On Demand + +To refresh a semantic model, you can use the `api` command as follows: + +```bash +fab api -A powerbi -X post "groups/$WORKSPACE_ID/datasets/$SEMANTIC_MODEL_ID/refreshes" +``` + +Where `$SEMANTIC_MODEL_ID` and `$WORKSPACE_ID` are set to your semantic model ID and workspace ID respectively. + +## Run Refresh With Parameters + +You can also provide additional parameters to the refresh job, based on the supported payload documented in [Refresh Dataset In Group](https://learn.microsoft.com/rest/api/power-bi/datasets/refresh-dataset-in-group#request-body), as follows: + +```bash +fab api -A powerbi -X post "groups/$WORKSPACE_ID/datasets/$SEMANTIC_MODEL_ID/refreshes" --show_headers -i '{"retryCount":"1","timeout":"00:20:00"}' +``` + +## Check Refresh Status + +You can check the status of a specific refresh operation using the refresh ID. The refresh ID is returned in the `Location` or `RequestId` response headers when you run a refresh. + +```bash +fab api -A powerbi -X get "groups/$WORKSPACE_ID/datasets/$SEMANTIC_MODEL_ID/refreshes/$REFRESH_ID" +``` + +This command uses the [Get Refresh Execution Details In Group](https://learn.microsoft.com/en-us/rest/api/power-bi/datasets/get-refresh-execution-details-in-group) API endpoint. + +## End-to-End Example: Run Refresh and Poll for Completion + +Replace the following placeholders before running: + +- **`{WORKSPACE_ID}`** - Your workspace ID +- **`{SEMANTIC_MODEL_ID}`** - Your semantic model ID +- **`{POLLING_INTERVAL}`** - Polling interval in seconds + +=== "PowerShell" + ```powershell + # Configuration + $WorkspaceId = "{WORKSPACE_ID}" + $SemanticModelId = "{SEMANTIC_MODEL_ID}" + $PollingInterval = {POLLING_INTERVAL} # seconds + + # Customize the request body according to your needs + $requestBody = '{\"retryCount\":\"1\"}' + + $refreshResponse = fab api -A powerbi -X post "groups/$WorkspaceId/datasets/$SemanticModelId/refreshes" --show_headers -i $requestBody + + # Parse the response as JSON and check status code + + $refreshJson = $refreshResponse | ConvertFrom-Json + $statusCode = $refreshJson.status_code + + # Check POST response status (expecting 202 Accepted) + if ($statusCode -ne 202) { + exit 1 + } + + $pollingEndpoint = $null + + # Try to extract Location header first (preferred method) + if ($refreshJson.headers.Location) { + $locationUrl = $refreshJson.headers.Location + if ($locationUrl -match 'https?://[^/]+/v1\.0/myorg/(.+)') { + $pollingEndpoint = $Matches[1].Trim() + } + } + + # Fallback to RequestId header if Location not present + if (-not $pollingEndpoint) { + if ($refreshJson.headers.RequestId) { + $refreshId = $refreshJson.headers.RequestId + $pollingEndpoint = "groups/$WorkspaceId/datasets/$SemanticModelId/refreshes/$refreshId" + } + } + + if (-not $pollingEndpoint) { + exit 1 + } + + $status = "" + + while ($true) { + Start-Sleep -Seconds $PollingInterval + + $statusResponse = fab api -A powerbi $pollingEndpoint --show_headers + + $statusResponseJson = $statusResponse | ConvertFrom-Json + $getStatusCode = $statusResponseJson.status_code + + # Check GET response status (expecting 200 or 202) + if ($getStatusCode -ne 200 -and $getStatusCode -ne 202) { + Write-Host $statusResponse + } + + $statusJson = $statusResponseJson.text + + $status = if ($statusJson.extendedStatus) { $statusJson.extendedStatus } else { $statusJson.status } + + Write-Host " Refresh Status: $status" -ForegroundColor Cyan + + # Then handle completion states + switch -Regex ($status) { + "^Completed$" { + exit 0 + } + "^(Failed|Cancelled|Disabled|TimedOut)$" { + Write-Host $statusResponse + exit 1 + } + "^(NotStarted|InProgress|Unknown)$" { + # Continue polling + } + default { + Write-Host $statusResponse + exit 1 + } + } + } + ``` + +=== "Bash" + ```bash + #!/bin/bash + + # Configuration + WORKSPACE_ID="{WORKSPACE_ID}" + SEMANTIC_MODEL_ID="{SEMANTIC_MODEL_ID}" + POLLING_INTERVAL={POLLING_INTERVAL} # seconds + + # Customize the request body according to your needs + REQUEST_BODY='{"retryCount":"1"}' + + REFRESH_RESPONSE=$(fab api -A powerbi -X post "groups/$WORKSPACE_ID/datasets/$SEMANTIC_MODEL_ID/refreshes" --show_headers -i "$REQUEST_BODY") + + # Parse the response as JSON and check status code + + REFRESH_JSON=$(echo "$REFRESH_RESPONSE" | jq '.') + STATUS_CODE=$(echo "$REFRESH_JSON" | jq -r '.status_code') + + # Check POST response status (expecting 202 Accepted) + if [ "$STATUS_CODE" != "202" ]; then + exit 1 + fi + + POLLING_ENDPOINT="" + + # Try to extract Location header first (preferred method) + LOCATION=$(echo "$REFRESH_JSON" | jq -r '.headers.Location // empty') + if [ -n "$LOCATION" ]; then + POLLING_ENDPOINT=$(echo "$LOCATION" | sed -n 's|.*https\?://[^/]*/v1\.0/myorg/\(.*\)|\1|p' | xargs) + fi + + # Fallback to RequestId header if Location not present + if [ -z "$POLLING_ENDPOINT" ]; then + REFRESH_ID=$(echo "$REFRESH_JSON" | jq -r '.headers.RequestId // empty') + if [ -n "$REFRESH_ID" ]; then + POLLING_ENDPOINT="groups/$WORKSPACE_ID/datasets/$SEMANTIC_MODEL_ID/refreshes/$REFRESH_ID" + fi + fi + + if [ -z "$POLLING_ENDPOINT" ]; then + exit 1 + fi + + STATUS="" + + while true; do + sleep "$POLLING_INTERVAL" + + STATUS_RESPONSE=$(fab api -A powerbi "$POLLING_ENDPOINT" --show_headers) + + STATUS_RESPONSE_JSON=$(echo "$STATUS_RESPONSE" | jq '.') + GET_STATUS_CODE=$(echo "$STATUS_RESPONSE_JSON" | jq -r '.status_code') + + # Check GET response status (expecting 200 or 202) + if [ "$GET_STATUS_CODE" != "200" ] && [ "$GET_STATUS_CODE" != "202" ]; then + echo "$STATUS_RESPONSE" + fi + + STATUS_JSON=$(echo "$STATUS_RESPONSE_JSON" | jq -r '.text') + + EXTENDED_STATUS=$(echo "$STATUS_JSON" | jq -r '.extendedStatus // empty') + if [ -n "$EXTENDED_STATUS" ]; then + STATUS="$EXTENDED_STATUS" + else + STATUS=$(echo "$STATUS_JSON" | jq -r '.status') + fi + + echo " Refresh Status: $STATUS" + + # Then handle completion states + case "$STATUS" in + "Completed") + exit 0 + ;; + "Failed"|"Cancelled"|"Disabled"|"TimedOut") + echo "$STATUS_RESPONSE" + exit 1 + ;; + "NotStarted"|"InProgress"|"Unknown") + # Continue polling + ;; + *) + echo "$STATUS_RESPONSE" + exit 1 + ;; + esac + done + ``` diff --git a/mkdocs.yml b/mkdocs.yml index 1dd38219..89e315dd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -106,7 +106,9 @@ nav: - Auth Examples: examples/auth_examples.md - Config Examples: examples/config_examples.md - Core Management: - - API Examples: examples/api_examples.md + - API Examples: + - examples/api_examples.md + - Example of semantic model refresh: examples/refresh_semantic_model_example.md - ACL Examples: examples/acl_examples.md - Describe Examples: examples/desc_examples.md - Tenant Management: