{"id":23375805,"url":"https://github.com/diefans/implant","last_synced_at":"2025-04-08T03:25:58.487Z","repository":{"id":144025968,"uuid":"67231937","full_name":"diefans/implant","owner":"diefans","description":"asynchronous adhoc remote procedure calls in Python","archived":false,"fork":false,"pushed_at":"2018-06-01T11:17:03.000Z","size":495,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-18T21:51:24.824Z","etag":null,"topics":["asyncio","bot","code","implant","python3","rpc"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/diefans.png","metadata":{"files":{"readme":"README.rst","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}},"created_at":"2016-09-02T15:01:53.000Z","updated_at":"2021-07-20T01:31:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"ef10d59c-de02-4ae5-8829-6f01ad746928","html_url":"https://github.com/diefans/implant","commit_stats":{"total_commits":239,"total_committers":1,"mean_commits":239.0,"dds":0.0,"last_synced_commit":"44203174ef8e0702be577a9e08dedde40e3ce1fe"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diefans%2Fimplant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diefans%2Fimplant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diefans%2Fimplant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diefans%2Fimplant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/diefans","download_url":"https://codeload.github.com/diefans/implant/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247768830,"owners_count":20992885,"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","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","bot","code","implant","python3","rpc"],"created_at":"2024-12-21T17:18:39.708Z","updated_at":"2025-04-08T03:25:58.472Z","avatar_url":"https://github.com/diefans.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. container:: bagdes\n\n    .. image:: https://travis-ci.org/diefans/implant.svg?branch=master\n       :target: https://travis-ci.org/diefans/implant\n       :align: right\n\n    .. image:: https://img.shields.io/pypi/pyversions/implant.svg\n       :target: https://pypi.org/project/implant/\n       :alt: PyPI - Python Version\n\n    .. image:: https://img.shields.io/pypi/v/implant.svg\n       :target: https://pypi.org/project/implant/\n       :alt: PyPI\n\n    .. image:: https://img.shields.io/readthedocs/implant.svg\n       :target: http://docs.implant.codes\n       :alt: Read the Docs\n\n    .. image:: https://codecov.io/gh/diefans/implant/branch/master/graph/badge.svg\n       :target: https://codecov.io/gh/diefans/implant\n\n----\n\n.. image:: implant.png\n   :alt: implant\n   :align: left\n\n\nimplant\n**********\n\nA proof-of-concept for asynchronous adhoc remote procedure calls in Python.\n\nThis is work in progress and serves basically as an exercise.\n\n\n.. inclusion-marker-do-not-remove\n\n\nFeatures\n========\n\n- Python \u003e= 3.5 asyncio\n\n- adhoc transferable remote procedures\n\n- remote part of a `implant.core.Command` may reside in a separate module\n\n- a `implant.core.Command` specific `implant.core.Channel`\n  enables arbitrary protocols between local and remote side\n\n- events\n\n- quite small core\n\n- tests\n\n\nLimitations\n===========\n\n- Python \u003e= 3.5\n\n- only pure Python modules are supported for remote import, if no venv is used\n\n- `implant.core.Command` s must reside in a module other then `__main__`\n\n- at the moment sudo must not ask for password\n\n\n\nExample\n=======\n\n\nGeneral application\n-------------------\n\n.. code:: python\n\n    import asyncio\n    import pathlib\n\n    from implant import core, connect, commands\n\n\n    async def remote_tasks():\n        # create a connector for a python process\n        connector = connect.Lxd(\n            container='zesty',\n            hostname='localhost'\n        )\n        connector_args = {\n            'python_bin': pathlib.Path('/usr/bin/python3')\n        }\n        # connect to a remote python process\n        remote = await connector.launch(**connector_args)\n\n        # start remote communication tasks\n        com_remote = asyncio.ensure_future(remote.communicate())\n        try:\n            # execute command\n            cmd = commands.SystemLoad()\n            result = await remote.execute(cmd)\n\n            print(\"Remote system load:\", result)\n\n        finally:\n            # stop communication tasks\n            com_remote.cancel()\n            await com_remote\n\n\n    if __name__ == '__main__':\n        loop = asyncio.get_event_loop()\n        loop.run_until_complete(remote_tasks())\n        loop.close()\n\n\nAn example Echo Command\n-----------------------\n\n.. code:: python\n\n    import logging\n    import os\n\n    from implant import core\n\n\n    log = logging.getLogger(__name__)\n\n\n    class Echo(core.Command):\n\n        \"\"\"Demonstrate the basic command API.\"\"\"\n\n        async def local(self, context):\n            \"\"\"The local side of the RPC.\n\n               :param context: :py:obj:`implant.core.DispatchLocalContext`\n            \"\"\"\n            # custom protocol\n            # first: send\n            await context.channel.send_iteration(\"send to remote\")\n\n            # second: receive\n            from_remote = []\n            async for x in context.channel:\n                from_remote.append(x)\n            log.debug(\"************ receiving from remote: %s\", from_remote)\n\n            # third: wait for remote to finish and return result\n            remote_result = await context.remote_future\n\n            result = {\n                'from_remote': ''.join(from_remote),\n            }\n            result.update(remote_result)\n            return result\n\n        async def remote(self, context):\n            \"\"\"The remote side of the RPC.\n\n               :param context: :py:obj:`implant.core.DispatchRemoteContext`\n            \"\"\"\n            # first: receive\n            from_local = []\n            async for x in context.channel:\n                from_local.append(x)\n            log.debug(\"************ receiving from local: %s\", from_local)\n\n            # second: send\n            await context.channel.send_iteration(\"send to local\")\n\n            # third: return result\n            return {\n                'from_local': ''.join(from_local),\n                'remote_self': self,\n                'pid': os.getpid()\n            }\n\n\nInternals\n=========\n\n::\n\n    master \u003c-----------------------------------------\u003e remote\n                                |\n                           stdin/stdout\n                                |\n                              chunks\n                                |\n                             channels\n                                |\n        --\u003e send ---\u003e |                   |  --\u003e queue --\u003e\n                      | module:class/fqin |\n        \u003c-- queue \u003c-- |                   |  \u003c--- send \u003c--\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiefans%2Fimplant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiefans%2Fimplant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiefans%2Fimplant/lists"}