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

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.

Reply
insoluzioni
Advocate I
Advocate I

Expiration information about AccessToken generated with PowerBI Rest API

Hello,

I am trying to automatically import a PBIX file into my workspace with Power BI Embedded, currently using the code below, but I get the error: 

HTTP Error 400. The request is badly formed.

I really couldn't find the correct syntax to send it via PHP cURL, currently using this:

 

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://api.powerbi.com/v1.0/collections/$workspace_collection_name/workspaces/$workspace_id/imports?datasetDisplayName=$display_name&nameConflict=$nameConflict");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_POST, TRUE);
$boundary = "BOUNDARY";

$postdata = "--". $boundary . "\r\n";
$postdata .= "Content-Disposition: form-data;\r\n";
$postdata .= "\r\n";
$postdata .= "{".file_get_contents($file_path)."}";
$postdata .= "--".$boundary . "--\r\n";

curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: AppKey  $access_key",
  "Content-Type: multipart/form-data; boundary=$boundary"  
)); 

$response = curl_exec($ch);
curl_close($ch);
var_dump($response);

Anyone would spot what I am doing wrong?

Thanks

1 ACCEPTED SOLUTION

Thanks for the reply @Eric_Zhang!

Actually, the problem was in the DisplayName variable, which had spaces. Solved that by removing these spaces, but don't know if there's another workaround.

 

I've worked hard to make this work in PHP, but happened to be some little details in the syntax of the HTTP request. I'm sharing my solution below to successfuly import a PBIX file to your workspace:

 

 

/**
 * Imports specified PBIX file to workspace collection
 *
 * @param string $file_path
 * @param string $file_name
 * @param string $display_name
 * @return void
 */

function importPBIX($file_path, $file_name, $display_name) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, "https://api.powerbi.com/v1.0/collections/".COLLECTION_NAME.
            "/workspaces/".WORKSPACE_ID."/imports?datasetDisplayName=$display_name");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    curl_setopt($ch, CURLOPT_POST, TRUE);
    $boundary = "BOUNDARY";
    $postdata = "--".$boundary . "\r\n";
    $postdata .= "Content-Disposition: form-data; name=\"" . $file_name . "\"; filename=\"" . $file_name . "\"\r\n";
    $postdata .= "Content-Type: application/octet-stream\r\n\r\n";
    $postdata .= file_get_contents($file_path);
    $postdata .= "\r\n";
    $postdata .= "--".$boundary . "--\r\n";

    curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Content-Type: multipart/form-data; boundary=\"$boundary\"",
        "Authorization: AppKey " . APP_KEY
    )); 
    curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );

    $response = curl_exec($ch);
    curl_close($ch);

    // Retorna o id do relatório importado
    $responseJson = json_decode($response, TRUE);
    $repoId = $responseJson['id'];

    // Retorna dados do relatório   
    return $repoId;
}

Pay attention to the constants COLLECTION_NAME, WORKSPACE_ID AND APP_KEY that must be defined previously in this code.

Thanks!

 

View solution in original post

2 REPLIES 2
Eric_Zhang
Employee
Employee


@insoluzioni wrote:

Hello,

I am trying to automatically import a PBIX file into my workspace with Power BI Embedded, currently using the code below, but I get the error: 

HTTP Error 400. The request is badly formed.

I really couldn't find the correct syntax to send it via PHP cURL, currently using this:

 

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://api.powerbi.com/v1.0/collections/$workspace_collection_name/workspaces/$workspace_id/imports?datasetDisplayName=$display_name&nameConflict=$nameConflict");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);

curl_setopt($ch, CURLOPT_POST, TRUE);
$boundary = "BOUNDARY";

$postdata = "--". $boundary . "\r\n";
$postdata .= "Content-Disposition: form-data;\r\n";
$postdata .= "\r\n";
$postdata .= "{".file_get_contents($file_path)."}";
$postdata .= "--".$boundary . "--\r\n";

curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
  "Authorization: AppKey  $access_key",
  "Content-Type: multipart/form-data; boundary=$boundary"  
)); 

$response = curl_exec($ch);
curl_close($ch);
var_dump($response);

Anyone would spot what I am doing wrong?

Thanks


@insoluzioni

The error shows nothing on PHP specific I think, it tells that there's something wrong in the request. I don't know PHP, however below C# demo can compose a good request and import a pbix to my workspace. You can reference the demo and tweak the request in PHP accordingly.

 

