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 am trying to import a PBIX file using postman, but all I get is a 400 with empty message. I have tried many ways, form-data, json, binary, so I must be missing something. Anyone able to do this in postman?
Solved! Go to Solution.
I was able to get Fiddler to work and used that to fix my Java version. I've included the script below (thanks to Zhang)
import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.HttpClientBuilder; public class ImportPBIXUtil { public static void main( String[] args ) { try { Import(); } catch ( UnsupportedOperationException e ) { // TODO Auto-generated catch block e.printStackTrace(); } catch ( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void Import() throws UnsupportedOperationException, IOException { String bearer = "Bearer {token}"; String fileName = "myReport.pbix"; String filePath = "C:\\Users\\JohnDoe\\Documents\\PowerBI\\" + fileName; String groupId = "{group_id}"; HttpClient request = HttpClientBuilder.create().build(); HttpPost post = new HttpPost( "https://api.powerbi.com/v1.0/myorg/groups/" + groupId + "/imports?datasetDisplayName=MyNewReport" ); long time = (new Date()).getTime(); String boundary = "---------------------------" + time; post.setHeader( "ContentType", "multipart/form-data; boundary=" + boundary ); post.setHeader( "Authorization", bearer ); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setBoundary( boundary ); builder.addBinaryBody( "filename", new File( filePath ), ContentType.APPLICATION_OCTET_STREAM, fileName ); HttpEntity multipart = builder.build(); post.setEntity( multipart ); HttpResponse response = null; System.out.println( "Request: " ); for (Header header : post.getAllHeaders()) { System.out.println( header.getName() + " : " + header.getValue() ); } System.out.println( post.getEntity().getContentLength() ); /*/ BufferedReader reqd = new BufferedReader( new InputStreamReader( post.getEntity().getContent() ) ); StringBuffer bbody = new StringBuffer(); String l = ""; while ( (l = reqd.readLine()) != null ) { bbody.append( l ); } System.out.println( bbody.toString() ); /*/ System.out.println( "Response: " ); try { response = request.execute( post ); } catch ( ClientProtocolException e ) { // TODO Auto-generated catch block e.printStackTrace(); } catch ( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } BufferedReader rd = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) ); StringBuffer result = new StringBuffer(); String line = ""; while ( (line = rd.readLine()) != null ) { result.append( line ); } System.out.println( response.getStatusLine().getStatusCode() ); System.out.println( result.toString() ); return; } }
It can also be done in Postman, Add your Authorization header and Content-type multipart/form-data header. Go to Body change to form-data go to the Key field a dropdown is then shown, change it from text to File and as a value select the PBIX file then you are all set to upload it using Postman for more info see https://upload.io/blog/postman-upload-file-cheat-sheet/
@dgdragon wrote:
I am trying to import a PBIX file using postman, but all I get is a 400 with empty message. I have tried many ways, form-data, json, binary, so I must be missing something. Anyone able to do this in postman?
I love Postman, however Postman seems not supporting the Content-Type: application / octet, see this link.
I usually use below code to import pbix file, just for your reference.
using System; using System.Net; //Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Version 2.21.301221612 using Microsoft.IdentityModel.Clients.ActiveDirectory; using System.IO; namespace ConsoleApplication39 { class Program { //Step 1 - Replace {client id} with your client app ID. //To learn how to get a client app ID, see Register a client app (https://msdn.microsoft.com/en-US/library/dn877542.aspx#clientID) private static string clientID = "49dxxxxxxxxx770d1a4"; //RedirectUri you used when you registered your app. //For a client app, a redirect uri gives AAD more details on the specific application that it will authenticate. private static string redirectUri = "https://login.live.com/oauth20_desktop.srf"; //Resource Uri for Power BI API private static string resourceUri = "https://analysis.windows.net/powerbi/api"; //OAuth2 authority Uri private static string authority = "https://login.windows.net/common/oauth2/authorize"; private static AuthenticationContext authContext = null; private static string token = String.Empty; //Uri for Power BI datasets private static string datasetsUri = "https://api.powerbi.com/v1.0/myorg"; // private static string datasetsBetaUri = "https://api.powerbi.com/beta/myorg"; //Example dataset name and group name private static string groupId = "dc581xxxxxxxxxxb6c15"; static void Main(string[] args) { //Import sample string pbixPath = @"C:\test\test.pbix"; string datasetDisplayName = "IamDataSetName"; string importResponse = Import(string.Format("{0}/groups/{1}/imports?datasetDisplayName={2}", datasetsUri, groupId, datasetDisplayName), pbixPath); Console.WriteLine(importResponse); } public static string Import(string url, string fileName) { string responseStatusCode = string.Empty; string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.ContentType = "multipart/form-data; boundary=" + boundary; request.Method = "POST"; request.KeepAlive = true; request.Headers.Add("Authorization", String.Format("Bearer {0}", AccessToken())); using (Stream rs = request.GetRequestStream()) { rs.Write(boundarybytes, 0, boundarybytes.Length); string headerTemplate = "Content-Disposition: form-data; filename=\"{0}\"\r\nContent-Type: application / octet - stream\r\n\r\n"; string header = string.Format(headerTemplate, fileName); byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); rs.Write(headerbytes, 0, headerbytes.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); } using (HttpWebResponse response = request.GetResponse() as System.Net.HttpWebResponse) { responseStatusCode = response.StatusCode.ToString(); } return responseStatusCode; } static string AccessToken() { if (token == String.Empty) { //Get Azure access token // Create an instance of TokenCache to cache the access token TokenCache TC = new TokenCache(); // Create an instance of AuthenticationContext to acquire an Azure access token authContext = new AuthenticationContext(authority, TC); // Call AcquireToken to get an Azure token from Azure Active Directory token issuance endpoint token = authContext.AcquireToken(resourceUri, clientID, new Uri(redirectUri), PromptBehavior.RefreshSession).AccessToken; } else { // Get the token in the cache token = authContext.AcquireTokenSilent(resourceUri, clientID).AccessToken; } return token; } } }
I was able to get Fiddler to work and used that to fix my Java version. I've included the script below (thanks to Zhang)
import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.HttpClientBuilder; public class ImportPBIXUtil { public static void main( String[] args ) { try { Import(); } catch ( UnsupportedOperationException e ) { // TODO Auto-generated catch block e.printStackTrace(); } catch ( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void Import() throws UnsupportedOperationException, IOException { String bearer = "Bearer {token}"; String fileName = "myReport.pbix"; String filePath = "C:\\Users\\JohnDoe\\Documents\\PowerBI\\" + fileName; String groupId = "{group_id}"; HttpClient request = HttpClientBuilder.create().build(); HttpPost post = new HttpPost( "https://api.powerbi.com/v1.0/myorg/groups/" + groupId + "/imports?datasetDisplayName=MyNewReport" ); long time = (new Date()).getTime(); String boundary = "---------------------------" + time; post.setHeader( "ContentType", "multipart/form-data; boundary=" + boundary ); post.setHeader( "Authorization", bearer ); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setBoundary( boundary ); builder.addBinaryBody( "filename", new File( filePath ), ContentType.APPLICATION_OCTET_STREAM, fileName ); HttpEntity multipart = builder.build(); post.setEntity( multipart ); HttpResponse response = null; System.out.println( "Request: " ); for (Header header : post.getAllHeaders()) { System.out.println( header.getName() + " : " + header.getValue() ); } System.out.println( post.getEntity().getContentLength() ); /*/ BufferedReader reqd = new BufferedReader( new InputStreamReader( post.getEntity().getContent() ) ); StringBuffer bbody = new StringBuffer(); String l = ""; while ( (l = reqd.readLine()) != null ) { bbody.append( l ); } System.out.println( bbody.toString() ); /*/ System.out.println( "Response: " ); try { response = request.execute( post ); } catch ( ClientProtocolException e ) { // TODO Auto-generated catch block e.printStackTrace(); } catch ( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } BufferedReader rd = new BufferedReader( new InputStreamReader( response.getEntity().getContent() ) ); StringBuffer result = new StringBuffer(); String line = ""; while ( (line = rd.readLine()) != null ) { result.append( line ); } System.out.println( response.getStatusLine().getStatusCode() ); System.out.println( result.toString() ); return; } }
I tried using the code (just hard coded the bearer token) but it just exits with "Unhandled Exception: System.Net.WebException: The remote server returned an error: (400) Bad Request."
Additionally I've tried Fiddler and followed this tutorial https://powerbi.microsoft.com/en-us/blog/upload-a-local-pbix-file-using-the-import-api/ with the same result.
I also constructed a java version using MultipartEntityBuilder, which also has the same result.
So far I've recieved only 400's with a body of {"Message":""}, an HTML page that says the request contained invalid headers (does not say what headers), or {"error":{"code":"PowerBIModelNotFoundException","pbi.error":{"code":"PowerBIModelNotFoundException","parameters":{},"details":[]}}}
UPDATE:
I did manage to get a 202 and an ID using Fiddler, but it doesnt actually do anything. It does not show up in PowerBI or using the get /imports route.
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 |
---|---|
100 | |
54 | |
21 | |
12 | |
11 |