{"id":21877777,"url":"https://github.com/byunjuneseok/async-typer","last_synced_at":"2026-05-31T05:01:16.751Z","repository":{"id":221143043,"uuid":"753578160","full_name":"byunjuneseok/async-typer","owner":"byunjuneseok","description":"Simple async wrapper for the typer. Use async function with typer easily. ","archived":false,"fork":false,"pushed_at":"2025-09-02T05:28:45.000Z","size":14,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-27T06:02:07.355Z","etag":null,"topics":["async","fastapi","python","typer"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/byunjuneseok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-02-06T11:59:41.000Z","updated_at":"2025-09-15T06:35:23.000Z","dependencies_parsed_at":"2024-02-06T13:35:34.918Z","dependency_job_id":"8cb0d773-fc53-4048-8bca-2f36d4102fa2","html_url":"https://github.com/byunjuneseok/async-typer","commit_stats":null,"previous_names":["byunjuneseok/async-typer"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/byunjuneseok/async-typer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byunjuneseok%2Fasync-typer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byunjuneseok%2Fasync-typer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byunjuneseok%2Fasync-typer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byunjuneseok%2Fasync-typer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/byunjuneseok","download_url":"https://codeload.github.com/byunjuneseok/async-typer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byunjuneseok%2Fasync-typer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33719601,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","fastapi","python","typer"],"created_at":"2024-11-28T08:10:27.556Z","updated_at":"2026-05-31T05:01:16.745Z","avatar_url":"https://github.com/byunjuneseok.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# async-typer\n\n[Typer](https://github.com/tiangolo/typer) with first-class async support:\n`async def` commands and callbacks work alongside regular sync ones via the\nsame `@app.command()` decorator — no second API to remember — plus lifecycle\nevent handlers for setting up and tearing down async resources.\n\n## Features\n\n- **One decorator, sync or async** — `@app.command()` and `@app.callback()`\n  accept both regular and `async def` functions. The wrapper is transparent;\n  Typer's `--help`, option parsing, and type conversion all work as normal.\n- **Shared event loop across the command lifecycle** — startup handlers,\n  the command body, and shutdown handlers all run on the same\n  [`asyncio.Runner`](https://docs.python.org/3/library/asyncio-runner.html),\n  so async resources created on startup (connection pools, HTTP sessions,\n  etc.) remain usable by the command and by shutdown.\n- **Fully typed** — ships with a `py.typed` marker and strict type hints.\n- **Drop-in replacement** — re-exports Typer's public API, so\n  `from async_typer import Option, Argument, echo, ...` works without a\n  second import line.\n\n## Installation\n\n```bash\npip install async-typer\n# or\nuv add async-typer\n```\n\nRequires Python 3.11+.\n\n## Quick start\n\n```python\nfrom async_typer import AsyncTyper\n\napp = AsyncTyper()\n\n\n@app.command()\ndef sync_hello(name: str = \"world\") -\u003e None:\n    print(f\"hi {name}\")\n\n\n@app.command()\nasync def async_hello(name: str = \"world\") -\u003e None:\n    # await anything you need here\n    print(f\"hello {name}\")\n\n\nif __name__ == \"__main__\":\n    app()\n```\n\n## Async callbacks\n\n```python\n@app.callback()\nasync def main(verbose: bool = False) -\u003e None:\n    if verbose:\n        print(\"verbose mode\")\n```\n\n## Lifecycle event handlers\n\nRegister `startup` and `shutdown` hooks, sync or async. They run on the\nsame event loop as the command body, so shared async resources stay alive\nacross the whole invocation:\n\n```python\nimport httpx\n\napp = AsyncTyper()\nstate: dict[str, httpx.AsyncClient] = {}\n\n\nasync def open_client() -\u003e None:\n    state[\"client\"] = httpx.AsyncClient()\n\n\nasync def close_client() -\u003e None:\n    await state[\"client\"].aclose()\n\n\napp.add_event_handler(\"startup\", open_client)\napp.add_event_handler(\"shutdown\", close_client)\n\n\n@app.command()\nasync def fetch(url: str) -\u003e None:\n    response = await state[\"client\"].get(url)\n    print(response.status_code)\n```\n\nThe shutdown handler runs even if the command raises — use it to release\nresources unconditionally.\n\n## Migrating from 0.1.x\n\nThe separate `async_command` / `async_callback` decorators still work but\nemit `DeprecationWarning`. Replace them with the unified `command` /\n`callback`, which auto-detect `async def`:\n\n```python\n# before\n@app.async_command()\nasync def foo(): ...\n\n# after\n@app.command()\nasync def foo(): ...\n```\n\n## Development\n\nThis repo uses [`uv`](https://github.com/astral-sh/uv),\n[`ruff`](https://github.com/astral-sh/ruff), and\n[`ty`](https://github.com/astral-sh/ty).\n\n```bash\nuv sync --dev\nuv run pytest\nuv run ruff check .\nuv run ty check\n```\n\n## License\n\nMIT — see [LICENSE.txt](LICENSE.txt).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyunjuneseok%2Fasync-typer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyunjuneseok%2Fasync-typer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyunjuneseok%2Fasync-typer/lists"}