автоматизация запросов к веб-интерфейсу (RestAPI) Python3

Есть необходимость выгружать JSON-файл с данными за определенный промежуток времени из веб-интерфейса через RestAPI. Лимит записей в полученном файле - 100. В самом файле информация о действиях и временем, когда это действие произошло. Если за запрашиваемый промежуток времени данных больше, чем на 100 записей, полученный ответ об этом сигнализирует - moreDataAvailable = True. Чтобы получить недостающие данные, необходимо сформировать новый request и в url прописать время последнего полученного события (receivedDateTime) вместо starttime и прибавить к нему 1 милисекунду.

На Python'е удалось сделать запрос к Веб-интерфейсу через requests.get()

 >>> import requests
>>> response = requests.get(
...     'https://api.blablabla.com/event/eventstatuses?requestId=1234&datetype=received&starttime=2020-02-10T00%3A00%3A57.001Z&...'
... )
>>> json_response = response.json()
>>> print(json_response)

Как возможно автоматизировать запросы для выгрузки всех необходимых данных за запрашиваемый период? (moreDataAvailable = False) Можно ли полученные JSONы объединить в один?


Ответы (1 шт):

Автор решения: mrEvgenX

Если я правильно понял...

Зависит, конечно, откуда берется этот URL, откуда берутся параметры для него. Его же можно формировать из нескольких переменных.

Так как у меня нет доступа к интерфейсу, то я написал просто распечатывание URL, но оставил в комментариях, чем это заменить.

Возможно, функция isoformat() не подойдет, ну вдруг. Тогда пригодится strftime(). Другими словами, я сделал кучу разумных предположений о формате ответа и код придется приспособить под свою ситуацию. Своей задачей увидел только показать, как формировать URL динамически.

from datetime import datetime, timedelta
import requests


def form_url(request_id, datetype, starttime):
    url_pattern = 'https://api.blablabla.com/event/eventstatuses?requestId={}&datetype={}&starttime={}&...'  # дополняем тем, что есть по факту в параметрах
    return url_pattern.format(request_id, datetype, starttime.isoformat())


events = []  # здесь будет список событий
starttime = datetime(2020, 2, 10, 0, 0, 0)
moreDataAvailable = True
for i in range(5):  # меняем на: while moreDataAvailable:
    url = form_url('1234',  'received', starttime)
    print(url)  # меняем на: response = requests.get(url)
    # response_json = response.json()
    # обновляем условие остановки: moreDataAvailable = response_json['moreDataAvailable']
    # добавляем агрегацию ответов, если в ответе список, то так: events += response_json['events']
    starttime += timedelta(milliseconds=1)  # меняем на: starttime = response_json['events'][-1]['starttime'] + timedelta(milliseconds=1)

Вывод программы такой:

https://api.blablabla.com/event/eventstatuses?requestId=1234&datetype=received&starttime=2020-02-10T00:00:00&...
https://api.blablabla.com/event/eventstatuses?requestId=1234&datetype=received&starttime=2020-02-10T00:00:00.001000&...
https://api.blablabla.com/event/eventstatuses?requestId=1234&datetype=received&starttime=2020-02-10T00:00:00.002000&...
https://api.blablabla.com/event/eventstatuses?requestId=1234&datetype=received&starttime=2020-02-10T00:00:00.003000&...
https://api.blablabla.com/event/eventstatuses?requestId=1234&datetype=received&starttime=2020-02-10T00:00:00.004000&...

Т.е. мы много раз по одной миллисекунде прибавляем и получаем URL для запроса новой порции, а когда moreDataAvailable станет ложно - цикл остановится.

Ну и выскажусь по поводу архитектурного решения API. Критика заключается в способе постраничного доступа. Гораздо проще было бы заиметь параметры pageSize и pageNumber, но если это какое-то совершенно сторонне API и они решили, что их клиентам так комфортно, либо им так комфортно реализовать свою логику, ну чтож...

→ Ссылка