Embedded Analytics with Power BI

Content

  1. What is Embedded Analytics?
  2. Why should I care?
  3. What is Power BI Embedded?
  4. History
  5. Power BI Embedded with Azure Functions (Demo)

1. What is Embedded Analytics?

Embedded Analytics refers to the integration of analytical content (reports, dashboards, data visualisations) directly within an application.

2. Why should I care?

User adoption of centralised BI systems has and continues to be a persistent challenge. With only a fraction of users ever leveraging some form of analytical capability, the majority of users are left ill-informed with adoption rates stagnating between 15 - 25%. This kind of makes absolute sense when you think of the expectation that is placed on consumers in order to reap any reward.

Typical Example:

  • User X is in the middle of working with Bus App Y and would like to analyse some of the underlying data.
  • In order to do so, User X would need to stop what they are doing and switch over to a BI platform, usually via a centralised portal.
  • Once complete, switch back and resume working.

As you can appreciate, this is quite disruptive to the users flow, and herein lies the opportunity! Embedded analytics delivers insights directly to users, significantly increasing the likelihood of adoption while accelerating the users time to value.

3. What is Power BI Embedded?

Power BI Embedded enables ISVs and developers to integrate Power BI content (reports, dashboards and tiles) directly into an application.

  • You simply provision and pay for the dedicated capacity required to serve the content and meet peak usage demand.
  • Each individual consumer does not require a license.
  • There only needs to be a single "master" Power BI Pro account.

Note:

  • The Power BI Embedded offering is targeted at ISVs and developers (i.e. building apps for external users).
  • If you are looking to embed Power BI within the enterprise context (e.g. an internal portal, SharePoint, Microsoft Teams), the guidance from Microsoft is to look at Power BI Premium, as this SKU may be better suited when combined with existing internal usage of the Power BI service.
  • Check out the Power BI Embedded FAQ for more info.

4. Power BI Embedded History

Not to dwell on the past but understanding Power BI Embedded's history to date may provide some needed clarity as the offering has evolved since its initial release.

pbi_embedded_history.png

With the above in mind...

Power BI Workspace Collections

  • You may still see this resource in the Azure marketplace or stumble across the term in Google, this is the legacy version of the Power BI Embedded offering prior to the API convergence that occurred in May 2017.
  • Power BI Workspace Collections are on the deprecation path and will be completely retired in June 2018.
  • The legacy pricing model was based on sessions (current model based on capacity).

5. Power BI Embedded with Azure Functions (Demo)

At a high-level, there are essentially four steps...

  1. Register an Azure AD application
  2. Provision Power BI Embedded Capacity (Azure)
  3. Get an Embed Token (Power BI API)
  4. Embed Content into your Web App (Power BI JavaScript Library)

