Asyncio Возвращает будущее в ожидании результата - PullRequest
0 голосов
/ 25 сентября 2018

Я использую пакет IBSYNC для запроса данных у Interactive Broker.По сути, код вернет XML-файл.

Код выполняется, и я вижу, что XML был возвращен (напечатан на консоли брокера).Однако, когда я использую .result (), он возвращает Future pending.

Как вместо этого получить XML?

async def ReportsFinStatements(symbol, exchange, currency, primary):
    stock = Stock(symbol, exchange, currency, primaryExchange= primary)
    #ib.qualifyContractsAsync(stock)
    assert await ib.reqContractDetailsAsync(stock)
    data = ib.reqFundamentalDataAsync(contract=stock, reportType='ReportsFinStatements')
    return data

async def main():
    group1 = loop.create_task(ReportsFinStatements('PIH', 'SMART', 'USD', 'NASDAQ'))
    group2 = loop.create_task(ReportsFinStatements('PIH', 'SMART', 'USD', 'NASDAQ'))
    group3 = loop.create_task(ReportsFinStatements('PIH', 'SMART', 'USD', 'NASDAQ'))
    await asyncio.wait([group1, group2, group3])
    return group1, group2, group3

if __name__ == '__main__':
    try:
        loop = asyncio.get_event_loop()
        d1, d2, d3 = loop.run_until_complete(main())
    except Exception as e:
        print('logging')
    finally:
        loop.close()

d1 равно <Task finished coro=<ReportsFinStatements() done, defined at <ipython-input-4-4a5ceba20b3a>:1> result=<Future pending>>

1 Ответ

0 голосов
/ 25 сентября 2018

Есть две проблемы:

  • Вам необходимо await позвонить на reqFundamentalDataAsync.Вот почему вы получаете ожидающее будущее, это возвращаемое значение reqFundamentalDataAsync (когда не ожидается) и, следовательно, вашего ReportsFinStatements.

  • Вам необходимо использовать asyncio.gather() вместо asyncio.wait(), в этом случае вам не нужно будет вызывать result() для возвращаемых значений.(Как только предыдущий пункт будет реализован, вы могли бы использовать asyncio.wait(), как вы пытались, и вызывать result() для задач, но asyncio.gather() разработан так, что вам не нужно это делать.)

Наконец, вам не нужно явно использовать create_task, и asyncio.gather, и asyncio.wait для него автоматически при передаче объектов сопрограммы.Например, вы можете написать main так:

async def main():
    return await asyncio.gather(
        ReportsFinStatements('PIH', 'SMART', 'USD', 'NASDAQ'),
        ReportsFinStatements('PIH', 'SMART', 'USD', 'NASDAQ'),
        ReportsFinStatements('PIH', 'SMART', 'USD', 'NASDAQ'))
...