Skip to main content

asynctor

Python Versions LatestVersionInPypi GithubActionResult pre-commit Coverage Status Mypy coverage Ruff

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
  1. 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
  1. 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.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for asynctor 0.15.5
File Size Uploaded
asynctor-0.15.5.tar.gz 53.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for asynctor 0.15.5
File Interpreter ABI Platform
asynctor-0.15.5-py3-none-any.whl Python 3 none any Details

Total release size: 111.0 kB

Release files / asynctor-0.15.5.tar.gz

Download URL asynctor-0.15.5.tar.gz
Size 53.3 kB
Tags Source
SHA-256 checksum
How to use checksums
b9a2d3f6fb9572c94aba65c67f282a8db82a6fa6530a4298fc06a46e9c7d30dd
BLAKE2b-256 checksum
How to use checksums
8494e3566d91c969b9c9aea1709b82c16878e1864acf650154c6be2f81151571
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.5-py3-none-any.whl

Download URL asynctor-0.15.5-py3-none-any.whl
Size 57.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4a96d0299f286ce60961b6a010eb6ef91beecc9f825539f2f36098a10be43073
BLAKE2b-256 checksum
How to use checksums
d1a73e0d845dd65ebbba318afcde71ca02321d22394c0edea1cf2a37e9bcf4e4
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 history Release notifications | RSS feed

This release

0.15.5 This release

2 release files

0.15.4

2 release files

0.15.3

2 release files

0.15.1

2 release files

0.15.0

2 release files

0.12.9

2 release files

0.12.8

2 release files

0.12.7

2 release files

0.12.6

2 release files

0.12.4

2 release files

0.12.2

2 release files

0.12.1

2 release files

0.11.9

2 release files

0.11.8

2 release files

0.11.7

2 release files

0.11.6

2 release files

0.11.5

2 release files

0.11.2

2 release files

0.11.1

2 release files

0.11.0

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.8

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.9

2 release files

0.6.8

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.5

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page