Is it possible to get reports by filtering using power bi rest api? - powerbi

Is it possible to get reports by filtering using power bi rest api? I want to embed power bi reports filtering by records. I can't see any option on power bi rest api, then how to get all reports by filter and embed reports in my application?
Since I am using powerbi.js as javascript client so below is my sample code:
https://github.com/Microsoft/PowerBI-JavaScript
var tokenType = 'embed';
// Get models. models contains enums that can be used.
var models = window['powerbi-client'].models;
// We give All permissions to demonstrate switching between View and
//Edit mode and saving report.
var permissions = models.Permissions.All;
var config = {
type: 'report',
tokenType: tokenType == '0' ? models.TokenType.Aad :
models.TokenType.Embed,
accessToken: txtAccessToken,
embedUrl: txtEmbedUrl,
id: txtEmbedReportId,
permissions: permissions,
settings: {
filterPaneEnabled: true,
navContentPaneEnabled: true
}
};
// Get a reference to the embedded report HTML element
var embedContainer = $('#embedContainer')[0];
// Embed the report and display it within the div container.
var report = (<any>window).powerbi.embed(embedContainer, config);

When you are embedding a report, you can use the Embed Configuration to apply filters when the report is loaded. You can also change the filters dynamically later.
Here is a quote from filters wiki:
Filters are JavaScript objects that have a special set of properties. Currently, there are five types of filters: Basic, Advanced, Relative Date, Top N and Include/Exclude, which match the types of filters you can create through the filter pane. There are corresponding interfaces IBasicFilter, IAdvancedFilter, IRelativeDateFilter, ITopNFilter and IIncludeExcludeFilter, which describe their required properties.
For example, your filter can be constructed like this:
const basicFilter: pbi.models.IBasicFilter = {
$schema: "http://powerbi.com/product/schema#basic",
target: {
table: "Sales",
column: "AccountId"
},
operator: "In",
values: [1,2,3],
filterType: pbi.models.FilterType.BasicFilter
}
You should pass this filter in report's configuration filters property.

Related

The property includeHiddenPages is not working while calling exporttofile API in Power BI

I have embedded Power BI into my application (embed for customer). Whenever I use exporttofile API to export Power BI reports, it always includes the hidden pages. As per the exporttofile API documentation, if we set IncludeHiddenPages to False, it will exclude the hidden pages. But it is not working.
var powerBIReportExportConfiguration = new PowerBIReportExportConfiguration
{
Settings = new ExportReportSettings
{
Locale = "en-us",
IncludeHiddenPages = false
},
Pages = pageNames?.Select(pn => new ExportReportPage(pn)).ToList()
};
Please note that, I have been used .NET Core to embed Power BI into my application.
ExportReportRequest contains PowerBIReportExportConfiguration property where we can control to include hidden pages or not. Here is the code
var exportRequest = new ExportReportRequest {
Format : ExportFileFormat,
powerBIReportExportConfiguration = new PowerBIReportExportConfiguration
{
Settings = new ExportReportSettings
{
Locale = "en-us",
IncludeHiddenPages = false
},
Pages = pageNames?.Select(pn => new ExportReportPage(pn)).ToList()
};};
Export export = pbiClient.Reports.ExporttofileInGroup(workspaceId, ReportId, exportRequest);
Reference
ExportReportRequest

How to query a table that I don't own and don't have bigquery.jobs.create permissions on it

