Цикл API, который вставляет параметр страницы - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь работать с документацией API для приложения.

Чтобы позвонить, я использую код:

curl -X GET \
  'https://api.program.com/v1/notes?page=1&pageSize=1000&sort=desc' \
  -H 'Authorization: Bearer xxx123xxx456xxx789xxx0001' \
  -H 'cache-control: no-cache'

Токен здесь заменен по понятным причинам.Но то, что я действительно пытаюсь настроить, включает параметр page=1.

Мой вопрос состоит из двух частей:

  1. Как мне написать команду, которая будет захватывать все страницы в текущей структуре команды?Таким образом, в основном, после page=1 он будет запускаться page=2, page=3, ...
  2. Как я могу сделать это таким образом, который также определяет, когда больше не осталось страниц, и, таким образом,знает, когда закончить работу?

Моя текущая настройка выглядит так, но она дает мне то, что мне нужно (я не очень хорошо знаю), плюс я не знаю, как выйти из цикла:

for ((i=1;i<=5;i++)); do
  curl -X GET \
  'https://api.program.com/v1/notes?page=1&pageSize=1000&sort=desc' \
  -H 'Authorization: Bearer xxx123xxx456xxx789xxx0001' \
  -H 'cache-control: no-cache'
done

Результат, когда больше не осталось записей, выглядит следующим образом:

{
    "meta": {
        "pageSize": 1000,
        "page": 65
    },
    "links": {
        "self": "/v1/conversations?page=65&pageSize=1000&sort=desc",
        "first": "/v1/conversations?page=1&pageSize=1000&sort=desc",
        "prev": "/v1/conversations?page=64&pageSize=1000&sort=desc",
        "next": null
    },
    "data": []
}

То, что я запускаю согласно ответу Чарльза Даффи - сохраняется как test_run.sh:

getPage () {
  curl -X GET 'https://api.test.com/v1/test?page="$1"&pageSize=1000&sort=desc' \
    -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9Cim97g123NXpMkS_Jc9xggCYlMQVvKsAeBCw' \
    -H 'cache-control: no-cache'
}

Но это возвращает ошибку:

MacBook-Pro-8:~ admin$ ./test_run.sh
-bash: ./json_blob.sh: Permission denied

Тем не менее, когда я запускаю, просто запускаю следующее прямо в командной строке, он возвращает результаты в порядке:

curl -X GET 'https://api.test.com/v1/test?page="$1"&pageSize=1000&sort=desc' \
        -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9Cim97g123NXpMkS_Jc9xggCYlMQVvKsAeBCw' \
        -H 'cache-control: no-cache' > test_run.json

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

На практике я, вероятно, написал бы это более похоже на следующее:

#!/usr/bin/env bash
case $BASH_VERSION in ''|[12].*) echo "Bash 3.0+ required" >&2; exit 1;; esac

# Given a page number, return text of that page.
# Note that we switch from single to double quotes before expanding $1
getPage() {
  curl --fail -X GET 'https://api.program.com/v1/notes?page='"$1"'&pageSize=1000&sort=desc' \
    -H 'Authorization: Bearer xxx123xxx456xxx789xxx0001' \
    -H 'cache-control: no-cache'
}

# return a stream with *all* page text, from page 1 until
# the first one with no .link.next.
getAllPages() {
  local page i=1
  while page=$(getPage "$i"); do
    printf '%s\n' "$page"
    if [[ $(jq '.links.next' <<<"$page") = null ]]; then
      break
    fi
    (( ++i ))
  done
}

getAllPages \
  | jq -c '.data[] | .attributes | {text: .preview, from: .meta.from}' \
  > data_json_blob.jsonl

Выходной файл называется здесь .jsonl, потому что он в формате JSONLines, а не в стандартном JSON.(Вы не можете поместить несколько объектов в один файл JSON, не помещая их в список или другой контейнер, и он должен быть действительным; таким образом, когда вы передаете 1: 1 jq преобразования более чем одного объекта на входе, вы обычнополучить JSONL, а не JSON, как вывод).

0 голосов
/ 20 февраля 2019

Для каждой итерации вам нужно проверить, есть ли "next" : null, если найдено, разорвать цикл.

while : ; do
  if [[ $(curl -X GET 'https://api.program.com/v1/notes?page=1&pageSize=1000&sort=desc' \
  -H 'Authorization: Bearer xxx123xxx456xxx789xxx0001' \
  -H 'cache-control: no-cache' | jq '.link.next') == 'null' ]] ; then
  break #Exit the loop
  fi 
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...