aioagi-ik


Nameaioagi-ik JSON
Version 1.2.2 PyPI version JSON
download
home_pagehttps://gitlab.com/VadimShakurov/aioagi.git
SummaryAsync agi client/server framework (asyncio)
upload_time2025-01-14 19:21:18
maintainerNone
docs_urlNone
authorShakurov Vadim Vladimirovich
requires_pythonNone
licenseApache 2
keywords aiogi asyncio asterisk telephony voip
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Aioagi
======

Async agi client/server framework.
The project based on "aiohttp" framework.

Key Features
============

- Supports both client and server side of AGI protocol.
- AGI-server has middlewares and pluggable routing.

Getting started
===============


Server
------

Simple AGI server:

.. code-block:: python

    import asyncio

    from aiohttp.web import Application, AppRunner, TCPSite, Response

    from aioagi import runner
    from aioagi.app import AGIApplication
    from aioagi.log import agi_server_logger
    from aioagi.urldispathcer import AGIView
    from aiohttp.web_runner import GracefulExit


    async def hello(request):
        message = await request.agi.stream_file('hello-world')
        await request.agi.verbose('Hello handler: {}.'.format(request.rel_url.query))
        agi_server_logger.debug(message)


    async def http_hello(request):
        return Response(text="Hello, world")


    class HelloView(AGIView):
        async def sip(self):
            message = await self.request.agi.stream_file('hello-world')
            await self.request.agi.verbose('HelloView handler: {}.'.format(self.request.rel_url.query))
            agi_server_logger.debug(message)


    if __name__ == '__main__':
        app = AGIApplication()
        app.router.add_route('SIP', '/', hello)
        runner.run_app(app)

    # OR
    if __name__ == '__main__':
        apps = []

        app = AGIApplication()
        app.router.add_route('SIP', '/', hello)

        http_app = Application()
        http_app.router.add_route('GET', '/', http_hello)

        loop = asyncio.get_event_loop()

        runners = []
        sites = []
        for _app in [app, http_app]:
            app_runner = AppRunner(_app)
            loop.run_until_complete(app_runner.setup())
            if isinstance(_app, AGIApplication):
                sites.append(runner.AGISite(app_runner, port=8081))
            else:
                sites.append(TCPSite(app_runner, port=8080))

            runners.append(app_runner)

        for site in sites:
            loop.run_until_complete(site.start())

        uris = sorted(str(s.name) for runner in runners for s in runner.sites)
        print("======== Running on {} ========\n"
              "(Press CTRL+C to quit)".format(', '.join(uris)))

        try:
            loop.run_forever()
        except (GracefulExit, KeyboardInterrupt):  # pragma: no cover
            pass

        finally:
            for runner in reversed(runners):
                loop.run_until_complete(runner.cleanup())

        if hasattr(loop, 'shutdown_asyncgens'):
            loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()


Client
------

To set AGI connection as Asterisk:

.. code-block:: python

    import asyncio
    import logging.config

    from aioagi.log import agi_client_logger
    from aioagi.client import AGIClientSession
    from aioagi.parser import AGIMessage, AGICode


    async def test_request(loop):
        headers = {
            'agi_channel': 'SIP/100-00000001',
            'agi_language': 'ru',
            'agi_uniqueid': '1532375920.8',
            'agi_version': '14.0.1',
            'agi_callerid': '100',
            'agi_calleridname': 'test',
            'agi_callingpres': '0',
            'agi_callingani2': '0',
            'agi_callington': '0',
            'agi_callingtns': '0',
            'agi_dnid': '101',
            'agi_rdnis': 'unknown',
            'agi_context': 'from-internal',
            'agi_extension': '101',
            'agi_priority': '1',
            'agi_enhanced': '0.0',
            'agi_accountcode': '',
            'agi_threadid': '139689736754944',
        }
        async with AGIClientSession(headers=headers, loop=loop) as session:
            async with session.sip('agi://localhost:8080/hello/?a=test1&b=var1') as response:
                async for message in response:
                    client_logger.debug(message)
                    await response.send(AGIMessage(AGICode.OK, '0', {}))

            async with session.sip('agi://localhost:8080/hello-view/?a=test2&b=var2') as response:
                async for message in response:
                    client_logger.debug(message)
                    await response.send(AGIMessage(AGICode.OK, '0', {}))

.. note:: Session request headers are set automatically for ``session.sip('agi://localhost:8080/hello/?a=test1&b=var1')`` request:

.. code-block:: bash

    agi_type: SIP
    agi_network: yes
    agi_network_script: hello/
    agi_request: agi://localhost:8080/hello/


AMI
---

