asynctor
Some async functions that using anyio, and toolkit for excel read.
Installation
$ pip install asynctor
---> 100%
Successfully installed asynctor
with extras:
pip install "asynctor[xlsx,redis,fastapi]"
Or by pdm:
pdm add "asynctor[redis]"
Or by uv:
uv add asynctor
Or install the latest from github
uv pip install "asynctor @git+https://github.com/waketzheng/asynctor"
Or install by ssh
uv pip install "asynctor[redis] @git+ssh://git@github.com/waketzheng/asynctor.git"
Usage
- Async function that compare asyncio but use anyio:
bulk_gather/gather/run
>>> import asynctor
>>> async def foo():
... return 1
...
>>> await asynctor.bulk_gather([foo(), foo()], limit=200)
(1, 1)
>>> await asynctor.gather(foo(), foo())
(1, 1)
>>> asynctor.run(gather(foo(), foo()))
(1, 1)
run_async: start a new thread to run async function and get result of it
>>> from asynctor import run_async
>>> async def foo(a=1):
... return a
...
>>> run_async(foo) == run_async(foo()) == run_async(foo, 1) == 1
True
- timeit/Timer
>>> import time
>>> import anyio
>>> from asynctor import Timer, timeit
>>> @timeit
... async def sleep_test():
... await anyio.sleep(3)
...
>>> await sleep()
sleep_test Cost: 3.0 seconds
>>> @timeit
... def sleep_test2():
... time.sleep(3.1)
...
>>> sleep_test2()
sleep_test2 Cost: 3.1 seconds
>>> with Timer('Sleeping'):
... sleep()
...
Sleeping Cost: 3.0 seconds
>>> from loguru import logger
>>> with Timer('doing sth', verbose=False) as t:
... time.sleep(0.222)
...
>>> logger.debug(t)
2026-06-10 12:07:55.658 | DEBUG | __main__:<module>:1 - doing sth Cost: 0.2 seconds
>>> Timer.beijing_now()
datetime.datetime(2026, 6, 10, 12, 9, 1, 577094, tzinfo=asynctor.timing.ZoneInfo(key='Asia/Shanghai'))
- AioRedis
pip install "asynctor[redis]"
from asynctor.contrib.fastapi import AioRedisDep, register_aioredis
from fastapi import FastAPI
app = FastAPI()
register_aioredis(app)
@app.get("/")
async def root(redis: AioRedisDep) -> list[str]:
return await redis.keys()
@app.get("/redis")
async def get_value_from_redis_by_key(redis: AioRedisDep, key: str) -> str:
value = await redis.get(key)
if not value:
return ""
return value.decode()
- Async Test Fixtures
pip install "asynctor[testing]"
import pytest
from asynctor.testing import AsyncClient, anyio_backend_fixture, async_client_fixture
from main import app # isinstance(app, FastAPI)
anyio_backend = anyio_backend_fixture()
client = async_client_fixture(app)
@pytest.mark.anyio
async def test_api(client: AsyncClient):
response = await client.get("/")
assert response.status_code == 200
- runserver/config_access_log/add_timing_middleware for fastapi projects
pip install "asynctor[fastapi]"
from asynctor.contrib.fastapi import add_timing_middleware, config_access_log, runserver
from fastapi import FastAPI
app = FastAPI()
config_access_log()
add_timing_middleware(app)
if __name__ == "__main__":
runserver()
- Read Excel File
pandas/openpyxl is required, can be installed with xlsx extra: pip install "asynctor[xlsx]"
>>> from asynctor.xlsx import load_xlsx
>>> await load_xlsx('tests/demo.xlsx')
[{'Column1': 'row1-\\t%c', 'Column2\nMultiLines': 0, 'Column 3': 1, 4: ''}, {'Column1': 'r2c1\n00', 'Column2\nMultiLines': 'r2 c2', 'Column 3': 2, 4: ''}]
- json
Auto use orjson if it's installed, fallback to standard json module.
>>> from asynctor.jsons import json_dump_bytes
>>> json_dump_bytes({'a': 1})
b'{"a":1}'
>>> json_dump_bytes({'a': 1}, pretty=True)
b'{\n "a": 1\n}'
- utils
load_bool
>>> from asynctor.utils import load_bool
>>> load_bool('NOT_EXIST')
False
>>> import os
>>> os.environ['MY_ENV'] = '0'
>>> load_bool('MY_ENV')
False
>>> os.environ['MY_ENV'] = '1'
>>> load_bool('MY_ENV')
True
- ExtendSyspath
>>> import conftest
Traceback (most recent call last):
File "<python-input-0>", line 1, in <module>
import conftest
ModuleNotFoundError: No module named 'conftest'
>>> from pathlib import Path
>>> from asynctor.utils import ExtendSyspath
>>> with ExtendSyspath('tests'):
... import conftest
...
>>> Path(conftest.__file__).relative_to(Path.cwd()).as_posix()
'tests/conftest.py'
Metadata
Release files for asynctor 0.15.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| asynctor-0.15.4.tar.gz | 53.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| asynctor-0.15.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 110.7 kB
Release files / asynctor-0.15.4.tar.gz
| Download URL | asynctor-0.15.4.tar.gz |
|---|---|
| Size | 53.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
17a7e1d68c157365d02e5e73aec214369482ac960f438edde624d6ca92d8ce2e
|
|
BLAKE2b-256 checksum How to use checksums |
13ac22bf376283091312a7aa55a220883d84c076280463166b2261639a7001f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / asynctor-0.15.4-py3-none-any.whl
| Download URL | asynctor-0.15.4-py3-none-any.whl |
|---|---|
| Size | 57.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a33f59f440ef0c69e6abfafb8dcac3ba5c25f4a69043696b89fe37075e25aa0e
|
|
BLAKE2b-256 checksum How to use checksums |
4b9a46f01b605696deec980f8ffc1e8cbabbec3338b4fea71cc5726af47c46e4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|