Power BI Embedded のアプリ開発 (PHP, etc)


This post is the old article, and please see "How to use Power BI Embedded via REST" for new one.

(2016/07/20 : この投稿は古い情報です。最新の Power BI Embedded 開発については「How to use Power BI Embedded via REST」を参照してください。)

Power BI を使った開発

こんにちは。

以前、Power BI の UI を Application に組み込む方法として、Power BI の Tile や Report を embed する方法を紹介しました。(匿名での公開も、認証ありでの公開も可能です。「Power BI の UI を iframe で表示する」を参照してください。)
この方法は、構築した内容を部門内に共有するケースや (認証ありの場合)、逆に、広くあまねく外部に共有するケース (匿名の場合) で使用できます。

しかし、一般の開発者 (または ISV 企業) が顧客ごとに Application に組み込む場合、利用組織ごとの Provisioning (配置、展開) などの観点から、上述の embed の手法をそのまま使うわけにはいきません。(例えば、顧客組織ごとに参照するデータや Report なども変わってくるでしょう。)
こうしたケースでは、ここで紹介する Power BI Embedded を使って、展開先のアプリケーションごとに、DataSet や Report のセキュアな配布が可能です。利用顧客側では、Azure AD のアカウント (組織アカウント) を準備する必要もありませんので、従来の Credential と組み合わせて自由に Application に組み込むことができます。

現在、この Power BI Embedded を使った開発用に .NET と Node.js の SDK が提供されていますが、他言語でも開発できます。ここでは、こうした PHP, Python, Java など他言語の開発者も対象に、Power BI Embedded の内部動作 (仕組み) を紹介します(2016/05/05 : 赤字追記)

 

Power BI Embedded の概要

Power BI Embedded は Microsoft Azure 上の開発サービスであり、一般に、下記の流れで使用します。

  1. サービス提供者は、まず Microsoft Azure 上にログインして、Application 用に Power BI Workspace Collection という領域を作成します。
  2. Power BI Desktop や Excel などを使って Application 内で使用する DataSet や Report を作成します。(後述の通り、Database の Connection String を配置時に変えることができるので、ここでは開発用の一時的な Database を使って構築して構いません。)
  3. Power BI Workspace Collection 内に、サービス提供先の顧客 (利用組織) ごとに Power BI Workspace を作成します。
  4. 作成した Power BI Workspace に、上記で構築した Power BI Desktop や Excel などの成果物を Import します。
  5. Application 内から REST API を使って Report を取得し、Application 内に embed (貼り付け) します。

上記 1 は Azure Portal か (ARM ベースの) Azure REST API を使って構築 (管理) でき、上記 2 以降は Power BI Embedded REST API か Power BI Embedded の SDK (.NET SDK、NodeJS SDK を提供) を使います。

特に SDK は優秀で、これから述べる内部実装を理解しなくても、直観的な API を使って簡単に構築でき、下記の Getting Started のドキュメントですぐに試すことができます。(下記は .NET SDK のチュートリアルです。)

Microsoft Azure : Get started with Microsoft Power BI Embedded
https://azure.microsoft.com/en-us/documentation/articles/power-bi-embedded-get-started/

繰り返しになりますが、本投稿では、この SDK のサンプルは使用せず、Java、PHP、Python などのさまざまな言語で実装するケースを想定して中身を徹底解説します。

 

Power BI Workspace Collection の作成と Access Key の取得

まず、Azure Portal を表示して、Power BI Workspace Collection を作成します。(下図)

作成された Power BI Workspace Collection を表示すると、下図の通り Access Key を取得できるため、これをコピーします。

なお、前述の通り、Azure の新しい (ARM ベースの) REST API を使って、Power BI Workspace Collection を管理 (作成含む) できます。詳細は下記を参照してください。

Microsoft Azure : Power BI Embedded REST - Power BI Resource Provider APIs
https://msdn.microsoft.com/en-us/library/azure/mt712306.aspx

 

Authentication (AppToken による REST API 実行)

以降の処理は、すべて Power BI Embedded REST API (下記) を使って処理できます。(つまり、プログラムから呼び出せます。)

Microsoft Azure : Power BI Embedded REST
https://msdn.microsoft.com/en-us/library/azure/mt712303.aspx

この REST API の呼び出しには、上記で取得した Access Key を使って生成される App Token が必要です。
以降に、この AppToken の生成方法と Authentication の流れを解説します。

まず、基礎知識として、OAuth Json Web Token (JWT) の理解なので、知らない方は「Azure AD を使った Service (API) 開発 (access token の verify)」を熟読しておいてください。(ここでは、この JWT については知っているという前提で解説します。)
ただし、今回使用する Access Key は Symmetry Key のため、使用する algorithm (署名作成の algorithm) は、「Azure AD を使った Service (API) 開発 (access token の verify)」とは異なります。

