Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use callback async? #492

Open
Chimildic opened this issue Sep 29, 2021 · 4 comments
Open

How to use callback async? #492

Chimildic opened this issue Sep 29, 2021 · 4 comments

Comments

@Chimildic
Copy link

Need to register global hotkeys. For example, f4 and f8. With keyboard library while first callback didn't return, the next won't call.

Another words, logs like this

pressed f4
end for f4
pressed f8
end for f8

But I want to like this

pressed f4
pressed f8
end for f4
end for f8

Demo code

# pip install keyboard
from keyboard import add_hotkey, wait
from time import sleep

def on_callback(key):
    print('pressed', key)
    sleep(5)
    print('end for', key)

add_hotkey("f4", lambda: on_callback("f4"))
add_hotkey("f8", lambda: on_callback("f8"))

wait('esc')

I tried to use asyncio, but nothing changed

pressed f4
end for f4
pressed f8
end for f8
from keyboard import add_hotkey, wait
import asyncio

async def on_callback(key):
    print('pressed', key)
    await asyncio.sleep(5)
    print('end for', key)

add_hotkey("f4", lambda: asyncio.run(on_callback("f4")))
add_hotkey("f8", lambda: asyncio.run(on_callback("f8")))

wait('esc')
@boppreh
Copy link
Owner

boppreh commented Sep 29, 2021

Callbacks are executed in the same thread, sequentially, so two callbacks with 5 seconds of sleep each result in one long thread sleeping 10 seconds. Asyncio may have helped if you were not using sleep, which doesn't yield to the event loop.

The easiest solution is to spawn a new thread on each callback, so that they can sleep separately. You use keyboard.call_later for this, which by default sleeps only a few milliseconds:

# pip install keyboard
from keyboard import add_hotkey, wait, call_later
from time import sleep

def on_callback(key):
    print('pressed', key)
    sleep(5)
    print('end for', key)

add_hotkey("f4", lambda: call_later(on_callback, args=("f4",)))
add_hotkey("f8", lambda: call_later(on_callback, args=("f8",)))

wait('esc')

@Chimildic
Copy link
Author

sleep in order to emulate long task for demo.
Can you write example with asyncio?

@boppreh
Copy link
Owner

boppreh commented Sep 29, 2021

The asyncio version of sleep is asyncio.sleep, as detailed here: https://stackoverflow.com/questions/56729764/python-3-7-asyncio-sleep-and-time-sleep

However I'm not sure it'll play well with the rest of keyboard, since the library is thread-based. I would keep the call_later functions, they should work for other long running tasks other than sleep.

@Chimildic
Copy link
Author

Chimildic commented Sep 29, 2021

Yeah, call_later works correctly. I ask you about

Asyncio may have helped if you were not using sleep

In my case, async didn't happen

add_hotkey(item["keys"], lambda: asyncio.run(_on_callback(item["function"])))

async def _on_callback(function):
    response = await _script.run(function)

async def run(self, function: str):
    # ...
    return self.service.run(scriptId=self._id, body=body)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants