Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Enhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends August 31st. Request your voucher.

Reply
Daniff
Helper I
Helper I

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 4
Daniff
Helper I
Helper I

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)}")

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

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

lbendlin
Super User
Super User

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.

Helpful resources

Announcements
July 2025 community update carousel

Fabric Community Update - July 2025

Find out what's new and trending in the Fabric community.

July PBI25 Carousel

Power BI Monthly Update - July 2025

Check out the July 2025 Power BI update to learn about new features.