Reputation: 133
I'm embedding a Power BI report on a "Embed for customer" manner and authenticating via service account. I have managed to get the embed token for a single report and a single workspace using Microsoft guides.
The issue comes when making a POST request to https://api.powerbi.com/v1.0/myorg/groups/{workspace_id}/reports/{report_id}
. I get a 403 error.
Also, note that I am using Django and the final purpose is to process everything on the backend and just send a URL to the front end to put inside an iframe.
This is my Django View:
from django.shortcuts import render
from django.views.generic import TemplateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse
from django.views import View
from django.shortcuts import get_object_or_404
from .models import Dashboard, ReportConfig, EmbedConfig, EmbedTokenRequestBody
from .serializer import DashboardSerializer
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from powerbi.aadservice import AadService
import requests
import json
class DashboardView(viewsets.ModelViewSet):
serializer_class = DashboardSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
# Retrieve the user's groups
user = self.request.user
user_groups = user.groups.all()
# Filter the dashboards based on group membership
queryset = Dashboard.objects.filter(group__in=user_groups)
return queryset
class PbiEmbedService(View):
def get(self, request, workspace_id, report_id, additional_dataset_id=None):
'''Get embed params for a report and a workspace'''
report_url = f'https://api.powerbi.com/v1.0/myorg/groups/{workspace_id}/reports/{report_id}'
api_response = requests.get(report_url, headers=self.get_request_header())
if api_response.status_code != 200:
return JsonResponse(
{
'error': f'Error while retrieving Embed URL\n{api_response.reason}:\t{api_response.text}\nRequestId:\t{api_response.headers.get("RequestId")}'
},
status=api_response.status_code,
)
api_response = json.loads(api_response.text)
report = ReportConfig(api_response['id'], api_response['name'], api_response['embedUrl'])
dataset_ids = [api_response['datasetId']]
# Append additional dataset to the list to achieve dynamic binding later
if additional_dataset_id is not None:
dataset_ids.append(additional_dataset_id)
embed_token = self.get_embed_token_for_single_report_single_workspace(report_id, dataset_ids, workspace_id)
embed_config = EmbedConfig(embed_token.tokenId, embed_token.token, embed_token.tokenExpiry, [report.__dict__])
parsed_token = (embed_config.__dict__)
access_token = parsed_token['token']
#Here's where the issue starts
embed_url = f'https://api.powerbi.com/v1.0/myorg/groups/{workspace_id}/reports/{report_id}'
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.post(embed_url, headers=headers)
print(response)
return JsonResponse(embed_config.__dict__)
def get_request_header(self):
'''Get Power BI API request header'''
return {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + AadService.get_access_token()}
def get_embed_token_for_single_report_single_workspace(self, report_id, dataset_ids, target_workspace_id=None):
'''Get Embed token for single report, multiple datasets, and an optional target workspace
Args:
report_id (str): Report Id
dataset_ids (list): Dataset Ids
target_workspace_id (str, optional): Workspace Id. Defaults to None.
Returns:
EmbedToken: Embed token
'''
request_body = EmbedTokenRequestBody()
for dataset_id in dataset_ids:
request_body.datasets.append({'id': dataset_id})
request_body.reports.append({'id': report_id})
if target_workspace_id is not None:
request_body.targetWorkspaces.append({'id': target_workspace_id})
# Generate Embed token for multiple workspaces, datasets, and reports. Refer https://aka.ms/MultiResourceEmbedToken
embed_token_api = 'https://api.powerbi.com/v1.0/myorg/GenerateToken'
api_response = requests.post(embed_token_api, data=json.dumps(request_body.__dict__), headers=self.get_request_header())
if api_response.status_code != 200:
return JsonResponse(
{
'error': f'Error while retrieving Embed URL\n{api_response.reason}:\t{api_response.text}\nRequestId:\t{api_response.headers.get("RequestId")}'
},
status=api_response.status_code,
)
api_response = json.loads(api_response.text)
embed_token = EmbedConfig(api_response['tokenId'], api_response['token'], api_response['expiration'], [])
return embed_token
At the moment, what I got is:
{
"tokenId": "REDACTED",
"token": "REDACTED",
"tokenExpiry": "2023-07-12T22:47:42Z",
"reports": [
{
"id": "REDACTED",
"name": "Supply Chain Sample",
"embedUrl": "https://app.powerbi.com/reportEmbed?reportId=REDACTEDb&groupId=REDACTED&w=2&config=REDACTED"
}
]
}
Upvotes: 0
Views: 1740
Reputation: 1810
For Getting Embed URL, you need to send the GET request and not the POST request.
Refer Get Report In Group Documentation for more details.
Upvotes: 0