Fabric is Generally Available. Browse Fabric Presentations. Work towards your Fabric certification with the Cloud Skills Challenge.
Hello,
Goal: Use an App ID to retrieve images from Azure Blob Storage and show them in a grid in a Power BI report.
Rationale: Because I cannot generate a long-lived SAS token per my orgs security requirements and I want to simplify permissions by using a single App ID.
So I...
- registered an App with Azure Active Directory
- created a `client_secret`
- then used this information in PowerQuery to send an OAUTH token request to the AAD auth endpoint
- and receive a Bearer token
- I also granted the App ID `Storage Blob Data Contributor` role to the Azure Blob Storage Container where images are stored
GetOATHToken Function PowerQuery:
- This results in a valid Bearer token to use in the Authorization header for subsequent GET Blob requests
= let
url = "https://login.microsoftonline.com/<my-tenant-id>/oauth2/v2.0/token",
headers = [
#"Content-Type" = "application/x-www-form-urlencoded"
],
content =
[
grant_type = "client_credentials",
scope = "https://<my-account>.blob.core.windows.net/.default",
client_id = "<my-id>",
client_secret = "<my-secret>"
],
webdata = Web.Contents(url, [Headers=headers,Content=Text.ToBinary(Uri.BuildQueryString(content))]),
response = Json.Document(webdata),
token = response[access_token]
in
token
I then...
- used the Azure Storage REST API and the results from the above Function call to request one of the blob images
- and this is successful
GetImage request PowerQuery:
- This results in an image
= let
url = "https://<my-account>.blob.core.windows.net/<my-container>/<folder1>/<folder2>/<actual-image>.jpg",
headers = [
#"x-ms-version" = "2018-03-28",
#"Authorization" = "Bearer " & GetOAUTHToken()
],
webdata = Web.Contents(url, [Headers=headers])
in
webdata
Now what?
1. How do I do this for ALL images in a certain blob folder, not just a single image?
2. How do I display the retrieved images and show them in my report?
Thank you
Hm...well, I was able to create an Azure Function to create short-lived SAS tokens to Storage Blobs.
Trigger: HTTP GET request
Input: Url-encoded blob URL, appended as a parameter to the GET request
Example:
https://<my-service>.azurewebsites.net/api/<my-api>?url=https%3A%2F%2F<blob-account>.blob.core.windows.net%2F<container-name>%2F<folder-1>%2F<folder-2>%2F<blob-name>.jpg
Output: Blob URL with short-lived SAS token appended
Example:
https://<blob-account>.blob.core.windows.net/<container-name>/<folder-1>/<folder-2>/<blob-name>.jpg?se=<expiration>&sp=<perms>&sv=<version>&sr=<resource>&sig=<signature>
Goal:
- Show a gallery of thumbnail images in the report.
- When user clicks on an image, the full size image opens in a new browser tab.
I'm able to create a Blank Query and trigger the Azure Function with this...
= let
url = "https://<my-service>.azurewebsites.net/api/<my-api>?url=https%3A%2F%2F<account-name>.blob.core.windows.net%2F<container-name>%2F<folder-1>%2F<folder-2>%2F<blob-name>.jpg",
headers = [
#"x-functions-key" = "<function-key>"
],
webdata = Web.Contents(url, [Headers=headers]),
token = Table.FromColumns({Lines.FromBinary(webdata,null,null,65001)})
in
token
Ideas? Thank you!
You would feed that set of URLs to the Image viewer visual. Or you can handcraft your HTML and use the HTML5 viewer visual etc.
All I have at this moment is a Blank Query that returns a Blob URL + SAS Token.
Seems quite difficult to:
- Connect to the Azure Blob Storage
- URL-encode all the images
- Somehow append the encoded URL's to the service GET request
- Call the service to show the thumbnails
- Then make each thumbnail itself a hyperlink that, when clicked, opens blob image in a new browser tab
1. Create a table with a column that holds the URL for each of the images. Call the second Power Query as a function with the URL as the parameter and the binary as the result. Convert the binary to Base64. Then in Power BI specify the field as imageURL and display as needed.
2. Chris Webb's BI Blog: Storing Large Images In Power BI Datasets (crossjoin.co.uk)
@lbendlin , thanks for the suggestion, however saving each "chunk" of an image's base64-encoded text, into a separate row of a data table, then using DAX to piece it back together is a little too deep for me.
I'm going to create an Azure Function instead that takes the URL of the blob and displays it in the user's browser.
You can try that. Be aware of potential authentication issues for report end users - something you avoid with the embedding.
The Function will use an App ID (or a Connection String) that is authorized to generate short-lived SAS tokens, apply them to the image URLs, then open the full size images in the browser. At least thats the thought ;).
Check out the November 2023 Power BI update to learn about new features.
Read the latest Fabric Community announcements, including updates on Power BI, Synapse, Data Factory and Data Activator.