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

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.2
File Size Uploaded
asynctor-0.15.2.tar.gz 53.1 kB Details

Built distribution (wheel)

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

Total release size: 110.5 kB

Release files / asynctor-0.15.2.tar.gz

Download URL asynctor-0.15.2.tar.gz
Size 53.1 kB
Tags Source
SHA-256 checksum
How to use checksums
93cdf55eef165e82095a9a46d57c270ddfcead97c34e6412c6f211463dfb3bb8
BLAKE2b-256 checksum
How to use checksums
686845b1b7a4621d0d7482ebea9235dcd8285ca8f4c4b9fd0ea48a9d734f8f98
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.2-py3-none-any.whl

Download URL asynctor-0.15.2-py3-none-any.whl
Size 57.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0e73f3caebb27c1cc6f018c0d73cc39e277877631aaaf36454839e41ec2d2a5f
BLAKE2b-256 checksum
How to use checksums
332beeeb3cc694e93183efd8bae2cb997370ed16ad705908f056cd9a2ce194d9
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

0.15.3

2 release files

This release

0.15.2 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