python - 尝试导出 powerbi 报告时出现 401 错误代码
问题描述
我可以使用 powerbi 的默认范围获取令牌(“范围”:“https://analysis.windows.net/powerbi/api/.default”])
使用该令牌,我可以读取我的用户有权访问的工作区(“https://api.powerbi.com/v1.0/myorg/groups”)以及每个工作区中的报告信息(“https ://api.powerbi.com/v1.0/myorg/reports/")
但是,如果我重复使用相同的令牌或只是获得一个全新的令牌并不重要,如果我尝试导出特定的报告,我会得到一个 401 错误代码。这就是我发出 requests.get 的方式
token_ = <new token or reused from previous get requests>
reports = requests.get( # Use token to call downstream service
config['reports']+report_id+'/Export',
headers={'Authorization': 'Bearer ' + token_ },)
现在,如果我去https://docs.microsoft.com/en-us/rest/api/power-bi/reports/getreportsingroup
并登录(使用我在 python 脚本上使用的同一用户)。从该页面获取令牌并将其用于我的脚本。它有效,如果我在邮递员中使用它,它有效我尝试在邮递员中使用我的脚本获取的令牌,我也会收到 401 错误。所以,是的,我的脚本没有为这个特定的入口点获取正确的令牌,但对于组和报告入口点来说已经足够了。
我需要在这个特定入口点的令牌请求中添加什么吗?
非常感谢,安德烈斯
这是我正在使用的完整脚本,还有一个 params.json,如下所示:
{
"authority": "https://login.microsoftonline.com/1abcdefg-abcd-48b6-9b3c-bd5123456",
"client_id": "5d2545-abcd-4765-8fbb-53555f2fa91",
"username":"myusername@tenant",
"password": "mypass",
"scope" : ["https://analysis.windows.net/powerbi/api/.default"],
"workspaces" : "https://api.powerbi.com/v1.0/myorg/groups",
"reports": "https://api.powerbi.com/v1.0/myorg/reports/"
}
#script based on msal github library sample
import sys # For simplicity, we'll read config file from 1st CLI param sys.argv[1]
import json
import logging
import requests
import msal
def exportReport(report_id,token_):
result = app.acquire_token_by_username_password( config["username"], config["password"], scopes=config["scope"])
token_ = result['access_token']
print(f'Using token: {token_}')
reports = requests.get( # Use token to call downstream service
config['reports']+report_id+'/Export',
headers={'Authorization': 'Bearer ' + token_ },)
print(f'-reports: {reports.status_code}')
def list_reports(workspace_id,ws_id,ws_name,token_):
print(f'reports id for workspace {ws_name}')
for rp in workspace_id['value']:
if rp["id"] == "1d509119-76a1-42ce-8afd-bd3c420dd62d":
exportReport("1d509119-76a1-42ce-8afd-bd0c420dd62d",token_)
def list_workspaces(workspaces_dict):
for ws in workspaces_dict['value']:
yield (ws['id'],ws['name'])
config = json.load(open('params.json'))
app = msal.PublicClientApplication(
config["client_id"], authority=config["authority"],
)
result = None
if not result:
logging.info("No suitable token exists in cache. Let's get a new one from AAD.")
result = app.acquire_token_by_username_password(
config["username"], config["password"], scopes=config["scope"])
if "access_token" in result:
workspaces = requests.get( # Use token to call downstream service
config['workspaces'],
headers={'Authorization': 'Bearer ' + result['access_token']},).json()
ids=list_workspaces(workspaces) #prepare workspace generator
headers = {'Authorization': 'Bearer ' + result['access_token']}
while True:
try:
ws_id,ws_name=next(ids)
reports = requests.get( # Use token to call downstream service
config['workspaces']+'/'+ws_id+'/reports',
headers={'Authorization': 'Bearer ' + result['access_token']},).json()
list_reports(reports,ws_id,ws_name,result['access_token'])
except StopIteration:
exit(0)
else:
print(result.get("error"))
print(result.get("error_description"))
print(result.get("correlation_id")) # You may need this when reporting a bug
if 65001 in result.get("error_codes", []):
# AAD requires user consent for U/P flow
print("Visit this to consent:", app.get_authorization_request_url(config["scope"]))
解决方案
根据您的描述,我想您没有为代码中用于登录您的用户帐户的 AD 应用授予正确的权限,请按照以下步骤操作。
导航到 Azure 门户 -> Azure Active Directory
-> App registrations
-> 找到您在代码中使用的 AD 应用程序(使用 过滤All applications
)-> ->在API 中API permissions
添加Report.Read.All
委托权限Power BI Service
(此权限仅用于读取操作,如果您需要进一步的写入操作,选择Report.ReadWrite.All
) ->Grant admin consent for xxx
最后单击按钮。
更新:
使用application id
从Get-PowerBIAccessToken
解决问题中获得的访问令牌。
推荐阅读
- android - No more emulator64-x86 or emulator64-arm using sdkmanager
- excel - 如何在 VBA 中找到一行“十六进制”单元格的校验和
- javascript - 我应该如何正确触发更改事件以触发单元测试中的功能?
- json - 如何在颤动中将 Json 数据传递到另一个屏幕
- graph - 找到由马尔可夫链定义的图的第一个顶点的最长路径
- javascript - 如何在第一次点击时停止重置缩放和平移 d3 图形?
- azure - 为什么在 Azure 应用服务中进行插槽交换后应用程序洞察力不起作用?
- angular - 在应用组件后面创建登录组件
- spring - 如果另一种类型的实体已经存在,如何防止保存一种类型的实体
- android-studio - 在 Android Studio 中包含第三方视图的简单方法?