I was shared on a BigQuery table that I don't own and I don't have the bigquery.jobs.create permission on the dataset that contains the table.
I successfully listed all the tables in the dataset, but when I tried to query the table using this code:
tables.map(async (table) => {
const url = `https://bigquery.googleapis.com/bigquery/v2/projects/${process.env.PROJECT_ID}/queries`;
const query = `SELECT * FROM \`${table.id}\` LIMIT 10`;
const data = {
query,
maxResults: 10,
};
const reqRes = await oAuth2Client.request({
method: "POST",
url,
data,
});
console.log(reqRes.data);
});
I got the following error:
Error: Access Denied: Project project_id: <project_id>
gaia_id: <gaia_id>
: User does not have bigquery.jobs.create permission in project <project_id>.
I can't ask for those permissions, what should I do in this situation?
IMPORTANT:
I have tried to run the same query in the GCP and it ran successfully, but it seems like it created a temporary table clone and then queried this table and no the original one:
There are two projects here: your project, and the project that contains the table.
You currently create the job in ${process.env.PROJECT_ID} that you use in URL, try specifying your own project instead, where you can create jobs.
You'll need to modify query to include table's project to allow BigQuery to find it, so make sure ${table.id} includes project (table's - not yours), dataset and table.

Reading a Fragment from the Apollo Cache with client.readFragment()

After successfully executing a query, I can see the following (image attached) using Apollo Dev Tools.
However, I'm unable to query for a filter object directly with the ID, say, 2025. I'm getting an Uncaught Invariant Violation: Can't find field filters on ROOT_QUERY object.
Here's how I'm trying to query:
client.cache.readQuery({
query: gql`
query Filter {
filters {
key
value
}
}
`
});
I also tried with fragment as follows:
client.readFragment({
id: '2025',
fragment: gql`
fragment filter on filters {
id
key
value
}
`
});
But that gives me null.
You need to specify the object with the__typename and id that you are querying out of the cache. Notice that the id of the filters object is filters:[id] inside the Apollo Cache, that is the format you need to use to access that fragment in the cache, [__typename]:[key]. You can read more about assigning cache identifiers in the docs.
You access your fragment using the following:
const filter = client.readFragment({
fragment: gql`
fragment filter on filters {
id
key
value
}
`,
fragmentName: 'filter',
id: 'filter:2025'
})

How do I schedule refresh of a Web.Contents data source?

I am trying to set a 'Scheduled Refresh' on a dataset in the Power BI web app (https://app.powerbi.com).
Normally I should see these options in the dataset settings:
But when I go to settings I am greeted by this warning:
and no way to select the 'Gateway Connection' or data source settings.
I found a useful article which explains a problem with Web.Contents and how to get around it:
https://blog.crossjoin.co.uk/2016/08/23/web-contents-m-functions-and-dataset-refresh-errors-in-power-bi/
I applied this and it still doesn't work.
In Power BI Desktop no data sources are listed as I am using a hand-authored query.
The way it works is there is a main query (Log Scroll) which calls a recursive function query (RecursiveFetch). The function then calls a Web API which works by sending a new page of JSON data everytime it is called, in a sort of 'scrolling' manner.
The Log Scroll query looks like this:
let
url = "http://exampleURL:1000"
Source = RecursiveFetch(url, 5, null, null)
in
Source
The RecursiveFetch looks like this:
let
RecursiveFetch= (url, scrollCount, scrollID, counter) =>
let
Counter = if (counter = null) then 0 else counter,
Results = if (scrollID = null) then
Json.Document(Web.Contents(url,
[
Headers=[
#"Authorization"="Basic <key here>",
#"Content-Type"="application/json"
]
]
))
else
Json.Document(Web.Contents(url,
[
Content = Text.ToBinary(scrollID),
Headers=[
#"Authorization"="Basic <key here>",
#"Content-Type"="application/json"
]
]
)),
ParsedResults = Table.FromList(Results[hits][hits], Splitter.SplitByNothing(), null, null, ExtraValues.Error),
Return = if (Counter < scrollCount) then
ParsedResults & RecursiveFetch(url, scrollCount scrollID, Counter)
else
ParsedResults
in
Return
in
RecursiveFetch
It all works perfectly in Power BI Desktop but when I publish it to the web app I get the errors shown above.
I have manually set up a data source in my Gateway Cluster which connects fine to the URL with the same credentials that the hand-authored query uses.
How do I get this all to work? Is there something I have missed?
It all works perfectly in Power BI Desktop but when I publish it to the web app I get the errors shown above.
To fix that, Web.Contents needs to use options[RelativePath] and options[Query] (or Content for HTTP POST)
The original:
"https://data.gov.uk/api/3/action/package_search?q=" & Term
Will use:
let
BaseUrl = "https://data.gov.uk",
Options = [
RelativePath = "/api/3/action/package_search",
Headers = [
Accept="application/json"
],
Query = [
q = Term
]
],
// wrap 'Response' in 'Binary.Buffer' if you are using it multiple times
response = Web.Contents(BaseUrl, Options),
buffered = Binary.Buffer(response),
response_metadata = Value.Metadata(response),
status_code = response_metadata[Response.Status],
from_json = Json.Document(final_result)
in
from_json
the parameter url is going to be the minimum url possible, otherwise the service will think your dynamic request is actually unchanged -- causing the original refresh error.

Unable to generate embed token for accessing dataset due to missing roles in effective identity

I have embedded powerbi report which was working fine until I changed my database.
I observed datasets.IsEffectiveIdentityRequired (in below code) was false earlier, now as it is true, I'm getting an error - {"error":{"code":"InvalidRequest","message":"Creating embed token for accessing dataset 02c90e15-35dd-4036-a525-4f5d158bfade requires roles to be included in provided effective identity"}}
I'm using standard Embed service code.
// Create a Power BI Client object. It will be used to call Power BI APIs.
using (var client = new PowerBIClient(new Uri(ApiUrl), m_tokenCredentials))
{
// Get a list of reports.
var reports = await client.Reports.GetReportsInGroupAsync(WorkspaceId);
Report report = reports.Value.FirstOrDefault(r => r.Id.Equals(ReportId, StringComparison.InvariantCultureIgnoreCase));
var datasets = await client.Datasets.GetDatasetByIdInGroupAsync(WorkspaceId, report.DatasetId);
m_embedConfig.IsEffectiveIdentityRequired = datasets.IsEffectiveIdentityRequired;
m_embedConfig.IsEffectiveIdentityRolesRequired = datasets.IsEffectiveIdentityRolesRequired;
GenerateTokenRequest generateTokenRequestParameters;
// This is how you create embed token with effective identities
// HERE username IS NULL
if (!string.IsNullOrWhiteSpace(username))
{
var rls = new EffectiveIdentity(username, new List<string> { report.DatasetId });
if (!string.IsNullOrWhiteSpace(roles))
{
var rolesList = new List<string>();
rolesList.AddRange(roles.Split(','));
rls.Roles = rolesList;
}
// Generate Embed Token with effective identities.
generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view", identities: new List<EffectiveIdentity> { rls });
}
else
{
// Generate Embed Token for reports without effective identities.
generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
}
var tokenResponse = await client.Reports.GenerateTokenInGroupAsync(WorkspaceId, report.Id, generateTokenRequestParameters);
}
First, I completely understand that this error occurs as I'm not passing any identity. So, is there any option to disable IsEffectiveIdentityRequired?
Second, how to set users and roles in powerbi?
--I'm not a PowerBI expert--
IsEffectiveIdentityRequired is a read only property so you can't control it and there is no option to disable it.
Depending on the data source you are connecting to an effective identity may or may not be required.
If IsEffectiveIdentityRequired is true you need to pass an EffectiveIdentity when calling GenerateTokenRequest to generate an embed token. If the data source requires an effective identity and you do not pass one you will get an error when calling GenerateTokenRequest. You will also get an error if you pass an incomplete EffectiveIdentity, such as one that is missing roles when calling GenerateTokenRequest.
Here is an example of how you can use the IsEffectiveIdentityRequired property to generate an embed token with or without an effective identity depending on if the data source requires it or not.
List<EffectiveIdentity> eil = new List<EffectiveIdentity>();
EffectiveIdentity ef = new EffectiveIdentity();
// UserName
ef.Username = FullADUsername;
// Roles
List<string> Roles = new List<string>();
ef.Roles = Roles;
// Datasets
List<string> _Datasets = new List<string>();
_Datasets.Add(report.DatasetId);
ef.Datasets = _Datasets;
eil.Add(ef);
// Look up the data set of the report and look if we need to pass an Effective Identify
Dataset d = client.Datasets.GetDatasetByIdInGroup(WorkspaceId, report.DatasetId);
if (d.IsEffectiveIdentityRequired == true){
GenerateTokenRequest gtr = new GenerateTokenRequest("View", null, false, eil);
newEmbedToken = client.Reports.GenerateTokenInGroup(WorkspaceId, ReportId, gtr);
}
else
{
GenerateTokenRequest gtr = new GenerateTokenRequest();
newEmbedToken = client.Reports.GenerateTokenInGroup(WorkspaceId, ReportId, gtr);
}