microsoft / powerbi-jupyter

A Custom Jupyter Widget Library for Power BI
MIT License
470 stars 151 forks source link

passing bearer access token to auth fails #34

Closed Cagataydemirkol closed 1 month ago

Cagataydemirkol commented 1 year ago

Hi team,

I have a service principal account and I would like to pass my bearer access token to Report() to avoid using either DeviceCodeLoginAuthentication or InteractiveLoginAuthenticationto prevent browser launching a page - so that I can perform this in remote machines.

group_id= "" report_id= "" report = Report(group_id=group_id, report_id=report_id, auth = access_token, view_mode=EmbedMode.VIEW.value)

Throws "LoadReportFailed - Fail to initialize - Could not resolve cluster".

Below is one of the methods I have used to obtain access token. (I have also used azure.identity ClientSecretCredential and adal libraries too which are not listed here, but failed to embed the report.)

Azure AD tenant ID and Power BI API resource URL

tenant_id = "" resource = "https://analysis.windows.net/powerbi/api"

Azure AD application client ID and client secret

client_id = "" client_secret = ""

Azure AD token endpoint

token_endpoint = f"https://login.microsoftonline.com/{tenant_id}/oauth2/token"

Request access token

headers = {"Content-Type": "application/x-www-form-urlencoded"}

data = { "grant_type": "client_credentials", "client_id": client_id, "client_secret": client_secret, "resource": resource } response = requests.post(token_endpoint, data=data) access_token = response.json()["access_token"]

bapat-atharva commented 1 year ago

Hi @Cagataydemirkol,

This approach you are using is used for App Owns Data. With this access-token you will be able to generate embed tokens using the PBI Rest APIs. But embed-tokens are not supported currently in powerbi-jupyter.

You could use master-user approach and specify a username(email) and password in the request with grant_type as 'password'. With this access token you should be able to embed any of the reports.

mhadi4194 commented 1 year ago

@bapat-atharva our organization will not allow master user. Our only option is Service Principal for authentication. The service principal has member role in powerbi the workspace of report and dataset. I am trying to download data from PowerBI visuals programmatically by running code in Google Cloud Function.

def get_powerbi_access_token(secrets: dict, scopes: list =None):
    from msal import ConfidentialClientApplication
    client_id = secrets['client_id']
    client_secret = secrets['client_secret']
    tenant_id = secrets['tenent_id']
    authority_url = f'https://login.microsoftonline.com/{tenant_id}'

    app = ConfidentialClientApplication(client_id,client_credential=client_secret,authority=authority_url)
    if not scopes:
        scopes = ['https://analysis.windows.net/powerbi/api/.default']

    return app.acquire_token_for_client(scopes=scopes)

access_token = get_powerbi_access_token(secrets)['access_token']
report = Report(group_id=group_id, report_id=report_id, auth=access_token)
report

It is throwing below error while running in notebook

Exception                                 Traceback (most recent call last)
File /opt/miniconda3/envs/powerbi/lib/python3.9/site-packages/ipywidgets/widgets/widget.py:773, in Widget._handle_msg(self, msg)
    771         if 'buffer_paths' in data:
    772             _put_buffers(state, data['buffer_paths'], msg['buffers'])
--> 773         self.set_state(state)
    775 # Handle a state request.
    776 elif method == 'request_state':

File /opt/miniconda3/envs/powerbi/lib/python3.9/site-packages/ipywidgets/widgets/widget.py:655, in Widget.set_state(self, sync_data)
    652 if name in self.keys:
    653     from_json = self.trait_metadata(name, 'from_json',
    654                                     self._trait_from_json)
--> 655     self.set_trait(name, from_json(sync_data[name], self))

File /opt/miniconda3/envs/powerbi/lib/python3.9/contextlib.py:126, in _GeneratorContextManager.__exit__(self, typ, value, traceback)
    124 if typ is None:
    125     try:
--> 126         next(self.gen)
    127     except StopIteration:
    128         return False

File /opt/miniconda3/envs/powerbi/lib/python3.9/site-packages/traitlets/traitlets.py:1498, in HasTraits.hold_trait_notifications(self)
   1496 for changes in cache.values():
   1497     for change in changes:
-> 1498         self.notify_change(change)

File /opt/miniconda3/envs/powerbi/lib/python3.9/site-packages/ipywidgets/widgets/widget.py:701, in Widget.notify_change(self, change)
    698     if name in self.keys and self._should_send_property(name, getattr(self, name)):
    699         # Send new state to front-end
    700         self.send_state(key=name)
--> 701 super().notify_change(change)

File /opt/miniconda3/envs/powerbi/lib/python3.9/site-packages/traitlets/traitlets.py:1513, in HasTraits.notify_change(self, change)
   1511 def notify_change(self, change):
   1512     """Notify observers of a change event"""
-> 1513     return self._notify_observers(change)

File /opt/miniconda3/envs/powerbi/lib/python3.9/site-packages/traitlets/traitlets.py:1560, in HasTraits._notify_observers(self, event)
   1557 elif isinstance(c, EventHandler) and c.name is not None:
   1558     c = getattr(self, c.name)
-> 1560 c(event)

File /opt/miniconda3/envs/powerbi/lib/python3.9/site-packages/powerbiclient/report.py:202, in Report._on_error(self, change)
    200 if (change['new'] is not self.INIT_ERROR_DEFAULT_STATE):
    201     self._init_error = self.INIT_ERROR_DEFAULT_STATE
--> 202     raise Exception(change['new'])

Exception: LoadReportFailed - Fail to initialize - Could not resolve cluster

Will this approach work to automate data export from powerbi reports to excel using functions on Azure or GCP?

v-MadhavC commented 1 month ago

In the powerbi-jupyter library, we use the "embed for your organization" scenario, which requires an Azure Active Directory (AAD) token instead of an Embed token, which means using a Service Principal is not supported. For more information about access token, please refer to this documentation - Permission tokens needed to embed a Power BI app - Power BI | Microsoft Learn

ayeshurun commented 1 month ago

The issue is closed since no response was received.