Atualmente, a busca por informação quer para um negócio pessoal quer para vida pessoal, quer-se de forma instantânea e se possível sem necessidade de interação por parte dos utilizadores.
O que se pretende abordar será a integração de dados com o Power BI em tempo real.
Através do recentemente lançado Power BI API Rest, é possível atualizar a informação de um Dashboard em tempo real sempre que a nossa fonte de dados sofra alterações. Qualquer linguagem de programação com suporte REST pode fazer integração com esta API.
Apesar das limitações que esta API ainda possui, já é possível usar algumas das mais importantes funcionalidades, entre as quais:
- Autenticação com Azure Active Directory OAuth2
- Criação/Eliminação datasets
- Adicionar / Remover dados
Abaixo é descrito o comportamento de uma aplicação para o Power BI:
Fonte – https://msdn.microsoft.com/en-us/library/dn877544.aspx
Para este exemplo foi criada uma aplicação consola em C#, que envia continuamente os dados de um computador local para o PowerBI. Para a interacção com a API os pedidos JSON são enviados através do protocolo HTTP.
Para podermos aceder à Power Bi Rest API, é necessário autenticarmos a nossa aplicação na Azure AD, previamente criada com as configurações necessárias.
Autenticação com Azure Active Directory (OAuth2)
O método de autenticação usado foi o seguinte:
private TokenSingleton()
{
try
{
//Get access token:
// To call a Power BI REST operation, create an instance of AuthenticationContext and call AcquireToken
// AuthenticationContext is part of the Active Directory Authentication Library NuGet package
// To install the Active Directory Authentication Library NuGet package in Visual Studio,
// run “Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory” from the nuget Package Manager Console.
//Resource Uri for Power BI API
// OAuth2 authority Uri = https://analysis.windows.net/powerbi/api
string resourceUri = ConfigurationManager.AppSettings[nsCom.Consts.ResourceUri];
// ClientID provided from Azure AD Application
string clientId = ConfigurationManager.AppSettings[nsCom.Consts.ClientID];
// Create an instance of AuthenticationContext to acquire an Azure access token
// OAuth2 authority Uri = https://login.windows.net/common/oauth2/authorize
string authorityUri = ConfigurationManager.AppSettings[nsCom.Consts.AuthorityUri]; ;
AuthenticationContext authContext = new AuthenticationContext(authorityUri);
UserCredential UserCredential = new UserCredential(ConfigurationManager.AppSettings[nsCom.Consts.Username], ConfigurationManager.AppSettings[nsCom.Consts.Password]);
// Call AcquireToken to get an Azure token from Azure Active Directory token issuance endpoint
// AcquireToken takes a Client Id that Azure AD creates when you register your client app.
// To learn how to register a client app and get a Client ID, see https://msdn.microsoft.com/en-US/library/dn877542(Azure.100).aspx
token = authContext.AcquireToken(resourceUri, clientId, UserCredential);
}
catch (Exception ex)
{
throw ex;
}
}
O token criado é então usado para as futuras chamadas à API.
Criação Dataset
O próximo passo será criar o dataset que irá compor o Dashboard. Os tipos que poderão ser usados para as colunas das tabelas são : int64, bool, DateTime, string e double. Para criação do dataset schema é necessário serializar o objeto em JSON e enviar para o PowerBI:
/// <summary>
/// Creates a dataset based on a DatasetSchema.
/// </summary>
/// <param name=”Schema”>Dataset Schema represents the definition of dataset including dataset name, tables and columns for each table.</param>
/// <returns>Created dataset as .NET object.</returns>
public static dataset GetDataset()
{
try
{
// DatasetName = DataSet
DataSet dataset = new DataSet() { name = ConfigurationManager.AppSettings[nsCom.Consts.DatasetName]};
dataset.tables =new Table[1];
dataset.tables[0] = new Table() { name = “IntGeneratorTable” };
dataset.tables[0].columns = new Column[2];
dataset.tables[0].columns[0] = new Column() { name = “DateTime”, dataType = “DateTime” };
dataset.tables[0].columns[1] = new Column() { name = “Int”, dataType = “Int64” }
// LIB used to serialize objects to JSON
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
var str = jsonSerializer.Serialize(dataset);
//Power BI Datasets Url
string powerBIApiUrl = “https://api.powerbi.com/v1.0/myorg/datasets“;
byte[] byteArray = Encoding.UTF8.GetBytes(str);
HttpWebRequest request = System.Net.WebRequest.Create(powerBIApiUrl) as System.Net.HttpWebRequest;
request.KeepAlive = true;
request.Method = “POST”;
request.ContentLength = byteArray.Length;
request.ContentType = “application/json”;
//Add access token to Request header
request.Headers.Add(“Authorization”, String.Format(“Bearer {0}”, nsToken.TokenSingleton.Instance.token.AccessToken));
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
//Get HttpWebResponse from GET request
using (HttpWebResponse httpResponse = request.GetResponse() as System.Net.HttpWebResponse)
{
//Get StreamReader that holds the response stream
using (StreamReader reader = new System.IO.StreamReader(httpResponse.GetResponseStream()))
{
string responseContent = reader.ReadToEnd();
jsonSerializer = new JavaScriptSerializer();
return (dataset)jsonSerializer.Deserialize(responseContent, typeof(dataset));
}
}
}
catch (Exception ex)
{
throw ex;
}
}
O token criado é então usado para as futuras chamadas à API.
Criação Dataset
O próximo passo será criar o dataset que irá compor o Dashboard. Os tipos que poderão ser usados para as colunas das tabelas são : int64, bool, DateTime, string e double. Para criação do dataset schema é necessário serializar o objeto em JSON e enviar para o PowerBI:
/// <summary>
/// Creates a dataset based on a DatasetSchema.
/// </summary>
/// <param name=”Schema”>Dataset Schema represents the definition of dataset including dataset name, tables and columns for each table.</param>
/// <returns>Created dataset as .NET object.</returns>
public static dataset GetDataset()
{
try
{
// DatasetName = DataSet
DataSet dataset = new DataSet() { name = ConfigurationManager.AppSettings[nsCom.Consts.DatasetName]};
dataset.tables =new Table[1];
dataset.tables[0] = new Table() { name = “IntGeneratorTable” };
dataset.tables[0].columns = new Column[2];
dataset.tables[0].columns[0] = new Column() { name = “DateTime”, dataType = “DateTime” };
dataset.tables[0].columns[1] = new Column() { name = “Int”, dataType = “Int64” }
// LIB used to serialize objects to JSON
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
var str = jsonSerializer.Serialize(dataset);
//Power BI Datasets Url
string powerBIApiUrl = “https://api.powerbi.com/v1.0/myorg/datasets“;
byte[] byteArray = Encoding.UTF8.GetBytes(str);
HttpWebRequest request = System.Net.WebRequest.Create(powerBIApiUrl) as System.Net.HttpWebRequest;
request.KeepAlive = true;
request.Method = “POST”;
request.ContentLength = byteArray.Length;
request.ContentType = “application/json”;
//Add access token to Request header
request.Headers.Add(“Authorization”, String.Format(“Bearer {0}”, nsToken.TokenSingleton.Instance.token.AccessToken));
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
//Get HttpWebResponse from GET request
using (HttpWebResponse httpResponse = request.GetResponse() as System.Net.HttpWebResponse)
{
//Get StreamReader that holds the response stream
using (StreamReader reader = new System.IO.StreamReader(httpResponse.GetResponseStream()))
{
string responseContent = reader.ReadToEnd();
jsonSerializer = new JavaScriptSerializer();
return (dataset)jsonSerializer.Deserialize(responseContent, typeof(dataset));
}
}
}
catch (Exception ex)
{
throw ex;
}
}
Este método criou uma tabela com uma coluna de inteiros e uma de data que irá permitir o armazenamento de dados. No response do pedido HTTP é permitido obter o ID do dataset que nos irá permitir , mais tarde, aceder ao dataset (para as operações de edição / eliminação de dados).
Para além da criação de um dataset também nos é permitido eliminar e obter um dataset previamente criado.
Adicionar dados
Finalmente, com o dataset criado, é agora possivel adicionar dados. Foi criado um caso de teste, que envia os dados do CPU continuamente para o Power BI. Mais uma vez é criado um objecto em C#, e posteriormente é serializado um objecto JSON, e enviado no HTTP Request.
public static void SendData(dataset_dataset)
{
string powerBIApiUrl = String.Format(“https://api.powerbi.com/v1.0/myorg/datasets/{0}/tables/{1}/rows”, _dataset.Id, “IntGeneratorTable”);
while (1 == 1)
{
// Data Generated
PerformanceCounter cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = “Processor”;
cpuCounter.CounterName = “% Processor Time”;
cpuCounter.InstanceName = “_Total”;
// will always start at 0
dynamic firstValue = cpuCounter.NextValue();
System.Threading.Thread.Sleep(1000);
// now matches task manager reading
dynamic secondValue = cpuCounter.NextValue();
// My object
TableRows rows = new TableRows();
rows.rows = new ArrayList();
rows.rows.Add(new IntGeneratorTable() { DateTime = DateTime.Now, Int = Convert.ToInt32(secondValue) });
JavaScriptSerializer JavaScriptSerializer = new JavaScriptSerializer();
var json = JavaScriptSerializer.Serialize(rows).ToString();
byte[] byteArray = Encoding.UTF8.GetBytes(json);
HttpWebRequest request = System.Net.WebRequest.Create(powerBIApiUrl) as System.Net.HttpWebRequest;
request.KeepAlive = true;
request.Method = “POST”;
request.ContentLength = byteArray.Length;
request.ContentType = “application/json”;
request.Headers.Add(“Authorization”, String.Format(“Bearer {0}”, nsToken.TokenSingleton.Instance.token.AccessToken));
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
// Get the response.
//Get HttpWebResponse from GET request
using (HttpWebResponse httpResponse = request.GetResponse() as System.Net.HttpWebResponse)
{
//Get StreamReader that holds the response stream
using (StreamReader reader = new System.IO.StreamReader(httpResponse.GetResponseStream()))
{
string responseContent = reader.ReadToEnd();
}
}
}
}
Assim, se o envio de dados for bem sucedido é possivel verificar o dashboard, a ser atualizado automaticamente:
Fontes
- Overview of Power BI REST API – https://msdn.microsoft.com/en-us/library/dn877544.aspx
- Power BI REST API limitations – https://msdn.microsoft.com/en-us/library/dn950053.aspx
- Power BI client app sample – https://msdn.microsoft.com/en-US/library/mt186159.aspx
.
.
.
.