Forum Discussion

Daniff's avatar
Daniff
Helper I
2 years ago

Power Bi with Phyton - export PDF

Good afternoon, I want to extract a PowerBI report in PDF so I can send it to the client. I use this code in phyton but the response is a 403 error! Someone can help me? thanks
 
 
import requests
import subprocess
from io import BytesIO

# Configurações da aplicação registrada no Azure Active Directory
tenant_id = 'x'
client_id = 'x'
client_secret = 'x'

# Configurações do relatório Power BI
workspace_id = 'me'
report_id = 'x'

# Obter token de acesso
authority = f'https://login.microsoftonline.com/{tenant_id}'
token_url = f'{authority}/oauth2/v2.0/token'
token_data = {
    'grant_type': 'client_credentials',
    'client_id': client_id,
    'client_secret': client_secret,
}
token_response = requests.post(token_url, data=token_data).json()
access_token = token_response.get('access_token')

if not access_token:
    print('Falha ao obter token de acesso.')
    exit()

# URL da API do Power BI para exportar o relatório como PPTX
api_url = f'https://api.powerbi.com/v1.0/myorg/groups/{workspace_id}/reports/{report_id}/exportTo'

# Parâmetros da solicitação para exportar como PPTX
export_parameters = {
    'format': 'PPTX',
    'settings': {
        'filterState': 'AllPages'
    }
}

# Faz a solicitação para exportar o relatório como PPTX
response = requests.post(api_url, headers={'Authorization': f'Bearer {access_token}'}, json=export_parameters)

if response.status_code == 202:
    # Sucesso - a exportação está em andamento
    print('Solicitação de exportação aceita. Aguarde alguns momentos e verifique seu Power BI Service.')

    # Recupera o link de download do arquivo exportado
    download_link = response.json().get('link')

    # Baixa o arquivo PPTX
    pptx_response = requests.get(download_link)

    # Converte PPTX para PDF usando unoconv
    pdf_path = 'relatorio.pdf'

    with open(pdf_path, 'wb') as pdf_file:
        subprocess.run(['unoconv', '--stdout', '--format=pdf', '-'], input=pptx_response.content, stdout=pdf_file)

    print(f'O relatório foi exportado como PDF em: {pdf_path}')

else:
    # Erro na solicitação
    print(f'Erro na solicitação. Código de status: {response.status_code}')
    print(response.text)

4 Replies

  • your code covers the partial process of requesting a PPTX export, not PDF.  It also misses all the other steps - monitoring rendering progress and then fetching the result of the rendering.

     

    Correct your code and add the missing steps - or use Power Automate which hides all that complexity from you.

  • this is new code. please help. erro 401!

    Considera este código como final pf

    # Importar bibliotecas necessárias

    import requests

    import json

    import pandas as pd

    import msal

    import os

    import time

     

    # Especificar Parâmetros

     

    # Service Principal

    client_id = '6b2c7699-67e4-446b-85c5-785cde6cac61'

    client_secret = 'O4k8Q~bPhbRsH2JzlQkJ0JKT6K4EjFfHJfSy6dtL'

     

    # Tenant Specification

    tenant_id = '10dd0fe4-58c7-43c5-a7c3-2a1bf4aae087'

    authority_url = 'https://login.microsoftonline.com/' + tenant_id

    scope = ['https://analysis.windows.net/powerbi/api/.default']

     

    # Report Specification

    workspace_id = '817d8d31-721c-4526-bffd-7fb26042ac62'

    report_id = '216452d6-d109-431c-a30c-d424c7f857e8'

    base_url = 'https://api.powerbi.com/v1.0/myorg/groups/' + workspace_id + '/reports/' + report_id

    format = 'PDF'

     

    # Report File Specification

    path = ''

     

    # Use MSAL para obter o token

    app = msal.ConfidentialClientApplication(client_id, authority=authority_url, client_credential=client_secret)

    result = app.acquire_token_for_client(scopes=scope)

     

    if 'access_token' in result:

        access_token = result['access_token']

        header = {'Content-Type': 'application/json', 'Authorization': f'Bearer {access_token}'}

     

        # Exportar relatório para PDF

        export_url = base_url + '/ExportTo'

        body = {"format": format}

     

        api_call = requests.post(export_url, headers=header, json=body)

        print(api_call)

        if api_call.status_code == 202:  # 202 indica que a exportação foi aceita

            export_id = api_call.json()['id']

            url_status = base_url + f'/exports/{export_id}'

     

            # Aguardar até que a exportação tenha sucesso

            while True:

                status_call = requests.get(url_status, headers=header)

                status = status_call.json().get('status', '')

     

                if status == 'Succeeded':

                    break

                elif status == 'Failed':

                    print("A exportação falhou.")

                    break

     

                # Aguardar um curto período antes de verificar novamente o status

                time.sleep(1)

     

            # Se a exportação foi bem-sucedida, salvar o PDF

            if status == 'Succeeded':

                url_save = base_url + f'/exports/{export_id}/file'

                api_call = requests.get(url_save, headers=header)

     

                if api_call.status_code == 200:

                    completename = os.path.join(path, f'report_{report_id}.pdf')

                    with open(completename, 'wb') as f:

                        f.write(api_call.content)

                    print(f"Relatório salvo como PDF: {completename}")

                else:

                    print("Erro ao salvar o PDF.")

        else:

            print(f"Erro na solicitação de exportação: {api_call.status_code}, {api_call.text}")

    else:

        print(f"Erro ao obter token de acesso: {result.get('error_description', result)}")

    • lbendlin's avatar
      lbendlin
      Super User

      That code looks better.  At what point do you get the 401?

      • Dream_on's avatar
        Dream_on
        New Member

        I can get the token, after the token it gives me the error. Don't you have to have a pro license? thanks