API Power BI Get token but get request get response 401

丶灬走出姿态 提交于 2019-12-08 01:57:25

问题


I have registered an APP in Azure to access PBI (with MFA);

APP details:

  • Native App (mobile desktop)
  • API Permissions
    • Azure Active Directory Graph (1) User.Read
    • Power Bi Service (1) DataSet.ReadWrite.All

I can get the token but when try to run a get request I get error 401.

import adal
import requests


authority_url = 'https://login.windows.net/<tennantID>'
resource_url = 'https://analysis.windows.net/powerbi/api'
target_url = 'https://api.powerbi.com/v1.0/myorg/groups/<groupID>/datasets'

client_id = '<applicationID>'
secret= '<clientsecretID>'

context = adal.AuthenticationContext(authority=authority_url,
                                     validate_authority=True,
                                     api_version=None)

token = context.acquire_token_with_client_credentials(resource=resource_url,
                                                     client_id=client_id,
                                                     client_secret=secret)

access_token = token.get('accessToken')

#print(access_token)


header = {'Authorization': f'Bearer {access_token}'}
#print(header)
r = requests.get(url=target_url, headers=header)
r

I expect to get a list of datasets on the group but getting error 401

HTTPError: 401 Client Error: Unauthorized for url: https://api.powerbi.com/v1.0/myorg/groups//datasets


回答1:


Here are the steps to access powerBI reporting data from python

Pre-requisite

  • an Organizational Active Directory, and a global admin on it
  • a PowerBI Pro Licence (you can get one for free, for trial)
  • a user in your AD that is also logged in to Power BI

  • Create an Application

You need to create an application, follow this tutorial: https://docs.microsoft.com/en-us/power-bi/developer/register-app. Make sure you save the application secret and application id.

Make sure the permissions are all correct (remember you have to click "Save" then "Grant permissions" when modifying the permission in Azure AD).

  • Ensure power bi report exist for the link and it is published.

  • Generating an Access Token

First thing first, you need to generate an access token, that will be used to authenticate yourself in further communication with the API.

Endpoint: https://login.microsoftonline.com/common/oauth2/token Method: POST Data:

grant_type: password
scope: openid
resource: https://analysis.windows.net/powerbi/api
client_id: APPLICATION_ID
client_secret: APPLICATION_SECRET
username: USER_ID
password: USER_PASSWORD

replace APPLICATION_ID, APPLICATION_SECRET with the application id and secret you got after creating the app in AAD. Replace USER_ID and USER_PASSWORD with the login/password for the master user. Leave the rest as is.

If successful, you should obtain a response similar to:

{'access_token': 'eyJ0...ubUA',
 'expires_in': '3599',
 'expires_on': '1515663724',
 'ext_expires_in': '0',
 'id_token': 'eyJ0A...MCJ9.',
 'not_before': '1515659824',
 'refresh_token': 'AQABAA...hsSvCAA',
 'resource': 'https://analysis.windows.net/powerbi/api',
 'scope': 'Capacity.Read.All Capacity.ReadWrite.All Content.Create Dashboard.Read.All Dashboard.ReadWrite.All Data.Alter_Any Dataset.Read.All Dataset.ReadWrite.All Group.Read Group.Read.All Metadata.View_Any Report.Read.All Report.ReadWrite.All Tenant.Read.All Workspace.Read.All Workspace.ReadWrite.All',
 'token_type': 'Bearer'}

Once you have obtained the token , you are good to proceed with PowerBi api calls.

posting a sample code which i have used.

"""
Simple example code to communicate with Power BI REST API. Hope it helps.


"""
import requests


# Configuration goes here:
RESOURCE = "https://analysis.windows.net/powerbi/api"  # Don't change that.
APPLICATION_ID = "abcdef-abcdef-abcdef-abcdef"  # The ID of the application in Active Directory
APPLICATION_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxx"  # A valid key for that application in Active Directory

USER_ID = "emmanuel@your_company.com"  # A user that has access to PowerBI and the application
USER_PASSWORD = "password"  # The password for that user

GROUP_ID = 'xxxxxxxxxxx'  # The id of the workspace containing the report you want to embed
REPORT_ID = 'xxxxxxxxxxxxxx'  # The id of the report you want to embed


def get_access_token(application_id, application_secret, user_id, user_password):
    data = {
        'grant_type': 'password',
        'scope': 'openid',
        'resource': "https://analysis.windows.net/powerbi/api",
        'client_id': application_id,
        'client_secret': application_secret,
        'username': user_id,
        'password': user_password
    }
    token = requests.post("https://login.microsoftonline.com/common/oauth2/token", data=data)
    assert token.status_code == 200, "Fail to retrieve token: {}".format(token.text)
    print("Got access token: ")
    print(token.json())
    return token.json()['access_token']


def make_headers(application_id, application_secret, user_id, user_password):
    return {
        'Content-Type': 'application/json; charset=utf-8',
        'Authorization': "Bearer {}".format(get_access_token(application_id, application_secret, user_id, user_password))
    }


def get_embed_token_report(application_id, application_secret, user_id, user_password, group_id, report_id):
    endpoint = "https://api.powerbi.com/v1.0/myorg/groups/{}/reports/{}/GenerateToken".format(group_id, report_id)
    headers = make_headers(application_id, application_secret, user_id, user_password)
    res = requests.post(endpoint, headers=headers, json={"accessLevel": "View"})
    return res.json()['token']


def get_groups(application_id, application_secret, user_id, user_password):
    endpoint = "https://api.powerbi.com/v1.0/myorg/groups"
    headers = make_headers(application_id, application_secret, user_id, user_password)
    return requests.get(endpoint, headers=headers).json()


def get_dashboards(application_id, application_secret, user_id, user_password, group_id):
    endpoint = "https://api.powerbi.com/v1.0/myorg/groups/{}/dashboards".format(group_id)
    headers = make_headers(application_id, application_secret, user_id, user_password)
    return requests.get(endpoint, headers=headers).json()


def get_reports(application_id, application_secret, user_id, user_password, group_id):
    endpoint = "https://api.powerbi.com/v1.0/myorg/groups/{}/reports".format(group_id)
    headers = make_headers(application_id, application_secret, user_id, user_password)
    return requests.get(endpoint, headers=headers).json()


# ex:
# get_embed_token_report(APPLICATION_ID, APPLICATION_SECRET, USER_ID, USER_PASSWORD, GROUP_ID, REPORT_ID)


来源:https://stackoverflow.com/questions/57305847/api-power-bi-get-token-but-get-request-get-response-401

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!