Invoke-WebRequest Canvas LMS API 分页

Fra*_*sso 3 powershell pagination canvas-lms

我似乎找不到有关此主题的任何示例,我想知道如何做到这一点。任何人都可以向我展示一个示例或向我指出如何使用 Invoke web-request 在 powershell 中进行分页的链接吗?我面临的挑战是我对服务器进行 API 调用,但一次只返回 100 行。为了获得更多行,我必须对服务器进行第二次调用。我不知道该怎么做。如果有帮助,这里是 Canvas LMS 提供的链接和我迄今为止拥有的代码。

分页

分页

默认情况下,返回多个项目的请求将分页到 10 个项目。您可以使用 ?per_page 参数设置自定义每页金额。对于可以将 per_page 设置为多大,有一个未指定的限制,因此请务必检查链接标头。

要检索其他页面,应使用返回的链接标头。这些链接应被视为不透明。它们将是绝对 URL,其中包含检索所需的当前页、下一页、上一页、第一页或最后一页所需的所有参数。一个例外是,如果发送 access_token 参数进行身份验证,则该参数不会包含在返回的链接中,并且必须重新附加。

分页信息在链接标头中提供:

Link:
<https://<canvas>/api/v1/courses/:id/discussion_topics.json?opaqueA>; rel="current",
<https://<canvas>/api/v1/courses/:id/discussion_topics.json?opaqueB>;> rel="next",
<https://<canvas>/api/v1/courses/:id/discussion_topics.json?opaqueC>;> rel="first",
<https://<canvas>/api/v1/courses/:id/discussion_topics.json?opaqueD>;> rel="last" 
Run Code Online (Sandbox Code Playgroud)

可能的相对值是:

当前 - 链接到当前结果页面。下一页 - 链接到下一页结果。上一页 - 链接到上一页结果。第一 - 链接到结果的第一页。最后 - 链接到结果的最后一页。仅当它们相关时才会包含这些内容。例如,结果的第一页将不包含 rel="prev" 链接。如果每个请求的总计数太昂贵而无法计算,则也可以排除 rel="last"。

初期产品

$curlly=""
$url_main="https://[instance].instructure.com/api/v1/accounts/1/courses?per_page=1"
$security_token="imhungry"
$header = @{"Authorization"="Bearer "+ $security_token; "rel"="last"}
$curlly=Invoke-WebRequest -Headers $header   -Method Get   -Uri $url_main   
$curlly = ConvertFrom-Json $curlly.Content
foreach($course in $curlly)
{
    $course.name
}
$curlly.Count
Run Code Online (Sandbox Code Playgroud)

最终产品

 ##This is an example on how to use pagination in powershell
$url_main="https://[instance].instructure.com/api/v1/accounts/1/courses?per_page=100"
$security_token="boyimhungry"
$header = @{"Authorization"="Bearer "+ $security_token}
$purlly=Invoke-WebRequest -Headers $header   -Method Get   -Uri $url_main   
$curlly = ConvertFrom-Json $purlly.Content
$url_main = $purlly.Headers.Link.Split(",")[1].Replace("<","").Replace(">","") ## you can get away with just doing one replace("<","") but it looks neater this way
while( !$url_main.Contains("prev"))
{
$purlly=Invoke-WebRequest -Headers $header   -Method Get   -Uri $url_main   
$curlly += ConvertFrom-Json $purlly.Content
$url_main = $purlly.Headers.Link.Split(",")[1].Replace("<","").Replace(">","")
cls
$curlly.Count
$url_main
}
foreach($course in $curlly)
{
    $course.name
}
$curlly.Count
Run Code Online (Sandbox Code Playgroud)

小智 5

我知道您已经接受了答案,但我想我应该给出我的代码示例,以防万一有人需要。此示例获取所有 Canvas 用户的列表。这并不是一个糟糕的过程——大部分工作只需一个 4 行 do..while 循环即可完成。

$token = "YOUR_ACCESS_TOKEN"
$headers = @{"Authorization"="Bearer "+$token}
$allCanvasUsers = New-Object System.Collections.ArrayList @()
$pageNumber = 1

Function RequestPageOfUsers($page) {
    $script:resultsPage = Invoke-WebRequest -Method GET -Headers $headers -Uri "https://$domain/api/v1/accounts/self/users?per_page=100&search_term=P00&page=$page"
    $usersPage = ConvertFrom-Json $resultsPage.Content

    foreach ($user in $usersPage) {
        $script:allCanvasUsers.Add($user)
    }
}

do {
    RequestPageOfUsers $pageNumber
    $pageNumber++
} while ($resultsPage.Headers.Link.Contains('rel="next"'))
Run Code Online (Sandbox Code Playgroud)