0

I have an Issue with asyncio I can't really get me head around.

take this working example (with Python 3.6+ because of string interpolation)

import asyncio
import aiohttp
import async_timeout
import json


async def fetch(session, url):
    async with async_timeout.timeout(10):
        async with session.get(url) as response:
            return await response.text()


async def get_bittrex_marketsummary(currency_pair):
    url = f'https://bittrex.com/api/v1.1/public/getmarketsummary?market={currency_pair}'
    async with aiohttp.ClientSession() as session:
        response = await fetch(session, url)
    return json.loads(response)


class MyCryptoCurrency:
    def __init__(self):
        self.currency = "BTC-ETH"
        self.last_price = None
        asyncio.ensure_future(self.get_last_price())

    async def get_last_price(self):
        self.last_price = await get_bittrex_marketsummary(self.currency)


async def main():
    eth = MyCryptoCurrency()
    print(eth.last_price)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

while this runs and doesn't throw any Exceptions, it doesn't get the result from the api request and so ... doesn't work :P

If I try to use f.e. loop.run_until_complete(get_bittrex_marketsummary()) I get "event loop is already running" error - which kind of makes sense.

Any hints how to solve this properly?

Thx in advance!

elmcrest
  • 195
  • 11
  • related but doesn't solve my specific issue: https://stackoverflow.com/questions/42009202/how-to-call-a-async-function-contained-in-a-class – elmcrest Mar 20 '18 at 12:34

1 Answers1

1

ok, after talking about this in #python channel on freenode I got the answer "don't do async I/O in __init__", so here is the working version:

import asyncio
import aiohttp
import async_timeout
import json


async def fetch(session, url):
    async with async_timeout.timeout(10):
        async with session.get(url) as response:
            return await response.text()


async def get_bittrex_marketsummary(currency_pair):
    url = f'https://bittrex.com/api/v1.1/public/getmarketsummary?market={currency_pair}'
    async with aiohttp.ClientSession() as session:
        response = await fetch(session, url)
    return json.loads(response)


class MyCryptoCurrency:
    def __init__(self):
        self.currency = "BTC-ETH"
        self.last_price = None

    async def get_last_price(self):
        self.last_price = await get_bittrex_marketsummary(self.currency)


async def main():
    eth = MyCryptoCurrency()
    await eth.get_last_price()
    print(eth.last_price)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
elmcrest
  • 195
  • 11