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.3

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.3
File Size Uploaded
asynctor-0.15.3.tar.gz 53.2 kB Details

Built distribution (wheel)

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

Total release size: 110.7 kB

Release files / asynctor-0.15.3.tar.gz

Download URL asynctor-0.15.3.tar.gz
Size 53.2 kB
Tags Source
SHA-256 checksum
How to use checksums
1657bd7995e468b9cb5e45d33c06caf6b4a23c902215dc0d44c7716c2e789ff0
BLAKE2b-256 checksum
How to use checksums
cf0a34e6088ee4f1a96d425887f8599c07f5f3ba29c1408816ccfd0ba3d9d6fd
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.3-py3-none-any.whl

Download URL asynctor-0.15.3-py3-none-any.whl
Size 57.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c5617867fa88f28f36b2090d93b9a898a5067c2b19642c8ee7464cefbfe1043
BLAKE2b-256 checksum
How to use checksums
6f34df3aa9c27faf9675214467f18963560495d3139810fb1dbcb4afd97f8f9a
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

0.15.5

2 release files

0.15.4

2 release files

This release

0.15.3 This release

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