{"id":31079599,"url":"https://github.com/welchbj/sublemon","last_synced_at":"2025-10-06T01:45:42.858Z","repository":{"id":50201664,"uuid":"153152394","full_name":"welchbj/sublemon","owner":"welchbj","description":"Python 3.6+ library for local asynchronous subprocess spawning and monitoring","archived":true,"fork":false,"pushed_at":"2022-12-08T01:16:03.000Z","size":109,"stargazers_count":12,"open_issues_count":6,"forks_count":1,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-09-29T18:32:03.964Z","etag":null,"topics":["asyncio","concurrency","streams","subprocess"],"latest_commit_sha":null,"homepage":"https://sublemon.brianwel.ch","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/welchbj.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}},"created_at":"2018-10-15T17:14:19.000Z","updated_at":"2025-09-01T03:57:48.000Z","dependencies_parsed_at":"2023-01-24T06:31:08.188Z","dependency_job_id":null,"html_url":"https://github.com/welchbj/sublemon","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/welchbj/sublemon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/welchbj%2Fsublemon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/welchbj%2Fsublemon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/welchbj%2Fsublemon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/welchbj%2Fsublemon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/welchbj","download_url":"https://codeload.github.com/welchbj/sublemon/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/welchbj%2Fsublemon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278547879,"owners_count":26004773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"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":["asyncio","concurrency","streams","subprocess"],"created_at":"2025-09-16T10:28:15.597Z","updated_at":"2025-10-06T01:45:42.851Z","avatar_url":"https://github.com/welchbj.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg width=\"300\" height=\"200\" src=\"https://raw.githubusercontent.com/welchbj/sublemon/master/static/logo.png\" alt=\"sublemon\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eSublemon\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  🍈 \u003cem\u003elocal asynchronous subprocess control\u003c/em\u003e 🍋\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://travis-ci.org/welchbj/sublemon\"\u003e\n    \u003cimg src=\"https://img.shields.io/travis/welchbj/sublemon/master.svg?style=flat-square\u0026label=travis\" alt=\"travis status\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/sublemon/\"\u003e\n    \u003cimg src=\"https://img.shields.io/pypi/v/sublemon.svg?style=flat-square\u0026label=pypi\" alt=\"pypi\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.python.org/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/python-3.6+-2a98ed.svg?style=flat-square\" alt=\"python version\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Installation\n\nTo get the latest version from PyPI, use:\n```sh\npip install sublemon\n```\n\nAlternatively, install the latest version from version control:\n```sh\npip install https://github.com/welchbj/sublemon/archive/master.tar.gz\n```\n\n\n## Basic Usage\n\nThe below example shows some of the basic subprocess-spawning functionality of this library:\n```python\nimport asyncio\nimport time\n\nfrom sublemon import (\n    amerge,\n    crossplat_loop_run,\n    Sublemon)\n\n\nasync def main():\n    \"\"\"`sublemon` library example!\"\"\"\n    for c in (1, 2, 4,):\n        async with Sublemon(max_concurrency=c) as s:\n            start = time.perf_counter()\n            await asyncio.gather(one(s), two(s))\n            end = time.perf_counter()\n            print('Limiting to', c, 'concurrent subprocess(es) took',\n                  end-start, 'seconds\\n')\n\n\nasync def one(s: Sublemon):\n    \"\"\"Spin up some subprocesses, sleep, and echo a message for this coro.\"\"\"\n    shell_cmds = [\n        'sleep 1 \u0026\u0026 echo subprocess 1 in coroutine one',\n        'sleep 1 \u0026\u0026 echo subprocess 2 in coroutine one']\n    async for line in s.iter_lines(*shell_cmds):\n        print(line)\n\n\nasync def two(s: Sublemon):\n    \"\"\"Spin up some subprocesses, sleep, and echo a message for this coro.\"\"\"\n    subprocess_1, subprocess_2 = s.spawn(\n        'sleep 1 \u0026\u0026 echo subprocess 1 in coroutine two',\n        'sleep 1 \u0026\u0026 echo subprocess 2 in coroutine two')\n    async for line in amerge(subprocess_1.stdout, subprocess_2.stdout):\n        print(line.decode('utf-8'), end='')\n\n\nif __name__ == '__main__':\n    crossplat_loop_run(main())\n\n```\n\nRunning this example would yield the following console output, demonstrating `sublemon`'s ability to rate-limit pooled subprocess execution:\n```\nsubprocess 1 in coroutine one\nsubprocess 2 in coroutine one\nsubprocess 1 in coroutine two\nsubprocess 2 in coroutine two\nLimiting to 1 concurrent subprocess(es) took 4.251494415589895 seconds\n\nsubprocess 1 in coroutine one\nsubprocess 2 in coroutine one\nsubprocess 2 in coroutine two\nsubprocess 1 in coroutine two\nLimiting to 2 concurrent subprocess(es) took 2.1220036135871787 seconds\n\nsubprocess 1 in coroutine one\nsubprocess 2 in coroutine one\nsubprocess 1 in coroutine two\nsubprocess 2 in coroutine two\nLimiting to 4 concurrent subprocess(es) took 1.083995944693033 seconds\n```\n\n\n## License\n\n`sublemon` uses the [MIT License](https://opensource.org/licenses/MIT).\n\n\n## Development\n\nThe development requirements can be installed with:\n```sh\npip install -r requirements.txt\n```\n\nThen try running the tests with:\n```sh\npython test.py\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwelchbj%2Fsublemon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwelchbj%2Fsublemon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwelchbj%2Fsublemon/lists"}