Power BI Embedded REST API の AppToken は、一言で書くと、上記で取得した Access Key (Symmetric Key) から HMAC SHA256 アルゴリズムによって生成されるハッシュを OAuth JWT の Signature (デジタル署名) として使用する token です。(Azure Storage (v1) とのやりとりを SDK を頼らずに開発した経験がある方は、この辺りの仕組みはご存じかと思います。)

具体的に説明します。
まず、OAuth JWT の入力 (input) に相当する 1 番目の token と 2 番目の token として、以下の文字列を準備します。(下記は、見やすいように改行や空白を入れています。)
最初の token は署名のフォーマットを意味しており、HS256 は上述の HMAC SHA256 を意味しています。
2 番目の token の wcn は、上記で作成した Power BI Workspace Collection の名前で、nbf (Not Before) は Token の有効期限の開始日時 (通常は現在時刻)、exp (Expiration) は有効期限の終了日時 (通常は開始時刻より 1 時間後)、iss (Issuer) は皆さんが構築する Application の名前を設定します。(下記では、実際に .NET SDK が使用している Application 名を設定しています。)

{
  "typ": "JWT",
  "alg": "HS256"
}
{
  "ver": "0.1.0",
  "type": "provision",
  "wcn": "mywsc01",
  "iss": "PowerBISDK",
  "aud": "https://analysis.windows.net/powerbi/api",
  "exp": 1461586171,
  "nbf": 1461582584
}

Azure AD を使った Service (API) 開発 (access token の verify)」で解説したように、これら 2 つの token を RFC 4648 による Base 64 エンコード (Base64 Url Encoding) によってエンコードして、. (dot string) でつなげた下記のような文字列を作成します。

eyJ0eXAiOi・・・.eyJ2ZXIiOi・・・

この値を入力 (input) として、HMAC SHA265 によるハッシュ (バイトコード) を生成し、このハッシュを RFC 4648 Base 64 エンコード (Base64 Url Encoding) したものが添付する署名 (signature) です。
例えば、下記は、PHP と C# を使用して、この署名 (signature) を生成するサンプル コードです。(この方式は標準に沿ったものなので、多くの言語で関数や API などが提供されているはずです。)

PHP の場合

<?php
// Get encoded signature value
$hash = hash_hmac('sha256',
	'eyJ0eXAiOi...(input value)',
	'1iNOEz1fwr...(access key)',
	true);
$sig = rfc4648_base64_encode($hash);
print($sig);

function rfc4648_base64_encode($arg) {
  $res = $arg;
  $res = base64_encode($res);
  $res = str_replace('/', '_', $res);
  $res = str_replace('+', '-', $res);
  $res = rtrim($res, '=');
  return $res;
}	
?>

C# の場合

static void Main(string[] args)
{
  // Get encoded signature value
  var alg = System.Security.Cryptography.HashAlgorithm.Create();
  var key =
    new System.Security.Cryptography.HMACSHA256(
      Encoding.UTF8.GetBytes("1iNOEz1fwr...(access key)"));
  var resbyte =
    key.ComputeHash(
      Encoding.UTF8.GetBytes("eyJ0eXAiOi...(input value)"));
  var res = Rfc4648_Base64_Encode(resbyte);
  Console.WriteLine(res);
  Console.ReadLine();
}

static string Rfc4648_Base64_Encode(byte[] arg)
{
  string res = Convert.ToBase64String(arg);
  res = res.Replace('+', '-').Replace('/', '_');
  res = res.TrimEnd('=');
  return res;
}

前述の 1 番目の token と 2 番目の token に、この作成された署名を (ドット区切りで) 繋げた下記の OAuth JWT が AppToken です。

eyJ0eXAiOi・・・.eyJ2ZXIiOi・・・.VgoIEHGSOH・・・

生成された AppToken を使って、下記の通り、Power BI Embedded REST API を呼び出すことができます。

GET https://api.powerbi.com/beta/collections/{workspace collection name}/workspaces
Authorization: AppToken eyJ0eXAiOi...

なお、上述の 2 番目の token (Claim) は、利用場面に応じて異なる値が必要なので注意してください。
後述の手順における Workspace の作成時には type に provision を指定し、Workspace が決められた開発作業では type に dev を指定し、Report の Embed (Application の表示) では type に embed を指定します。

provision の場合 (Workspace の作成時)

{
  "ver": "0.1.0",
  "type": "provision",
  "wcn": "{workspace collection name}",
  "iss": "PowerBISDK",
  "aud": "https://analysis.windows.net/powerbi/api",
  "exp": {utc start time},
  "nbf": {utc end time}
}

