Как сделать много вызовов API и загрузить их в postgres одновременно? - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть скрипт, который вызывает API (используя запросы), чтобы получить финансовые данные для списка акций.Он считывает данные в pandas dataframes, выполняет преобразование, а затем загружает извлеченные данные в postgres с помощью psycopg2.Для каждого тикера необходимо сделать 10-150 вызовов API.Каждая итерация занимает несколько секунд.

Принимая во внимание, что список тикеров имеет длину более 2 КБ, выполнение этого сценария занимает около одного дня, в то время как процессор используется только на 4% мощности.Я хочу изменить сценарий так, чтобы он использовал AIOHTTP (https://aiohttp.readthedocs.io/en/stable/client_quickstart.html) для создания всех API, необходимых для каждого тикера в один момент времени.Затем, когда возвращается каждый запрос, он может быть преобразован и загружен в Postgres.Я надеюсь, что это значительно сократит время, необходимое для обработки каждого тикера, за счет увеличения объема работы процессора.

Я посмотрел документацию для aiohttp и async-await, но мне трудно обдумать, как структурировать асинхронный цикл.Я также не уверен, как сделать так, чтобы при каждом возврате API-запроса он немедленно запускал загрузку pandas / postgres, а не ожидал возврата всех вызовов API, прежде чем двигаться дальше.

#here is a simplified example of the code for one ticker
import asyncio
import json
import pandas as pd
import psycopg2 as pg
import Requests as rq


tkr = foo
api_key = 'bar'
url = http://api_call_website.com?{0}&{1}&{2}&{3}&api-key:{4}
list_of_stmnts = 
[(True, 2009, 'Q4', 'pl'),
 (True, 2018, 'Q3', 'cf'),
 (True, 2018, 'Q2', 'cf'),
 (True, 2017, 'Q4', 'cf')]

#these "statements" contain the parameters that get passed into the url

async def async_get_loop(list_of_stmnts, tkr, url, api_key):
    urls = [url.format(tkr, stmt[1],stmt[2],stmt[3], api_key) for stmt in list_of_stmnts]
    #this builds the list of urls that need to be called
    await data = rq.request("GET", url)
    results = data.json()
    df = pd.DataFrame(results['values'])
    df.to_sql('table_name', engine, schema='schema', if_exists='append', index = False)
    #the postgres engine is defined earlier in the code using psycopg2
    return

Это показывает мое простое понимание того, как асинхронное ожидание должно работать.Я знаю, что для того, чтобы сделать это асинхронным, мне нужно реализовать aiohttp вместо запросов.Но, честно говоря, я заблудился относительно того, как я использую эти два пакета.

...