leonhard-s / auraxium

A high-level Python wrapper for the PlanetSide 2 API.
https://auraxium.readthedocs.io/
MIT License
28 stars 8 forks source link

README example is raising RuntimeError #60

Closed yakMM closed 1 year ago

yakMM commented 1 year ago

Not really relevant for real use, but might be impactful for new users as it's a basic example from the README

Reproduction steps:

Config: Python 3.10.4, auraxium 0.2.2, windows 10.

Running the following script as main.py from the github README:

import asyncio
import auraxium
from auraxium import ps2

async def main():
    async with auraxium.Client(service_id="REDACTED") as client:

        char = await client.get_by_name(ps2.Character, 'auroram')
        print(char.name)
        print(char.data.prestige_level)

        # NOTE: Any methods that might incur network traffic are asynchronous.
        # If the data type has been cached locally, no network communication
        # is required.

        # This will only generate a request once per faction, as the faction
        # data type is cached forever by default.
        print(await char.faction())

        # The online status is never cached as it is bound to change at any
        # moment.
        print(await char.is_online())

asyncio.run(main())

Expected result:

The script is working, data from the api is properly displayed => OK

Unexpected result:

RuntimeError raised during the cleanup phase:

Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000016243D50280>
Traceback (most recent call last):
  File "[REDACTED]\Python310\lib\asyncio\proactor_events.py", line 116, in __del__
    self.close()
  File "[REDACTED]\Python310\lib\asyncio\proactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "[REDACTED]\Python310\lib\asyncio\base_events.py", line 750, in call_soon
    self._check_closed()
  File "[REDACTED]\Python310\lib\asyncio\base_events.py", line 515, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Workaround:

Adding asyncio.sleep(2) at the end of the main function fixes the problem, I assume the connection is not closed properly before the loop is closed.

leonhard-s commented 1 year ago

Thanks for the report - this is a known issue with current implementation details of aiohttp and asyncio: https://docs.aiohttp.org/en/stable/client_advanced.html#graceful-shutdown

So while technically not related to this project, I'll look into adding a brief sleep as part of the client close() method to avoid confusion for users.

leonhard-s commented 1 year ago

Fixed upstream in Python 3.11. For previous versions, a janky workaround has been in 2bc89d7.