dev の場合 (DataSet, Report の Import など)

{
  "ver": "0.1.0",
  "type": "dev",
  "wcn": "{workspace collection name}",
  "wid": "{workspace id}",
  "iss": "PowerBISDK",
  "aud": "https://analysis.windows.net/powerbi/api",
  "exp": {utc start time},
  "nbf": {utc end time}
}

embed の場合 (Report の表示時)

{
  "ver": "0.1.0",
  "type": "embed",
  "wcn": "{workspace collection name}",
  "wid": "{workspace id}",
  "rid": "{report id}",
  "iss": "PowerBISDK",
  "aud": "https://analysis.windows.net/powerbi/api",
  "nbf": {utc start time},
  "exp": {utc end time}
}

 

Workspace, DataSet, Report の作成

上述の概念がわかれば、あとは Power BI Embedded REST を使って、処理を順番に実行するだけです。
典型的な構築手順は下記です。

なお、以降では、上記で作成された {workspace collection name} を mywsc01 と仮定します。

Power BI Desktop を使った pbix ファイルの作成

Application に配置する DataSet と Report を Power BI Desktop を使って構築します。これは、もちろん、REST API ではなく、手作業で作ります。

そして、作成した内容を [名前を付けて保存] を選択し、.pbix ファイルとして保存します。

なお、下記の通り、接続先の Database の Connection String は REST API を使って (配置時などに) 変えることができるので、Power BI Desktop の成果物作成では Import や DirectQuery を使って開発用の Database と接続された形で作成して構いません。(下記の {workspace id} と {dataset id} については後述します。)
つまり、実際の配置の際、利用顧客ごとに接続先の Database をわけて展開できます。

POST https://api.powerbi.com/beta/collections/mywsc01/workspaces/{workspace id}/datasets/{dataset id}/Default.SetAllConnections
Authorization: AppToken eyJ0eXAiOi...

{
  "connectionString": "data source=MyAzureDB.database.windows.net;initial catalog=Sample2;persist security info=True;encrypt=True;trustservercertificate=False"
}

Power BI Workspace の作成

上述で作成した Power BI Workspace Collection (今回の場合、mywsc01 と仮定します) に、顧客用の Power BI Workspace を新規作成 (追加) します。
以下の REST API を実行します。

POST https://api.powerbi.com/beta/collections/mywsc01/workspaces
Authorization: AppToken eyJ0eXAiOi...
HTTP/1.1 201 Created
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true
Location: https://wabi-paas-1-scus-redirect.analysis.windows.net/beta/collections/mywsc01/workspaces

{
  "@odata.context": "http://wabi-paas-1-scus-redirect.analysis.windows.net/beta/collections/mywsc01/$metadata#workspaces/$entity",
  "WorkspaceId": "656c4ab0-4635-47ab-b4e9-23d322e35228",
  "workspaceCollectionName": "mywsc01"
}

ここで返される Workspace Id は、このあとの処理で使用しますので Application でおぼえておいてください。

pbix ファイルの Import

上記で保存した .pbix ファイルを Power BI Workspace に Import します。
下記の REST API を実行します。

なお、URI パラメータの datasetDisplayName には、Power BI Workspace 内に作成する DataSet の名前 (任意) を設定します。

POST https://api.powerbi.com/beta/collections/mywsc01/workspaces/656c4ab0-4635-47ab-b4e9-23d322e35228/imports?datasetDisplayName=mydataset01
Authorization: AppToken eyJ0eXAiOi...
Content-Type: multipart/form-data; boundary=A300testx

--A300testx
Content-Disposition: form-data

{.pbix ファイルの中身 (byte 列)}
--A300testx--

この要求の結果として、通常は、登録完了までに時間がかかるため、下記の通り、202 (Accepted) の HTTP Status と Import 作業の Id (Import Id) が返されます。

HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Location: https://wabi-paas-1-scus-redirect.analysis.windows.net/beta/myorg/imports/f55010a6-21c3-4e88-98ff-a127e12857c5

{
  "id":"f55010a6-21c3-4e88-98ff-a127e12857c5"
}

Application では、この Import Id (上記の f55010a6-21c3-4e88-98ff-a127e12857c5) を使って、下記の通り、登録の状況を確認できます。
下記は、まだ登録中 (Publishing) の状態です。

GET https://api.powerbi.com/beta/collections/mywsc01/workspaces/656c4ab0-4635-47ab-b4e9-23d322e35228/imports/f55010a6-21c3-4e88-98ff-a127e12857c5
Authorization: AppToken eyJ0eXAiOi...
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "id": "f55010a6-21c3-4e88-98ff-a127e12857c5",
  "importState": "Publishing",
  "createdDateTime": "2016-04-25T11:09:58.753",
  "updatedDateTime": "2016-04-25T11:09:58.753"
}

