{"id":34045183,"url":"https://github.com/tastyware/streaq","last_synced_at":"2026-02-22T05:00:50.312Z","repository":{"id":278471167,"uuid":"927444432","full_name":"tastyware/streaq","owner":"tastyware","description":"Fast, async, fully-typed distributed task queue via Redis streams","archived":false,"fork":false,"pushed_at":"2026-02-20T16:48:28.000Z","size":1004,"stargazers_count":125,"open_issues_count":5,"forks_count":11,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-02-20T21:09:59.778Z","etag":null,"topics":["anyio","asyncio","distributed-systems","fastapi","redis","task-queue","trio","typed"],"latest_commit_sha":null,"homepage":"https://streaq.rtfd.io","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/tastyware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.rst","funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":"tastyware"}},"created_at":"2025-02-05T00:52:19.000Z","updated_at":"2026-02-20T16:48:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"d457ac49-c2b8-42a6-a125-a508f6ece23c","html_url":"https://github.com/tastyware/streaq","commit_stats":null,"previous_names":["tastyware/streaq"],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/tastyware/streaq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tastyware%2Fstreaq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tastyware%2Fstreaq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tastyware%2Fstreaq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tastyware%2Fstreaq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tastyware","download_url":"https://codeload.github.com/tastyware/streaq/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tastyware%2Fstreaq/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29705523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T03:17:42.375Z","status":"ssl_error","status_checked_at":"2026-02-22T03:17:31.622Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["anyio","asyncio","distributed-systems","fastapi","redis","task-queue","trio","typed"],"created_at":"2025-12-13T23:04:30.247Z","updated_at":"2026-02-22T05:00:50.307Z","avatar_url":"https://github.com/tastyware.png","language":"Python","funding_links":["https://github.com/sponsors/tastyware"],"categories":[],"sub_categories":[],"readme":"[![Docs](https://readthedocs.org/projects/streaq/badge/?version=latest)](https://streaq.readthedocs.io/en/latest/?badge=latest)\n[![PyPI](https://img.shields.io/pypi/v/streaq)](https://pypi.org/project/streaq)\n[![Downloads](https://static.pepy.tech/badge/streaq)](https://pepy.tech/project/streaq)\n[![Release](https://img.shields.io/github/v/release/tastyware/streaq?label=release%20notes)](https://github.com/tastyware/streaq/releases)\n![Coverage](https://raw.githubusercontent.com/tastyware/streaq/master/coverage.svg)\n[![Gitter](https://img.shields.io/gitter/room/:user/tastyware)](https://matrix.to/#/#tastyware:gitter.im)\n\n# streaQ\n\nFast, async, fully-typed distributed task queue via Redis streams\n\n## Features\n\n- Up to [5x faster](https://github.com/tastyware/streaq/tree/master/benchmarks) than `arq`\n- Fully typed\n- Comprehensive documentation\n- Support for delayed/scheduled tasks\n- Cron jobs\n- Task middleware\n- Task dependency graph\n- Pipelining\n- Priority queues\n- Support for synchronous tasks (run in separate threads)\n- Redis Sentinel \u0026 Cluster support for production\n- Built-in web UI for monitoring tasks\n- Built with structured concurrency on `anyio`, supports both `asyncio` and `trio`\n\n\u003e [!TIP]\n\u003e Sick of `redis-py`? Check out [coredis](https://coredis.readthedocs.io/en/latest/), a fast, fully-typed Redis client that supports Trio!\n\n## Installation\n\n```console\n$ pip install streaq\n```\n\n## Getting started\n\nTo start, you'll need to create a `Worker` object:\n\n```python\nfrom streaq import Worker\n\nworker = Worker(redis_url=\"redis://localhost:6379\", anyio_backend=\"trio\")\n```\n\nYou can then register async tasks with the worker like this:\n\n```python\nimport trio\n\n@worker.task\nasync def sleeper(time: int) -\u003e int:\n    await trio.sleep(time)\n    return time\n\n@worker.cron(\"* * * * mon-fri\")  # every minute on weekdays\nasync def cronjob() -\u003e None:\n    print(\"Nobody respects the spammish repetition!\")\n```\n\nFinally, let's use the worker's async context manager to queue up some tasks:\n\n```python\nasync with worker:\n    await sleeper.enqueue(3)\n    # enqueue returns a task object that can be used to get results/info\n    task = await sleeper.enqueue(1).start(delay=3)\n    print(await task.info())\n    print(await task.result(timeout=5))\n```\n\nPutting this all together gives us [example.py](https://github.com/tastyware/streaq/blob/master/example.py). Let's spin up a worker:\n```\n$ streaq run example:worker\n```\nand queue up some tasks like so:\n```\n$ python example.py\n```\n\nLet's see what the output looks like:\n\n```\n[INFO] 2025-09-23 02:14:30: starting worker 3265311d for 2 functions\n[INFO] 2025-09-23 02:14:35: task sleeper □ cf0c55387a214320bd23e8987283a562 → worker 3265311d\n[INFO] 2025-09-23 02:14:38: task sleeper ■ cf0c55387a214320bd23e8987283a562 ← 3\n[INFO] 2025-09-23 02:14:40: task sleeper □ 1de3f192ee4a40d4884ebf303874681c → worker 3265311d\n[INFO] 2025-09-23 02:14:41: task sleeper ■ 1de3f192ee4a40d4884ebf303874681c ← 1\n[INFO] 2025-09-23 02:15:00: task cronjob □ 2a4b864e5ecd4fc99979a92f5db3a6e0 → worker 3265311d\nNobody respects the spammish repetition!\n[INFO] 2025-09-23 02:15:00: task cronjob ■ 2a4b864e5ecd4fc99979a92f5db3a6e0 ← None\n```\n```python\nTaskInfo(fn_name='sleeper', enqueue_time=1751508876961, tries=0, scheduled=datetime.datetime(2025, 7, 3, 2, 14, 39, 961000, tzinfo=datetime.timezone.utc), dependencies=set(), dependents=set())\nTaskResult(fn_name='sleeper', enqueue_time=1751508876961, success=True, start_time=1751508880500, finish_time=1751508881503, tries=1, worker_id='ca5bd9eb', _result=1)\n```\n\nFor more examples, check out the [documentation](https://streaq.readthedocs.io/en/latest/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftastyware%2Fstreaq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftastyware%2Fstreaq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftastyware%2Fstreaq/lists"}