.. code-block:: python

    import asyncio

    from aioagi.ami.action import AMIAction
    from aioagi.ami.manager import AMIManager


    async def callback(manager, message):
        print(message)


    async def main(app):
        manager = AMIManager(
            app=app, title='myasterisk',
            host='127.0.0.1',
            port=5038,
            username='username',
            secret='secret',
        )
        manager.register_event('*', callback)
        app['manager'] = manager
        await manager.connect()

        await asyncio.sleep(2)

        message = await manager.send_action(AMIAction({
            'Action': 'Command',
            'Command': 'database show',
        }))
        print(message)
        print(message.body)


    async def cleanup(app):
        app['manager'].close()


    if __name__ == '__main__':
        app = {}
        _loop = asyncio.get_event_loop()
        try:
            _loop.run_until_complete(main(app))
        except KeyboardInterrupt:
            _loop.run_until_complete(cleanup(app))
            _loop.close()


Install
=======

``pip install aioagi``


Thanks
======
* Gael Pasgrimaud - panoramisk_

.. _panoramisk: https://github.com/gawel/panoramisk

            

Raw data

            {
    "_id": null,
    "home_page": "https://gitlab.com/VadimShakurov/aioagi.git",
    "name": "aioagi-ik",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "aiogi asyncio asterisk telephony voip",
    "author": "Shakurov Vadim Vladimirovich",
    "author_email": "apelsinsd@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/11/bb/6656f134f0535f1538fb0aef8301a0bbfdcd3bd8a865f991df66e64df777/aioagi_ik-1.2.2.tar.gz",
    "platform": null,
    "description": "Aioagi\n======\n\nAsync agi client/server framework.\nThe project based on \"aiohttp\" framework.\n\nKey Features\n============\n\n- Supports both client and server side of AGI protocol.\n- AGI-server has middlewares and pluggable routing.\n\nGetting started\n===============\n\n\nServer\n------\n\nSimple AGI server:\n\n.. code-block:: python\n\n    import asyncio\n\n    from aiohttp.web import Application, AppRunner, TCPSite, Response\n\n    from aioagi import runner\n    from aioagi.app import AGIApplication\n    from aioagi.log import agi_server_logger\n    from aioagi.urldispathcer import AGIView\n    from aiohttp.web_runner import GracefulExit\n\n\n    async def hello(request):\n        message = await request.agi.stream_file('hello-world')\n        await request.agi.verbose('Hello handler: {}.'.format(request.rel_url.query))\n        agi_server_logger.debug(message)\n\n\n    async def http_hello(request):\n        return Response(text=\"Hello, world\")\n\n\n    class HelloView(AGIView):\n        async def sip(self):\n            message = await self.request.agi.stream_file('hello-world')\n            await self.request.agi.verbose('HelloView handler: {}.'.format(self.request.rel_url.query))\n            agi_server_logger.debug(message)\n\n\n    if __name__ == '__main__':\n        app = AGIApplication()\n        app.router.add_route('SIP', '/', hello)\n        runner.run_app(app)\n\n    # OR\n    if __name__ == '__main__':\n        apps = []\n\n        app = AGIApplication()\n        app.router.add_route('SIP', '/', hello)\n\n        http_app = Application()\n        http_app.router.add_route('GET', '/', http_hello)\n\n        loop = asyncio.get_event_loop()\n\n        runners = []\n        sites = []\n        for _app in [app, http_app]:\n            app_runner = AppRunner(_app)\n            loop.run_until_complete(app_runner.setup())\n            if isinstance(_app, AGIApplication):\n                sites.append(runner.AGISite(app_runner, port=8081))\n            else:\n                sites.append(TCPSite(app_runner, port=8080))\n\n            runners.append(app_runner)\n\n        for site in sites:\n            loop.run_until_complete(site.start())\n\n        uris = sorted(str(s.name) for runner in runners for s in runner.sites)\n        print(\"======== Running on {} ========\\n\"\n              \"(Press CTRL+C to quit)\".format(', '.join(uris)))\n\n        try:\n            loop.run_forever()\n        except (GracefulExit, KeyboardInterrupt):  # pragma: no cover\n            pass\n\n        finally:\n            for runner in reversed(runners):\n                loop.run_until_complete(runner.cleanup())\n\n        if hasattr(loop, 'shutdown_asyncgens'):\n            loop.run_until_complete(loop.shutdown_asyncgens())\n        loop.close()\n\n\nClient\n------\n\nTo set AGI connection as Asterisk:\n\n.. code-block:: python\n\n    import asyncio\n    import logging.config\n\n    from aioagi.log import agi_client_logger\n    from aioagi.client import AGIClientSession\n    from aioagi.parser import AGIMessage, AGICode\n\n\n    async def test_request(loop):\n        headers = {\n            'agi_channel': 'SIP/100-00000001',\n            'agi_language': 'ru',\n            'agi_uniqueid': '1532375920.8',\n            'agi_version': '14.0.1',\n            'agi_callerid': '100',\n            'agi_calleridname': 'test',\n            'agi_callingpres': '0',\n            'agi_callingani2': '0',\n            'agi_callington': '0',\n            'agi_callingtns': '0',\n            'agi_dnid': '101',\n            'agi_rdnis': 'unknown',\n            'agi_context': 'from-internal',\n            'agi_extension': '101',\n            'agi_priority': '1',\n            'agi_enhanced': '0.0',\n            'agi_accountcode': '',\n            'agi_threadid': '139689736754944',\n        }\n        async with AGIClientSession(headers=headers, loop=loop) as session:\n            async with session.sip('agi://localhost:8080/hello/?a=test1&b=var1') as response:\n                async for message in response:\n                    client_logger.debug(message)\n                    await response.send(AGIMessage(AGICode.OK, '0', {}))\n\n            async with session.sip('agi://localhost:8080/hello-view/?a=test2&b=var2') as response:\n                async for message in response:\n                    client_logger.debug(message)\n                    await response.send(AGIMessage(AGICode.OK, '0', {}))\n\n.. note:: Session request headers are set automatically for ``session.sip('agi://localhost:8080/hello/?a=test1&b=var1')`` request:\n\n.. code-block:: bash\n\n    agi_type: SIP\n    agi_network: yes\n    agi_network_script: hello/\n    agi_request: agi://localhost:8080/hello/\n\n\nAMI\n---\n\n.. code-block:: python\n\n    import asyncio\n\n    from aioagi.ami.action import AMIAction\n    from aioagi.ami.manager import AMIManager\n\n\n    async def callback(manager, message):\n        print(message)\n\n\n    async def main(app):\n        manager = AMIManager(\n            app=app, title='myasterisk',\n            host='127.0.0.1',\n            port=5038,\n            username='username',\n            secret='secret',\n        )\n        manager.register_event('*', callback)\n        app['manager'] = manager\n        await manager.connect()\n\n        await asyncio.sleep(2)\n\n        message = await manager.send_action(AMIAction({\n            'Action': 'Command',\n            'Command': 'database show',\n        }))\n        print(message)\n        print(message.body)\n\n\n    async def cleanup(app):\n        app['manager'].close()\n\n\n    if __name__ == '__main__':\n        app = {}\n        _loop = asyncio.get_event_loop()\n        try:\n            _loop.run_until_complete(main(app))\n        except KeyboardInterrupt:\n            _loop.run_until_complete(cleanup(app))\n            _loop.close()\n\n\nInstall\n=======\n\n``pip install aioagi``\n\n\nThanks\n======\n* Gael Pasgrimaud - panoramisk_\n\n.. _panoramisk: https://github.com/gawel/panoramisk\n",
    "bugtrack_url": null,
    "license": "Apache 2",
    "summary": "Async agi client/server framework (asyncio)",
    "version": "1.2.2",
    "project_urls": {
        "Homepage": "https://gitlab.com/VadimShakurov/aioagi.git"
    },
    "split_keywords": [
        "aiogi",
        "asyncio",
        "asterisk",
        "telephony",
        "voip"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "308720da2ca215db4dbd6445ae899bc8b0d50e2a1703db8c5a41dff169eb6ad5",
                "md5": "1e67c74fcc77c394352690a766550117",
                "sha256": "6329aa48a325058c88307556ec9d78e8ffc655bb87e93986492fc77287cece2b"
            },
            "downloads": -1,
            "filename": "aioagi_ik-1.2.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1e67c74fcc77c394352690a766550117",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 40059,
            "upload_time": "2025-01-14T19:21:13",
            "upload_time_iso_8601": "2025-01-14T19:21:13.309305Z",
            "url": "https://files.pythonhosted.org/packages/30/87/20da2ca215db4dbd6445ae899bc8b0d50e2a1703db8c5a41dff169eb6ad5/aioagi_ik-1.2.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "11bb6656f134f0535f1538fb0aef8301a0bbfdcd3bd8a865f991df66e64df777",
                "md5": "33a1df38b4860f8689dabab498047a64",
                "sha256": "b7c572eea697de6aa5ab29efbf3e733b0cf54f6a870930426d8c36807ad53c6e"
            },
            "downloads": -1,
            "filename": "aioagi_ik-1.2.2.tar.gz",
            "has_sig": false,
            "md5_digest": "33a1df38b4860f8689dabab498047a64",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 35843,
            "upload_time": "2025-01-14T19:21:18",
            "upload_time_iso_8601": "2025-01-14T19:21:18.363346Z",
            "url": "https://files.pythonhosted.org/packages/11/bb/6656f134f0535f1538fb0aef8301a0bbfdcd3bd8a865f991df66e64df777/aioagi_ik-1.2.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-14 19:21:18",
    "github": false,
    "gitlab": true,
    "bitbucket": false,
    "codeberg": false,
    "gitlab_user": "VadimShakurov",
    "gitlab_project": "aioagi",
    "lcname": "aioagi-ik"
}
        
Elapsed time: 0.41063s