登録が完了 (成功) すると、下記の通り、登録結果が返されます。

補足 : 下記では、公開されている Power BI のサンプルをアップロードしたため、webUrl のみが設定されていますが、database と接続された開発では、下記の tablesdatasources に内容が設定されます。
上述の通り、dataset id を使って、この datasource の connection string を更新できます。

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "id": "f55010a6-21c3-4e88-98ff-a127e12857c5",
  "importState": "Succeeded",
  "createdDateTime": "2016-04-25T11:09:58.753",
  "updatedDateTime": "2016-04-25T11:09:58.753",
  "reports": [
    {
      "id": "c0c160e2-54a6-47ac-9893-7c73b4894d3b",
      "name": "mydataset01",
      "webUrl": "https://embedded.powerbi.com/reports/c0c160e2-54a6-47ac-9893-7c73b4894d3b",
      "embedUrl": "https://embedded.powerbi.com/appTokenReportEmbed?reportId=c0c160e2-54a6-47ac-9893-7c73b4894d3b"
    }
  ],
  "datasets": [
    {
      "id": "27faf92b-2f77-4411-8c0a-089be9392137",
      "name": "mydataset01",
      "tables": [
      ],
      datasources:[
      ],
      "webUrl": "https://embedded.powerbi.com/datasets/27faf92b-2f77-4411-8c0a-089be9392137"
    }
  ],
  "name": "mydataset01"
}

 

UI の作成 (Report の embed)

以上で設定は完了しました。(必要な Workspace, Database, DataSet, Report が準備できました。)
Application では、Report を取得して、Web の UI に貼り付けます。

まず、Application で、以下の REST API を実行して、使用可能な Report の一覧を取得できます。

GET https://api.powerbi.com/beta/collections/mywsc01/workspaces/656c4ab0-4635-47ab-b4e9-23d322e35228/reports
Authorization: AppToken eyJ0eXAiOi...
HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true

{
  "@odata.context": "http://wabi-paas-1-scus-redirect.analysis.windows.net/beta/collections/mywsc01/workspaces/656c4ab0-4635-47ab-b4e9-23d322e35228/$metadata#reports",
  "value": [
    {
      "id": "c0c160e2-54a6-47ac-9893-7c73b4894d3b",
      "name": "mydataset01",
      "webUrl": "https://embedded.powerbi.com/reports/c0c160e2-54a6-47ac-9893-7c73b4894d3b",
      "embedUrl": "https://embedded.powerbi.com/appTokenReportEmbed?reportId=c0c160e2-54a6-47ac-9893-7c73b4894d3b"
    }
  ]
}

HTTP Response (上記) の embedUrl が、Web に貼り付ける Report の URL になります。

これを iframe を使って貼り付けますが、もちろん、ここでも認証 (AppToken による認証) が必要です。「Power BI の UI を iframe で表示する」で解説した方法で、token (上記の AppToken) を iframe に POST する必要があります。(これにより、この embedUrl の内容が iframe に表示されます。)

注意 : 上述の通り、この際に使用する token (AppToken) の Claim に注意してください。(embed 用の Claim を設定してください。)

下記は、PHP を使って、この embedUrl を iframe で表示するサンプル コードです。このサンプルでは、Text Box に App Token を入力してボタンを押すと Report が表示されます。
(下記は Report の embedUrl をそのまま埋め込んでいますが、もちろん、現実の開発では、この辺りの処理もすべて Application から動的に設定してください。下記は、仕組みを理解する目的で作成したサンプルです。)

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Test page</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  access token:<input type="text" id="txtToken" />
  <button id="btnView">View Report !</button>
  <div id="divView">
    <iframe id="ifrTile" width="100%" height="400"></iframe>
  </div>
  <script>
    (function () {
      document.getElementById('btnView').onclick = function() {
        var iframe = document.getElementById('ifrTile'); 
        iframe.src = 'https://embedded.powerbi.com/appTokenReportEmbed?reportId=c0c160e2-54a6-47ac-9893-7c73b4894d3b'; 
        iframe.onload = function() {
          var token = document.getElementById('txtToken').value; 
          var msgJson = {
            action: "loadReport",
            accessToken: token,
            height: 500,
            width: 722
          };
          var msgTxt = JSON.stringify(msgJson);
          iframe.contentWindow.postMessage(msgTxt, "*");
        };
      };
    }());
  </script>
</body>
</html>

 

※ 変更履歴

2016/05/05  Power BI Embedded の Node.js SDK (PowerBI-Node) のリリースにあわせて追記

 

Comments (0)

Skip to main content