Forum Discussion
PowerQuery Post API call to return complete data from all pages.
Hi
Looping is done using List.Generate.
I recently answered some questions related to paging:
- https://community.powerbi.com/t5/Power-Query/how-to-iterate-the-data-of-several-sheets-of-a-web-page...
- and also you can have a look at https://learn.microsoft.com/en-us/power-query/helper-functions#tablegeneratebypage
If you cannot manage to fix it using the above links, please reply and I'll have a look at your code.
Also it will be important to know where is the next page token/number in the API response and how to request the next page.
Please mark this as answer if it helped.
i could see Authorization: Bearer , kvAccessToken is same for all the pages.
when i click on the next page --
{"query":"((end_time ge '2023-01-18T05:28:31Z' and start_time le '2023-02-17T05:28:31Z') and (file_type_name eq 'datalog'))","fields":[],"count":true,"start":100,"limit":100,"sort":{"fieldname":"end_time","order":"desc"}}
Next page ----
{"query":"((end_time ge '2023-01-18T05:30:02Z' and start_time le '2023-02-17T05:30:02Z') and (file_type_name eq 'datalog'))","fields":[],"count":true,"start":200,"limit":100,"sort":{"fieldname":"end_time","order":"desc"}}
seems "start" is the changed every time, then "limit":100 every time.
these days are same for all page, because i choose last 30 days in application...
end_time ge '2023-01-18T05:28:31Z' and start_time le '2023-02-17T05:28:31Z'
- hanuraolm3 years agoHelper I
Your help in sharing the code structure would be greatly appreciated.
- ams13 years agoResponsive Resident
Hi,
Should be something like below - it assumes that we don't know the number of available pages (do we know from the response how many pages are left?) and therefore will keep incrementing "start = start + limit" until we get an error.
Hopefully your server will raise an error if we request a start that doesn't exist, otherwise it won't stop requesting.
If below doesn't work, please get back here and we'll finish it.
Please mark this as answer if it helped.
let apiUrl = "http://...", bearerToken = getbearerToken(), getkvAccessToken = getkvAccessToken(), headers = [ #"Content-Type" = "application/json", #"Authorization" = "Bearer " & bearerToken, #"clientAppName" = "Voyager", #"clientFeatureName" = "Search", #"kvAccessToken" = getkvAccessToken, #"Ocp-Apim-Subscription-Key" = "ec424b08a1a14b7b97e2e9f6138767be" ], limit = 100, runNextRequest = (lastRequest) => let getResponse = (startRow) => let requestBodyRecord = [ query = "((end_time ge '2022-12-31T12:01:33Z' and start_time le '2023-01-30T12:01:33Z') and search.ismatch('/.*datalog.*/', 'file_type_name', 'full', 'any'))", fields = {}, count = true, start = startRow, limit = limit, sort = [ fieldname = "end_time", order = "desc" ] ], options = [ Content = Json.FromValue(requestBodyRecord), Headers = headers ], apiResponse = Json.Document(Web.Contents(apiUrl, options)) in apiResponse, start = if lastRequest = null then 0 else lastRequest[start] + limit, response = getResponse(start), hasError = (try response)[HasError] = true, currentRequest = // in the absence of anything in the response to tell us when to stop, // we will continue requesting as long as we don't get an error if hasError = false then [ response = response, start = start ] else null in currentRequest, allPages = List.Generate( // initial () => runNextRequest(null), // condition (requestResponse) => requestResponse <> null, //next (requestResponse) => runNextRequest(requestResponse), //selector // TODO: add [docs] at the end of the line below to extract just docs (requestResponse) => requestResponse[response] ) in allPages- hanuraolm3 years agoHelper I
Thanks for your Inputs, I tried the above code given, but it is loading very slowly record by record.
Tried with the below chat gpt code and getting repeated data(1st 100 records) until the completion of the loop, can somebody please help me to capture all data.
let
apiUrl = "https://sample url/username",
//startDateTime = DateTime.ToText(DateTime.LocalNow(), "yyyy-MM-ddThh:mm:ssZ"),
//endDateTime = DateTime.ToText( DateTime.LocalNow() - #duration(60, 0, 0, 0), "yyyy-MM-ddThh:mm:ssZ" ),
startDateTime = "2023-02-21T07:19:22Z",
endDateTime ="2023-01-22T07:19:22Z",
requestBody = "{""query"":""((((end_time ge '"
& endDateTime
& "' and start_time le '"
& startDateTime
& "')
options = [
Headers = [
#"Content-Type" = "application/json",
#"Authorization" = "Bearer " & bearerToken,
##"kvAccessToken" = getkvAccessToken(),
]
],
apiResponse = Web.Contents(apiUrl, options & [Content = Text.ToBinary(requestBody)]),
#"Imported JSON" = Json.Document(apiResponse, 1252),
docs = #"Imported JSON"[docs],
totalDocs = #"Imported JSON"[numFound],
allDocs = List.Generate(
() => [start = 0, accumulatedDocs = {}],
each [start] < totalDocs,
each [start = [start] + 100, accumulatedDocs = List.Combine({[accumulatedDocs], [docs]})],
each
let
optionsWithContent = Record.AddField(
options,
"Content",
Text.ToBinary(Text.Replace(requestBody, "#start#", Text.From([start])))
),
response = Web.Contents(apiUrl, optionsWithContent),
json = Json.Document(response, 1252)
in
[docs = json[docs]]
),
combinedDocs = List.Combine(List.Transform(allDocs, each _[docs])),
#"Converted to Table" = Table.FromList(combinedDocs, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"id", "start_time"}, {"id", "start_time"}),
#"Filtered Rows" = Table.SelectRows(#"Expanded Column1", each ([id] = "0055c4e0-027d-4883-b5cc-6ec9d4731fcf"))in
#"Filtered Rows"