using System;
using System.Net;
using System.IO;
namespace PBIGettingStarted
{
    class Program
    {
        //Access key for app token
        private static string accessKey = "yourAccesskey";
        //Power BI app token values
        private static string workspaceCollectionName = "yourworkspacecollectioname";
        private static string workspaceId = "yourworkspaceid";
        private static string pbixFileName = "pbixname.pbix";
        static void Main(string[] args)
        {
            //Imports uri
            var uri = String.Format
("https://api.powerbi.com/v1.0/collections/{0}/workspaces/{1}/imports?datasetDisplayName=SampleImport",
workspaceCollectionName, workspaceId);
            //PBIX file to import
  
            string fileName = @"C:\test\kpi.pbix";

            //Create web request
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            //Import Request format:
            // Header:
            //  Content - Type: multipart / form - data; ----------BOUNDARY
            //  Authorization: AppToken
            // Body:
            //  ----------BOUNDARY
            //  Content - Disposition: form - data; filename = "{pbix file}.pbix"
            //  Content - Type: application / octet – stream

            //Define POST
            request.Method = "POST";
            request.UseDefaultCredentials = true;
            //Header
            // Boundary
            string boundary = "----------BOUNDARY";
            byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
            // Content - Type
            request.ContentType = "multipart/form-data; boundary=" + boundary;
            // Authorization - Use AppToken jwt for Authorization header
            request.Headers.Add("Authorization", String.Format("AppKey {0}", accessKey));
            //Body
            string bodyTemplate = "Content-Disposition: form-data; filename=\"{0}\"\r\nContent-Type: application / octet - stream\r\n\r\n";
            string body = string.Format(bodyTemplate, fileName);
            byte[] bodyBytes = System.Text.Encoding.UTF8.GetBytes(body);
            //Get request stream 
            using (Stream rs = request.GetRequestStream())
            {
                rs.Write(boundaryBytes, 0, boundaryBytes.Length);
                rs.Write(bodyBytes, 0, bodyBytes.Length);
                using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    byte[] buffer = new byte[4096];
                    int bytesRead = 0;
                    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                    {
                        rs.Write(buffer, 0, bytesRead);
                    }
                }
                byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
                rs.Write(trailer, 0, trailer.Length);
            }
            //Get response
            using (HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse)
            {
                //If Import succeeds, StatusCode = Accepted 
                var responseStatusCode = response.StatusCode.ToString();
            }
        }
    }

}

 

Thanks for the reply @Eric_Zhang!

Actually, the problem was in the DisplayName variable, which had spaces. Solved that by removing these spaces, but don't know if there's another workaround.

 

I've worked hard to make this work in PHP, but happened to be some little details in the syntax of the HTTP request. I'm sharing my solution below to successfuly import a PBIX file to your workspace:

 

 

/**
 * Imports specified PBIX file to workspace collection
 *
 * @param string $file_path
 * @param string $file_name
 * @param string $display_name
 * @return void
 */

function importPBIX($file_path, $file_name, $display_name) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, "https://api.powerbi.com/v1.0/collections/".COLLECTION_NAME.
            "/workspaces/".WORKSPACE_ID."/imports?datasetDisplayName=$display_name");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    curl_setopt($ch, CURLOPT_POST, TRUE);
    $boundary = "BOUNDARY";
    $postdata = "--".$boundary . "\r\n";
    $postdata .= "Content-Disposition: form-data; name=\"" . $file_name . "\"; filename=\"" . $file_name . "\"\r\n";
    $postdata .= "Content-Type: application/octet-stream\r\n\r\n";
    $postdata .= file_get_contents($file_path);
    $postdata .= "\r\n";
    $postdata .= "--".$boundary . "--\r\n";

    curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);

    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Content-Type: multipart/form-data; boundary=\"$boundary\"",
        "Authorization: AppKey " . APP_KEY
    )); 
    curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );

    $response = curl_exec($ch);
    curl_close($ch);

    // Retorna o id do relatório importado
    $responseJson = json_decode($response, TRUE);
    $repoId = $responseJson['id'];

    // Retorna dados do relatório   
    return $repoId;
}

Pay attention to the constants COLLECTION_NAME, WORKSPACE_ID AND APP_KEY that must be defined previously in this code.

Thanks!

 

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

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

Top Kudoed Authors