Security News
Introducing the Socket Python SDK
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
asynckivy
is an async library that saves you from ugly callback-style code,
like most of async libraries do.
Let's say you want to do:
print('A')
print('B')
print('C')
in that order. Your code would look like this:
from kivy.clock import Clock
def what_you_want_to_do(button):
print('A')
def one_sec_later(__):
print('B')
button.bind(on_press=on_button_press)
Clock.schedule_once(one_sec_later, 1)
def on_button_press(button):
button.unbind(on_press=on_button_press)
print('C')
what_you_want_to_do(...)
It's not easy to understand.
If you use asynckivy
, the code above will become:
import asynckivy as ak
async def what_you_want_to_do(button):
print('A')
await ak.sleep(1)
print('B')
await ak.event(button, 'on_press')
print('C')
ak.start(what_you_want_to_do(...))
Pin the minor version.
poetry add asynckivy@~0.7
pip install "asynckivy>=0.7,<0.8"
import asynckivy as ak
async def some_task(button):
# waits for 2 seconds to elapse
dt = await ak.sleep(2)
print(f'{dt} seconds have elapsed')
# waits for a button to be pressed
await ak.event(button, 'on_press')
# waits for the value of 'button.x' to change
__, x = await ak.event(button, 'x')
print(f'button.x is now {x}')
# waits for the value of 'button.x' to become greater than 100
if button.x <= 100:
__, x = await ak.event(button, 'x', filter=lambda __, x: x>100)
print(f'button.x is now {x}')
# waits for either 5 seconds to elapse or a button to be pressed.
# i.e. waits at most 5 seconds for a button to be pressed
tasks = await ak.wait_any(
ak.sleep(5),
ak.event(button, 'on_press'),
)
print("Timeout" if tasks[0].finished else "The button was pressed")
# same as the above
async with ak.move_on_after(5) as bg_task:
await ak.event(button, 'on_press')
print("Timeout" if bg_task.finished else "The button was pressed")
# waits for both 5 seconds to elapse and a button to be pressed.
tasks = await ak.wait_all(
ak.sleep(5),
ak.event(button, 'on_press'),
)
# nest as you want.
# waits for a button to be pressed, and either 5 seconds to elapse or 'other_async_func' to complete.
tasks = await ak.wait_all(
ak.event(button, 'on_press'),
ak.wait_any(
ak.sleep(5),
other_async_func(),
),
)
child_tasks = tasks[1].result
print("5 seconds elapsed" if child_tasks[0].finished else "other_async_func has completed")
ak.start(some_task(some_button))
For more details, read the documentation.
Kivy supports two legitimate async libraries, asyncio and Trio, starting from version 2.0.0, so developing another one seems like reinventing the wheel. Actually, I started this one just to learn how the async/await syntax works, so it initially was "reinventing the wheel".
But after playing with Trio and Kivy for a while, I noticed that Trio is not suitable for the situation where fast reactions are required e.g. touch events.
The same is true of asyncio.
You can confirm that by running investigation/why_xxx_is_not_suitable_for_handling_touch_events.py
, and mashing a mouse button as quickly as possible.
You'll see sometimes up
is not paired with down
.
You'll see the coordinates aren't relative to the RelativeLayout
even though the target
belongs to it.
The cause of those problems is that trio.Event.set()
and asyncio.Event.set()
don't immediately resume the tasks waiting for the Event
to be set.
They just schedule the tasks to resume.
Same thing can be said to nursery.start_soon()
and asyncio.create_task()
.
Trio and asyncio are async I/O libraries after all.
They probably don't have to immediately resumes/starts tasks, which I think necessary for touch handling in Kivy.
(If you fail to handle touches promptly, their state might undergo changes, leaving no time to wait for tasks to resume/start).
Their core design might not be suitable for GUI in the first place.
That's why I'm still developing this asynckivy
library to this day.
FAQs
Async library for Kivy
We found that asynckivy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Security News
Floating dependency ranges in npm can introduce instability and security risks into your project by allowing unverified or incompatible versions to be installed automatically, leading to unpredictable behavior and potential conflicts.
Security News
A new Rust RFC proposes "Trusted Publishing" for Crates.io, introducing short-lived access tokens via OIDC to improve security and reduce risks associated with long-lived API tokens.