Forum Discussion
Rest API _ Json _ several pages _ automatically call the next_page_URL
Hi Everyone,
I am a newbie on powerBi and would need your help to figure out how to automate a rest-API call with a Json response having several pages.
The initial URL is the following:
https://api.higring.com/v2/reporting/get?period=custom_date&start_date=2017-01-01&end_date=2017-07-20&data_type=adnetwork &group_by=date,platform,custom_1,custom_2, type,ad_format,connection,country&filter[]=network:network1
I get the following response:
The idea would be to automatically call the “next_page_url” until there is no “next_page_url”.
Any thoughts on how I can process this ?
Thanks a lot
This video will show you: https://www.youtube.com/watch?v=vhr4w5G8bRA&t=6s
Hi ImkeF,
Thanks a lot for your reply. It helps a lot.
I generate a script that do pretty much the same than the video.
It looks like this:let Source = Json.Document(Web.Contents(url, [Headers=[Authorization="your token"]])), iterations = Source[total_pages], // get the information within the response url = "you URL", // here goes your URL FnGetOnePage = (url) as record => let Source = Json.Document(Web.Contents(url, [Headers=[Authorization="yourtoken"]])), data = try Source[connections] otherwise null, //get the data of the first page next = try Source[next_page_url] otherwise null, // the script ask if there is another page res = [Data=data, Next=next] in res, GeneratedList = List.Generate( ()=>[i=0, res = FnGetOnePage(url)], each [i]<iterations and [res][Data]<>null, each [i=[i]+1, res = FnGetOnePage([res][Next])], each [res][Data]), #"Converti en table" = Table.FromList(GeneratedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error) in #"Converti en table"It works perfectly.
Have a good day,Paul
47 Replies
- ImkeF
Community Champion
This video will show you: https://www.youtube.com/watch?v=vhr4w5G8bRA&t=6s
- PaullFrequent Visitor
Hi ImkeF,
Thanks a lot for your reply. It helps a lot.
I generate a script that do pretty much the same than the video.
It looks like this:let Source = Json.Document(Web.Contents(url, [Headers=[Authorization="your token"]])), iterations = Source[total_pages], // get the information within the response url = "you URL", // here goes your URL FnGetOnePage = (url) as record => let Source = Json.Document(Web.Contents(url, [Headers=[Authorization="yourtoken"]])), data = try Source[connections] otherwise null, //get the data of the first page next = try Source[next_page_url] otherwise null, // the script ask if there is another page res = [Data=data, Next=next] in res, GeneratedList = List.Generate( ()=>[i=0, res = FnGetOnePage(url)], each [i]<iterations and [res][Data]<>null, each [i=[i]+1, res = FnGetOnePage([res][Next])], each [res][Data]), #"Converti en table" = Table.FromList(GeneratedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error) in #"Converti en table"It works perfectly.
Have a good day,Paul
- markholland
Helper I
Hi,
I'm having real difficulties following the steps in this post with my API. I've watched the video, which differs from the code given at the bottom of this post. Neither approach has worked for me. I'll go through what I've done and hopefully someone can help me:
Following the video I've added the following code:
GetData
(page as number) as table => let Source = Json.Document(Web.Contents("https://api.harvestapp.com/v2/time_entries?access_token=********&account_id=********&page=" & Number.ToText(page))), Data1 = Source{1}[Data], RemoveBottom = Table.RemoveLastN(Data1,3) in RemoveBottomI've then copied the code to create the list of pages:
let Source = List.Generate( () => [Result = try GetData(1) otherwise null, Page = 1], each [Result] <> null, each [Result = try GetData([Page]+1) otherwise null, Page = [Page]+1], each [Result]) in SourceBut when I do this I get nothing, just a column header with List but no list of pages.
When I try the amended version in this post I get nothing either. Here's the code I'm using:
let Source = Json.Document(Web.Contents(url, [Headers=[Authorization="********"]])), iterations = Source[total_pages], // get the information within the response url = "https://api.harvestapp.com/v2/time_entries?access_token=********&account_id=********", // here goes your URL FnGetOnePage = (url) as record => let Source = Json.Document(Web.Contents(url, [Headers=[Authorization="********"]])), data = try Source[connections] otherwise null, //get the data of the first page next = try Source[next_page_url] otherwise null, // the script ask if there is another page res = [Data=data, Next=next] in res, GeneratedList = List.Generate( ()=>[i=0, res = FnGetOnePage(url)], each [i]<iterations and [res][Data]<>null, each [i=[i]+1, res = FnGetOnePage([res][Next])], each [res][Data]), #"Converted to Table" = Table.FromList(GeneratedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error) in #"Converted to Table"I really have no idea where I'm going wrong. Can anyone help? Paull ImkeF
Thanks,
Mark
- TerriblyVexedFrequent Visitor
Thank you all so much for this!!!
One point of clarification - The GeneratedList had a typo in it about half way through the discussion.
each [res][Next] <> nullas the evaluator function should be
each [res][Data] <> nullit was this way in several posts and then got switched.
I would like to share my version for anyone struggling with Fhir data.
let baseUrl = "https://{myurl}.azurewebsites.net", resource = "/Questionnaire", search = "?&_total=accurate", fullUrl = baseUrl & resource & search, // define the function FnGetOnePage = (url) as record => let Source = Json.Document(Web.Contents(url)), data = try Source[entry] otherwise null, // link is list of records link = try Source[link] otherwise null, // link{0} could be "self", "next" next = if link{0}[relation] = "next" then link{0}[url] else null, res = [Data=data, Next=next] in res, // use the FnGetOnePage function with List.Generate GeneratedList = List.Generate( ()=> [result = FnGetOnePage(fullUrl)], // do while each [result][Data] <> null, // each row of list each [result = FnGetOnePage([result][Next])], // output each [result][Data] ), // convert to table from the output of function GeneratedList #"Converted to Table" = Table.FromList(GeneratedList, Splitter.SplitByNothing(), null, null, ExtraValues.Error), #"Expand Table" = funcExpand(GeneratedList) in #"Expand Table"This uses not only the functions listed here but also the funcExpand function which auto expands all columns that have data.
ImkeF - thank you!
Vexed
- FPackermanGTA
Advocate I
OK I have a similar issue trying to get this to work.
I have an api which will only return 200 records but rather than the next url it gives me the lastid which I think I can tag onto the url to then give me the next page of results. So the simple code below return one page of data and not sure what the best way would be to go about doing this.
let apiUrl = "myUrl", options = [Headers =[ #"Accept"="application/json", #"Authorization"="myKey"]], result = Web.Contents(apiUrl , options), #"Imported JSON" = Json.Document(result,65001) in #"Imported JSON"The url would then look like this to search the next set and so on. I think thats how it would work anyway.
https://myURL?after_id=1494The API says
Pass the last id received, to receive records after it. Null can be passed to start at the beginning.
Any help much appreiciated and I know this is an old thread but here goes.....
Cheers
Paul.
- TerriblyVexedFrequent Visitor
FPackermanGTA wrote:OK I have a similar issue trying to get this to work.
I have an api which will only return 200 records but rather than the next url it gives me the lastid which I think I can tag onto the url to then give me the next page of results. So the simple code below return one page of data and not sure what the best way would be to go about doing this.
let apiUrl = "myUrl", options = [Headers =[ #"Accept"="application/json", #"Authorization"="myKey"]], result = Web.Contents(apiUrl , options), #"Imported JSON" = Json.Document(result,65001) in #"Imported JSON"The url would then look like this to search the next set and so on. I think thats how it would work anyway.
https://myURL?after_id=1494The API says
Pass the last id received, to receive records after it. Null can be passed to start at the beginning.
Any help much appreiciated and I know this is an old thread but here goes.....
Cheers
Paul.
And does it?
- FPackermanGTA
Advocate I
Yes I just need a way to recursively enter the function with the previous 'last_id' appended to the base url until 'additional_pages' is False and then join it all together but struggling to do it. Any ideas?