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
Anonymous
Not applicable

how to fully load data from limited HTTP API?

I need to load all data from the API, but the server returns a maximum of 100 rows.

at the link below, if I change the limit=100 to a bigger number, it returns with 100.

to get more data, I need to change offset=0 to another part, for instance offset=100, offset=200 and so on.

 

https://<testserver>.com/<token>?limit=100&offset=0&date_range=201701010000:201712310000

 

I did manage to use parameters under WEB load, advanced options, but it loads only one set of 100 rows, and I need to import ALL rows from this link.

the code below works, but does not returns full table, and I need full table.

 

=Json.Document(Web.Contents("https://<testserver>.com/<token>?limit=100&offset=" & offsettt & "&date_range=201001010000:201912310000"))

in this code, offsettt is the list I made with possible values for offset, but it returns only 100 rows at max.


today, maximum possible offset is around 3000, but everyday this database keeps growing.

 

how do I loop this loading process, to get all possible rows in one query?

12 REPLIES 12
Anonymous
Not applicable

what I need is something similar to this topic:
https://community.powerbi.com/t5/Desktop/how-to-create-a-query-that-paginates/td-p/20047/page/2
but somehow I still could not find a solution for me.
my server API returns this:
offset=actual starting value, if not set it returns 0, to start at row 0;
limit=maximum is 100;

next_offset=show the start of the next offset. if I start offset=300, limit=100, but there are only 7 more rows to load, next_offset will be 307. if there are thousands more, next_offset will always be offset+limit, in this example 300+100=400.

from_cache=TRUE if there is more data, FALSE if no more data to show. but I think I can use only the next_offset value in this loading procedure.

 

See if you can adapt this for your scenario:

 

https://www.linkedin.com/pulse/loading-data-paged-related-from-ms-graph-api-power-bi-rob-reilly

 

Otherwise, you will have to create some kind of logic within your query to use the offset+limit only if the count of results is a multiple of 100.  That way, if the result count is 307, it will know that there are no more results.  Additionally, if there are exactly 300 (or other multiple of 100) results, then offset+limit wont work, so you will have to incorporate some error handling.

Anonymous
Not applicable

hi dkay84.

I read the link twice, tested both scripts in it, but they simply does not work.

A simple copy+paste shows error on the second line: missing Eof "GetUserDetail = (Path)=>".

what does that means?

I am new to M language and I cannot find the error on the script.

Anonymous
Not applicable

please, I still need help.
I tried to modify the script from another post, but then Power BI freezes for a second and then returns and error.

error: An error occured when deserializing the results. try to repeat the operation.


below is the full script that I would like someone to review and correct.

in bold, commands that I don´t understand, but I am using anyway because I just adapted from another post, and I think this is the way to get my solution.

 

let

Source = Json.Document(Web.Contents("https://url.com/token?limit=100&offset=0&date_range=201001010000:201912310000")),

Pagination = List.Skip(List.Generate( () => [offsett = "0"], // Start Value
each Source[offset] <> Source[next_offset], // Condition under which the next execution will happen
each [ WebCall = "https://url.com/token?limit=100&offset="&[offsett]&"date_range=201001010000:201912310000", // retrieve results per call
offsett = if WebCall[next_offset] >= WebCall[offset] then WebCall[next_offset] else WebCall[next_offset] ],// determine the offset for the next execution
each [Value]),1) // Select just the Record of the last step from your query
in
Pagination

 

I tried to wrap the webcall under Json.Document(Web.Contents()), but this also doesn´t work.


for information, the first line (Source) returns this, which is ok.

i need to use and compare the values from offset and next_offset.

the from_cache value is not good for this script, because it returns false or true even if I still have more data to read.

Untitled.png

Anonymous
Not applicable

I tried to improve the last code as it follows below.

in bold, thing that i changed.

now i got a different erro: The type of the current preview value is too complex to display

 

but before the error occurs, i can see at the bottom right corner of the power bi, an increasing number of rows that goes a bit above 300 rows and then it crashes.

 

let
Source = Json.Document(Web.Contents("https://url.com/token?limit=100&offset=0&date_range=201001010000:201912310000")),

Pagination = List.Skip(List.Generate( () => [offsett = "0"], // Start Value
each Source[offset] <= Source[next_offset], // Condition under which the next execution will happen
each [ WebCall = "https://url.com/token?limit=100&offset=" & [offsett] & "&date_range=201001010000:201912310000", // retrieve results per call
offsett = WebCall[next_offset]  ],// determine the offset for the next execution
each [posts]),1) // Select just the Record of the last step from your query
in
Pagination


