python - API Power BI 获取令牌但获取请求获取响应 401
问题描述
我已经在 Azure 中注册了一个 APP 来访问 PBI(使用 MFA);
APP详情:
- 原生应用(移动桌面)
- API 权限
- Azure Active Directory Graph (1) User.Read
- Power Bi 服务(一)DataSet.ReadWrite.All
我可以获取令牌,但尝试运行获取请求时出现错误 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
我希望获得组中的数据集列表,但收到错误 401
HTTPError:401 客户端错误:未经授权的 url:https ://api.powerbi.com/v1.0/myorg/groups//datasets
解决方案
以下是从 python 访问 powerBI 报告数据的步骤
先决条件
- 一个组织活动目录和一个全局管理员
- 一个 PowerBI Pro 许可证(您可以免费获得一个,用于试用)
您的 AD 中也登录到 Power BI 的用户
创建应用程序
您需要创建一个应用程序,请遵循本教程:https ://docs.microsoft.com/en-us/power-bi/developer/register-app 。确保保存应用程序密码和应用程序 ID。
确保权限全部正确(记住在 Azure AD 中修改权限时必须单击“保存”然后“授予权限”)。
确保链接存在 power bi 报告并已发布。
生成访问令牌
首先,您需要生成一个访问令牌,该令牌将用于在与 API 的进一步通信中对您自己进行身份验证。
端点: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
将APPLICATION_ID、APPLICATION_SECRET替换为您在 AAD 中创建应用程序后获得的应用程序 ID 和密码。用主用户的登录名/密码替换USER_ID和USER_PASSWORD 。其余部分保持原样。
如果成功,您应该获得类似于以下内容的响应:
{'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'}
获得令牌后,您就可以继续进行 PowerBi api 调用了。
发布我使用过的示例代码。
"""
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)
推荐阅读
- php - 从 PHP 中共享主机上的 cron 运行脚本时,如何使用 curl 绕过网站的接受 cookie?
- python - 在一行中从多返回函数中解包并分配单个返回值(Python)
- python - 在按钮上单击将字符发送到后台应用程序
- django - 将对象分组(不排序)到单个 Django 页面上的字母列表中
- python - python类的资源
- php - 调用未定义函数 codeigniter\locale_set_default() 时出现 codeigniter 错误
- python - 如何在语音到文本 python 中同时识别和输入?
- css - 在输入的最右边设置图标
- javascript - 如何使用 AJAX 在同一脚本中刷新 html 表和其他数据
- regex - 传递项目 ID 时 cloudbuild.yaml 文件中的正则表达式错误