Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.
I'm trying to test the APIs (get a list of datasets in my workspace) before progressing on to doing some dataflow work, but anything I do with the APIs after getting my token returns a 403 error.
I'm using the example website sample code from the adal python github page (https://github.com/AzureAD/azure-activedirectory-library-for-python/tree/dev/sample)
I added an extra requests.get call hitting up https://api.powerbi.com/v1.0/myorg/datasets to get a list of datasets and then just printing it out to the console, which gives me:
Running API
API Result: 403
The resource in the parameters.json file passed into the python script is "00000009-0000-0000-c000-000000000000" which I believe is correct. When I run the token through jwt.io to check it out, I see my username and scps of:
Capacity.Read.All Capacity.ReadWrite.All Content.Create Dashboard.Read.All Dashboard.ReadWrite.All Dataflow.Read.All Dataflow.ReadWrite.All Dataset.ReadWrite.All Group.Read Report.ReadWrite.All Workspace.Read.All Workspace.ReadWrite.All
Any help would be appreciated.
try:
from http import server as httpserver
from http import cookies as Cookie
except ImportError:
import SimpleHTTPServer as httpserver
import Cookie as Cookie
try:
import socketserver
except ImportError:
import SocketServer as socketserver
try:
from urllib.parse import urlparse, parse_qs
except ImportError:
from urlparse import urlparse, parse_qs
import json
import os
import random
import string
import sys
import requests
import urllib.request
import adal
# You can provide account information by using a JSON file. Either
# through a command line argument, 'python sample.py parameters.json', or
# specifying in an environment variable of ADAL_SAMPLE_PARAMETERS_FILE.
#
# The information inside such file can be obtained via app registration.
# See https://github.com/AzureAD/azure-activedirectory-library-for-python/wiki/Register-your-application-with-Azure-Active-Directory
#
# {
# "resource": "your_resource",
# "tenant" : "rrandallaad1.onmicrosoft.com",
# "authorityHostUrl" : "https://login.microsoftonline.com",
# "clientId" : "624ac9bd-4c1c-4687-aec8-b56a8991cfb3",
# "clientSecret" : "verySecret=""
# }
parameters_file = (sys.argv[1] if len(sys.argv) == 2 else
os.environ.get('ADAL_SAMPLE_PARAMETERS_FILE'))
if parameters_file:
with open(parameters_file, 'r') as f:
parameters = f.read()
sample_parameters = json.loads(parameters)
else:
raise ValueError('Please provide parameter file with account information.')
PORT = 8088
TEMPLATE_AUTHZ_URL = ('https://login.windows.net/{}/oauth2/authorize?'+
'response_type=code&client_id={}&redirect_uri={}&'+
'state={}&resource={}')
PBI_RESOURCE = '00000009-0000-0000-c000-000000000000'
RESOURCE = sample_parameters.get('resource', PBI_RESOURCE)
REDIRECT_URI = 'http://localhost:{}/getAToken'.format(PORT)
authority_url = (sample_parameters['authorityHostUrl'] + '/' +
sample_parameters['tenant'])
class OAuth2RequestHandler(httpserver.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/':
self.send_response(307)
login_url = 'http://localhost:{}/login'.format(PORT)
self.send_header('Location', login_url)
self.end_headers()
elif self.path == '/login':
auth_state = (''.join(random.SystemRandom()
.choice(string.ascii_uppercase + string.digits)
for _ in range(48)))
cookie = Cookie.SimpleCookie()
cookie['auth_state'] = auth_state
authorization_url = TEMPLATE_AUTHZ_URL.format(
sample_parameters['tenant'],
sample_parameters['clientId'],
REDIRECT_URI,
auth_state,
RESOURCE)
self.send_response(307)
self.send_header('Set-Cookie', cookie.output(header=''))
self.send_header('Location', authorization_url)
self.end_headers()
elif self.path.startswith('/getAToken'):
is_ok = True
try:
token_response = self._acquire_token()
access_token = token_response['accessToken']
#Later, if the access token is expired it can be refreshed.
#auth_context = adal.AuthenticationContext(authority_url)
#token_response_refresh = auth_context.acquire_token_with_refresh_token(
# token_response['refreshToken'],
# sample_parameters['clientId'],
# RESOURCE,
# sample_parameters['clientSecret'])
################OK We now have a token, lets do stuff with it to see if that works#########################
#refresh_token = token_response_refresh['accessToken']
print("Running API")
headers = {'Authorization': 'Bearer {}'.format(access_token), 'Content-Type': 'application/json'}
api = requests.get('https://api.powerbi.com/v1.0/myorg/datasets', headers=headers)
print("API Result: {}\n{}\n".format(api.status_code, api.text))
message = "Full Token Response: {}<br><br>token: {}<br><br>Status Code: {}<br>Returned: {}".format(token_response, access_token, api.status_code, api.text)
except ValueError as exp:
message = str(exp)
is_ok = False
self._send_response(message, is_ok)
def _acquire_token(self):
parsed = urlparse(self.path)
code = parse_qs(parsed.query)['code'][0]
state = parse_qs(parsed.query)['state'][0]
cookie = Cookie.SimpleCookie(self.headers["Cookie"])
if state != cookie['auth_state'].value:
raise ValueError('state does not match')
### Main logic begins
auth_context = adal.AuthenticationContext(authority_url)
return auth_context.acquire_token_with_authorization_code(
code,
REDIRECT_URI,
RESOURCE,
sample_parameters['clientId'],
sample_parameters['clientSecret'])
### Main logic ends
def _send_response(self, message, is_ok=True):
self.send_response(200 if is_ok else 400)
self.send_header('Content-type', 'text/html')
self.end_headers()
if is_ok:
#todo, pretty format token response in json
message_template = ('<html><head><title>Succeeded</title></head>'
'<body><p>{}</p></body></html>')
else:
message_template = ('<html><head><title>Failed</title></head>'
'<body><p>{}</p></body></html>')
output = message_template.format(message)
self.wfile.write(output.encode())
httpd = socketserver.TCPServer(('', PORT), OAuth2RequestHandler)
print('serving at port', PORT)
httpd.serve_forever()
Solved! Go to Solution.
Finally figured it out. The resource in the parameters.json needs to be https://analysis.windows.net/powerbi/api or it won't work.
Finally figured it out. The resource in the parameters.json needs to be https://analysis.windows.net/powerbi/api or it won't work.
Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City
Check out the April 2024 Power BI update to learn about new features.
User | Count |
---|---|
12 | |
2 | |
1 | |
1 | |
1 |