@Anonymous wrote:

I tried to modify the script from another post, but then Power BI freezes for a second and then returns and error.

error: An error occured when deserializing the results. try to repeat the operation.

 


 

Do you know what the format is of the results (XML, JSON, etc)?  Is your token something that you can change so that you can share it and the API url with us?  Or can you point to another API that is public that has a similar structure of returned results?

Anonymous
Not applicable

I believe the results are in JSON, because this is how Power BI automatically detects a simple load.

sorry, i cannot control nor manage the token, and therefore cannot share it here.

i dont know any other public API with a similar structure/list. i checked some another APIs from another posts´examples but none of them seems to use the same parameters or logic.

Anonymous
Not applicable

I managed to load 100% of the limited query, but the script if far from perfect.
I am still looking for a script that checks if offset < next_offset and then stops.

 

the aproach I used so far is: I created a list of offset values, and the script loads all data parts.
if I set a low number for the offset possibilities, the script will miss the last values.
if I set a high number, the script will return a lot of empty rows after the full load is finished.

 

the script below loads all rows until the end at row 4323.
but it continues to load more lines until the 4400 limit that I set (inicial source list goes from 0 to 4400).

for example, at this row 4323, this is when the offset and next_offset are the same and the script must stop, but i could not work on a script using this logic.

 

let

Source = Json.Document(Web.Contents("https://url.com/token?limit=100&offset=0&date_range=201001010000:201912310000")),
Source1 = {0..45}, //list of total pages in my full dataset
#"Converted to Table" = Table.FromList(Source1, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Added Custom" = Table.AddColumn(#"Converted to Table", "Personalizar", each [Column1]*100), //times 100 because my offset is at every 100 rows
#"Columns Renamed" = Table.RenameColumns(#"Added Custom",{{"Personalizar", "Column2"}}),
#"Added Custom" = Table.AddColumn(#"Columns Renamed", "Custom", each Json.Document(Web.Contents("https://url.com/token?limit=100&offset=" & Text.From([Column2]) & "&date_range=201001010000:201912310000")))
in
#"Added Custom"

Anonymous
Not applicable

I can work with this script for a short period of time, as it is not future proof.

But now I found another problem and I need a workaround:

I cannot refresh data online (also scheduled refresh) because of the limitation of the PBI Service.
I am using a function inside the URL and this is not allow for PBI Service.

In bold, the forbidden function inside URL:

each Json.Document(Web.Contents("https://url.com/token?limit=100&offset=" & Text.From([Column2]) & "&date_range=201001010000:201912310000")))

Can anyone please help me with another way to load all pages from API and solve this issue?

Unfortunately this is a current limitation of the service.  I believe the PG is actively working on or discussing enabling this type of query to be refreshable but AFAIK there is no workaround.

For anyone who comes across this in future, the LinkedIn link above contains a sample script to recursively access Microsoft Graph API. However cut and pasting the code will not work as there are a number of errors - which are described in the comments at the bottom. The corrected code can be found here:

 

// ##############   BEGIN QUERY ############################
let
       // Define a Function Called GetUserDetail that takes a single parameter Path
       // that is the MS Graph API Endpoint

GetUserDetail = (Path)=>

let
       // call out to the web endpoint and convert the result to a JSON
       // Document object which is saved in the Source variable

    Source = Json.Document(Web.Contents(Path)),

      // Assign the resultant List object to NextList variable

NextList= @Source[value],

    // recursively call GetUSerDetail function using the value of the
    // @odata.nextLink as the path
    // Since @odata.nextLink is not guaranteed to always exist in the case where
    // the result is less than 100 we need to catch this and deal with it
    // using a try otherwise basically means if you error out because no
    // @odata.nextLink exisit then just return the resulting list of values you did get

result = try @NextList & @GetUserDetail(Source[#"@odata.nextLink"]) otherwise @NextList

in

    // Return the result variable as the function return

result,
               // Use the function GetUserDetail with the initial path to the object.
              // The function will run recursively until it gets all the record and then
              // loads the full result to UserDetail Variable  
               UserDetail = GetUserDetail("https://graph.microsoft.com/beta/users?$expand=manager")
in
UserDetail
// ##################### END QUERY #######################

Can't get this to work on power bi service. Anyone else tried it?

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.