jaraco / keyring

MIT License
1.26k stars 159 forks source link

create an asyncio interface #397

Open graingert opened 5 years ago

graingert commented 5 years ago

Ideally I'd like to see an asyncio interface to keyring:

async def _keyring_stuff():
    keyring.aset_password("example", "example", "example")
    pw = keyring.aget_password("example", "example")

    async with keyring.aget_keyring() as kr:
        kr.set_password("example", "example", "example")
        pw = kr.get_password("example", "example")
graingert commented 5 years ago

I'm a little confused. Does every project in PyPI need to be rewritten for asyncio? If so, that doesn't seem sustainable, and duplicating every method that might ultimately have IO interaction to have an async doppleganger seems unruly and messy. Keyring aims to supply a small and simple interface with get/set/delete_password. Adding async variants to each of those will double the required interfaces and will likely require each and every backend to implement those variants. I'm struggling to see how that's viable.

Perhaps the aget_keyring() approach may be viable without proliferating interfaces, though I haven't done enough async programming to know with confidence.

Would you be willing to explore an adaptation of the Keyring base class that doesn't impose any necessary changes on the backends?

that's easy enough you 'just' wrap the sync versions with a https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.loop.run_in_executor

graingert commented 5 years ago

however that's won't work for jeepney and other services that already wrap their asyncio interfaces

graingert commented 5 years ago

Does every project in PyPI need to be rewritten for asyncio?

yes

jaraco commented 4 years ago

I'm not sure what's the best course of action here. The only recommendation is something that "won't work" for jeepney and other services. What's to be done?

nlgranger commented 8 months ago

What about using asyncio.to_thread? I'd expect keyring to be mostly IO bound with system calls releasing the GIL right? @jaraco does one need to serialize calls by holding a lock or is keyring threadsafe?

jaraco commented 8 months ago

Does one need to serialize calls by holding a lock or is keyring threadsafe?

I'm not sure. It doesn't do anything specifically to be thread safe, but it also doesn't do a lot with state internally - it's mostly an adapter layer to the underlying APIs. You may be able to find some calls that are thread-unsafe, but my suspicion is that the actual behavior is still stable. I welcome others to investigate deeper to see if there's a risk if run in a multithreaded environment.