Step 1. Register an Azure AD Application

  1. Navigate to https://dev.powerbi.com/apps
  2. Log in with your Power BI Pro account (this account should also have access to Azure).
  3. Populate application details.
    • App Name (e.g. PBIE Demo)
    • App Type (Native App)
    • Redirect URL (http://localhost:13526/redirect)
  4. Configure your level of access by choosing the API's that you need.
  5. Click Register App.

Note: When registering an application to access Power BI API's to facilitate Power BI Embedded scenarios, always choose Native App (even if you are ultimately surfacing the content in a web app).

While the app registration form does get us about 80% of the way there, we need to grant some additional permissions via Azure to complete this step.

  1. Log on to the Azure portal.
  2. Navigate to Azure AD > App Registrations > Your Power BI App.
  3. Click Settings > Required Permissions.
  4. Click Windows Azure Active Directory, check Access the directory as the signed-in user, click Save.
  5. Click Power BI Service, check Delegated Permissions to select all, click Save.
  6. Click Grant Permissions, click Yes.

Step 2. Provision Power BI Embedded Capacity (Azure)

Power BI Embedded Capacity (Azure)

  1. Log on to the Azure portal.
  2. Create a Power BI Embedded resource.
  3. Fill in the required property values.
    • Resource Name (e.g. pbiecapacity)
    • Subscription (a valid Azure subscription)
    • Resource Group (e.g. PBIE)
    • Power BI Capacity Administrator (your Power BI Pro account)
    • Location (e.g. West Central US)
    • Pricing Tier (e.g. A1)
  4. Click Create.

Note: Power BI Embedded is billed hourly. If you pause the resource, you will not be charged.

Do I need Power BI Embedded capacity during Development / Testing?
During development and testing, you do not need Power BI Embedded dedicated capacity (i.e. you could skip this step) as you are able to generate a limited number of embed tokens (we'll get to embed tokens later) without this resource being active. In terms of the number of embed tokens that can be generated before being exhausted, this (afaik) is undocumented. That said, generally speaking, you can live without Power BI Embedded dedicated capacity until you are ready to transition to Production. With Power BI Embedded capacity you are then free to generate unlimited embed tokens.

App Workspace (Power BI)

  1. Log on to the Power BI service (https://powerbi.com)
  2. Click Workspaces > Create app workspace
  3. Fill in the required details.
    • Workspace Name (e.g. PBIE Demo Workspace)
    • Workspace ID (auto-populated)
    • Visibility (e.g. during the demo you may want to set this to Private)
    • Workspace Members (Power BI Pro account)
  4. Click Advanced > Toggle Dedicated Capacity (ON)
  5. Select the Power BI Embedded resource from the drop-down menu.
  6. Click Save.

Once complete, you should see a diamond icon next to your App Workspace to indicate that it is backed by premium capacity.

Note: You will need to publish some content into your App Workspace (i.e. Dashboards, Reports). You can do this via Power BI Desktop otherwise clicking Get Data > Samples can quickly get you started.

Step 3. Get an Embed Token (Power BI API)

The diagram below illustrates the high-level interchange of requests. In this example I am using an Azure Function to do the bulk of the work, once authenticated it will invoke the Power BI API to construct a JSON response that will include an Embed Token. The Embed Token allows the client (Power BI JavaScript Library) to embed Power BI content. There are obviously a number of ways this could be done (e.g. back-end web server logic). Using Azure Functions keeps our complexity low and should be easy to follow along. 

Power_BI_Embedded_Flow.png

Azure Function App

  1. Log on to the Azure portal.
  2. Create a Function App.
  3. Fill in the required property values.
    • App Name (e.g. pbieFunctionApp)
    • Subscription (valid Azure subscription)
    • Resource Group (e.g. PBIE)
    • OS (Windows)
    • Hosting Plan (Consumption Plan)
    • Location (e.g. West Central US)
    • Storage (Create New)
    • Application Insights (Off)
  4. Click Create

Azure Function (Code)

  1. Navigate to your Azure Function App.
  2. Create a new C# HTTP triggered function (i.e. Webhook + API).
  3. Navigate back to the Azure Function App (parent) and click Application Settings.
  4. Add the following settings:
    • Name: PBIE_CLIENT_ID; Value: Azure AD > App Name > Application ID
    • Name: PBIE_GROUP_ID; Value: <Power BI Group ID> (see notes)
    • Name: PBIE_REPORT_ID; Value: <Power BI Report ID> (see notes)
    • Name: PBIE_USERNAME; Value: Your Power BI Pro Account Username
    • Name: PBIE_PASSWORD; Value: Your Power BI Pro Account Password
  5. Click Save
  6. Navigate back to the Azure Function.
  7. Add a new file called project.json
  8. Copy and paste the JSON code from below into the file and click Save.
  9. Open run.csx.
  10. Copy and paste the C# code from run.csx below and click Save.

Note: The easiest way to get the Group ID and Report ID is directly from PowerBI.com. Simply open a report from your App Workspace that you intend on embedding and you can see the values in the URL (e.g. https://powerbi.com/groups/<Group ID>/reports/<Report ID>/ReportSection). These values can also be attained programmatically but to keep this demo as simple as possible, we are going to supply them directly.

That's it. To test your API, click on the </> Get Function URL link and navigate to it in your browser. The JSON response should look something like the below.

Power_BI_Embedded_GetEmbedToken.png

project.json

{
  "frameworks": {
    "net46":{
      "dependencies": {
        "Microsoft.IdentityModel.Clients.ActiveDirectory": "3.19.4",
        "Microsoft.PowerBI.Api": "2.0.12"
      }
    }
   }
}

run.csx

#r "System.Web.Extensions"
using System.Configuration;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.PowerBI.Api.V2;
using Microsoft.PowerBI.Api.V2.Models;
using Microsoft.Rest;

// Static Values
static string authorityUrl = "https://login.windows.net/common/oauth2/authorize/";
static string resourceUrl = "https://analysis.windows.net/powerbi/api";
static string apiUrl = "https://api.powerbi.com/";
static string clientId = ConfigurationManager.AppSettings["PBIE_CLIENT_ID"];
static string username = ConfigurationManager.AppSettings["PBIE_USERNAME"];
static string password = ConfigurationManager.AppSettings["PBIE_PASSWORD"];
static string groupId = ConfigurationManager.AppSettings["PBIE_GROUP_ID"];
static string reportId = ConfigurationManager.AppSettings["PBIE_REPORT_ID"];

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{

    // Authenticate with Azure Ad > Get Access Token > Get Token Credentials
    var credential = new UserPasswordCredential(username, password);
    var authenticationContext = new AuthenticationContext(authorityUrl);
    var authenticationResult = await authenticationContext.AcquireTokenAsync(resourceUrl, clientId, credential);
    string accessToken = authenticationResult.AccessToken;
    var tokenCredentials = new TokenCredentials(accessToken, "Bearer");
    
    using (var client = new PowerBIClient(new Uri(apiUrl), tokenCredentials))
    {
        // Embed URL
        Report report = client.Reports.GetReportInGroup(groupId, reportId);
        string embedUrl = report.EmbedUrl;

        // Embed Token
        var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
        EmbedToken embedToken = client.Reports.GenerateTokenInGroup(groupId, reportId, generateTokenRequestParameters);

        // JSON Response
        EmbedContent data = new EmbedContent();
        data.EmbedToken = embedToken.Token;
        data.EmbedUrl = embedUrl;
        data.ReportId = reportId;
        JavaScriptSerializer js = new JavaScriptSerializer();
        string jsonp = "callback(" +  js.Serialize(data) + ");";

        // Return Response
        return new HttpResponseMessage(HttpStatusCode.OK) 
        {
            Content = new StringContent(jsonp, Encoding.UTF8, "application/json")
        };
    }
}

public class EmbedContent
{
    public string EmbedToken { get; set; }
    public string EmbedUrl { get; set; }
    public string ReportId { get; set; }
}

Step 4. Embed Content into your Web App (Power BI JavaScript Library)

Finally, our front-end code to tie it all together.

  1. Copy and paste the HTML below into a single index.html file.
  2. Update the JavaScript variable getEmbedToken with your Azure Function URL.
  3. Open the file in your browser.

If successful, you should see the embedded Power BI report!

Note: You will notice that the HTML is referring to online hosted versions of the JavaScript library dependencies (jQuery & Power BI JS). This means we can get away with a single HTML document.

That's it! In this example I'm just running the HTML code from my local machine, if you wanted to go FULL SERVERLESS, you could upload the HTML document on to Blob storage and make the container public.

Power_BI_Embedded_Example.png
<html>

<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Power BI Embedded Demo</title>
    <link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
    <script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script type="text/javascript" language="javascript" src="https://rawgit.com/Microsoft/PowerBI-JavaScript/master/dist/powerbi.min.js"></script> </script>
</head>

<body>
    <h1>Power BI Embedded Demo</h1>
    <div id="reportContainer" style="width: 80%; height: 600px;"></div>
</body>

<script>
    $(document).ready(function () {
        var getEmbedToken = "INSERT_YOUR_AZURE_FUNCTION_URL_HERE";

        $.ajax({
            url: getEmbedToken,
            jsonpCallback: 'callback',
            contentType: 'application/javascript',
            dataType: "jsonp",
            success: function (json) {

                var models = window['powerbi-client'].models;

                var embedConfiguration = {
                    type: 'report',
                    id: json.ReportId,
                    embedUrl: json.EmbedUrl,
                    tokenType: models.TokenType.Embed,
                    accessToken: json.EmbedToken
                };

                var $reportContainer = $('#reportContainer');
                var report = powerbi.embed($reportContainer.get(0), embedConfiguration);


            },
            error: function () {
                alert("Error");
            }
        });

    });
</script>

</html>