Registry / workflow / asyncio-atexit

asyncio-atexit

JSON →
library1.0.1pypypi✓ verified 85d ago

asyncio-atexit is a Python library that provides `atexit`-like functionality for `asyncio` event loops. It allows users to register coroutines or synchronous functions to be executed when the current `asyncio` event loop closes, rather than when the Python interpreter exits. The current version is 1.0.1, and it is a small utility that is updated infrequently but remains active and functional for its specific purpose.

pip install asyncio-atexit
INSTALL
IMPORT
SIG · ASYNCIO-ATEXIT
A
asyncio-atexit
workflowpythonv1.0.1
Install
1.5s avg
Import
197ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.0.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.212s · 17.8MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 1.5s · import 0.181s · 18MB
16MB installed
● package 16MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

register
from asyncio_atexit import register
unregister
from asyncio_atexit import unregister

Registers an asynchronous function and a synchronous function to be called when the asyncio event loop shuts down. This example demonstrates using `functools.partial` to pass arguments to the cleanup functions, as `asyncio-atexit` callbacks are invoked without arguments by default. The `asyncio.run` function typically manages loop closure, but an explicit `loop.close()` is added in the `finally` block to guarantee cleanup function execution in all environments for demonstration purposes.

import asyncio import asyncio_atexit import functools async def async_cleanup_task(resource_name): print(f"Async cleanup for {resource_name} started...") await asyncio.sleep(0.1) # Simulate async work print(f"Async cleanup for {resource_name} finished.") def sync_cleanup_task(message): print(f"Sync cleanup: {message}") async def main(): print("Main application started.") # Register an async cleanup task asyncio_atexit.register(functools.partial(async_cleanup_task, "Database Connection")) # Register a synchronous cleanup task asyncio_atexit.register(functools.partial(sync_cleanup_task, "Closing log file.")) print("Cleanup tasks registered.") await asyncio.sleep(0.5) # Simulate main application work print("Main application finishing.") if __name__ == '__main__': try: asyncio.run(main()) finally: # In some scenarios, especially with older asyncio.run or specific policies, # you might explicitly close the loop if it wasn't handled by asyncio.run. # asyncio-atexit hooks only run if the event loop is actually closed. # This ensures the example triggers the atexit hooks. loop = asyncio.get_event_loop() if not loop.is_closed(): loop.close()
Debug
Known issues
gotchaCallbacks registered with `asyncio-atexit` are called without arguments. To pass arguments to your cleanup functions, use `functools.partial` to wrap your function with its arguments.
fix
Wrap your target function with `functools.partial` before registering it, e.g., `asyncio_atexit.register(functools.partial(my_cleanup_func, arg1, kwarg='value'))`.
affects: All versions
gotchaCallbacks are only invoked when the associated `asyncio` event loop is explicitly closed. If your application's `asyncio` event loop is never closed (e.g., in long-running services or certain environments like `nest_asyncio` where loops are reused), registered cleanup functions may not execute.
fix
Ensure that `loop.close()` is called on the event loop where callbacks were registered. If using `asyncio.run()`, ensure it completes normally, as it typically handles loop closure. In complex scenarios or with libraries like `nest_asyncio`, you might need to manage loop lifecycle more explicitly.
affects: All versions
gotcha`asyncio-atexit.register()` must be called from within a running `asyncio` event loop. Attempting to register a callback without an active loop will likely result in an error or unexpected behavior.
fix
Ensure that `asyncio_atexit.register()` calls are made after the event loop has started, typically within an `async` function executed by `asyncio.run()` or `loop.run_until_complete()`.
affects: All versions
breakingUsing `asyncio-atexit` with `nest-asyncio` can be problematic, particularly on Python 3.14+. `nest_asyncio` alters the `asyncio` loop's closing behavior, often leaving the loop open and reused rather than truly closing it. This prevents `asyncio-atexit`'s hooks from firing, as they depend on the loop's `close()` method being called. Python 3.14+ further breaks `nest_asyncio` workarounds for nested loops.
fix
Avoid using `asyncio-atexit` with `nest-asyncio` if loop-closing guarantees are critical. If `nest-asyncio` is indispensable, ensure manual `loop.close()` calls are made when the outermost logical 'event loop' concludes, or reconsider cleanup strategies that don't rely on `asyncio-atexit`'s specific hook.
affects: asyncio-atexit all versions, especially with nest-asyncio on Python 3.14+
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'asyncio_atexit'
The 'asyncio-atexit' package is not installed in the Python environment.
fix
Install the package using pip: 'pip install asyncio-atexit'.
ImportError: cannot import name 'register' from 'asyncio_atexit'
Incorrect import statement; 'register' should be accessed directly from 'asyncio_atexit'.
fix
Use the correct import: 'import asyncio_atexit' and then call 'asyncio_atexit.register()'.
RuntimeError: Cannot run the event loop while another loop is running
Attempting to run an asyncio event loop within an existing running loop, often in interactive environments like Jupyter notebooks.
fix
Use 'asyncio.run()' for top-level entry points or 'await' within an existing event loop.
TypeError: 'coroutine' object is not callable
Registering a coroutine function without calling it, leading to passing the coroutine object instead of the function reference.
fix
Register the coroutine function without parentheses: 'asyncio_atexit.register(my_coroutine_function)'.
AttributeError: module 'asyncio_atexit' has no attribute 'unregister'
Attempting to use an 'unregister' function that does not exist in the 'asyncio-atexit' package.
fix
Ensure that the function to be unregistered is not registered, or manage registrations manually as 'asyncio-atexit' does not provide an 'unregister' function.
Upgrade
Version history
1.0.1latest on PyPI · released Apr 26, 2022
Audit
Dependencies

No dependency data recorded yet.

Agent activity
18 hits · last 30 days
node
14
OpenAI (training)
1
Resources
asyncio-atexit — pip install asyncio-atexit · libregistry