diff --git a/.github/workflows/python-test.yaml b/.github/workflows/python-test.yaml index 61fdaad..2ba7f8d 100644 --- a/.github/workflows/python-test.yaml +++ b/.github/workflows/python-test.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index ac2559a..08c141d 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name='python-yate', - version='0.4.1', + version='0.5.0', packages=['yate'], url='https://github.com/eventphone/python-yate', license='MIT', @@ -19,15 +19,11 @@ description='An (asyncio enabled) python library for yate IVRs and extmodules', classifiers=[ "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "License :: OSI Approved :: MIT License", ], - install_requires=[ - 'async_timeout', - ], entry_points={ "console_scripts": [ "yate_callgen=yate.callgen:main", diff --git a/tox.ini b/tox.ini index dd63438..746d110 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37,py38,py39,py310 +envlist = py311, py312, py313, py314 [testenv] diff --git a/yate/asyncio.py b/yate/asyncio.py index 7c22e74..ce8aef7 100644 --- a/yate/asyncio.py +++ b/yate/asyncio.py @@ -20,6 +20,7 @@ def __init__(self, host=None, port=None, sockpath=None): self.writer = None self.main_task = None self._automatic_bufsize = False + self._termination_handler = None if host is not None: self.mode = self.MODE_TCP @@ -34,6 +35,9 @@ def __init__(self, host=None, port=None, sockpath=None): def run(self, application_main): asyncio.run(self._amain(application_main)) + def set_termination_handler(self, termination_handler): + self._termination_handler = termination_handler + async def _amain(self, application_main): if self.mode == self.MODE_STDIO: await self.setup_for_stdio() @@ -108,7 +112,8 @@ def deferred_msg_write(_param, _value, _success): logger.debug("> %s", repr(msg)) async def _yate_stream_closed(self): - pass + if self._termination_handler is not None: + self._termination_handler() async def drain(self): await self.writer.drain() diff --git a/yate/callgen.py b/yate/callgen.py index 559fa89..d719506 100644 --- a/yate/callgen.py +++ b/yate/callgen.py @@ -29,6 +29,7 @@ def __init__(self, port, sounds_directory, bind_global=False): self.active_calls = {} self.yate = YateAsync("127.0.0.1", port) + self.yate.set_termination_handler(self.termination_handler) self.sounds_directory = sounds_directory self.web_app = web.Application() @@ -71,6 +72,12 @@ async def application_main(self, yate): def shutdown(self): self.shutdown_future.set_result(True) + @staticmethod + def termination_handler(): + logging.info("Yate has closed the connection. Terminating application.") + os._exit(1) + + async def web_call_handler(self, request): params = await request.post() diff --git a/yate/ivr.py b/yate/ivr.py index 921a293..cccb95d 100644 --- a/yate/ivr.py +++ b/yate/ivr.py @@ -3,8 +3,6 @@ from enum import Enum from typing import Optional, Callable -import async_timeout - from yate.asyncio import YateAsync from yate.protocol import MessageRequest @@ -156,7 +154,7 @@ async def read_dtmf_until(self, stop_symbols: str, timeout_s: float = None) -> s """ local_buf = "" try: - async with async_timeout.timeout(timeout_s): + async with asyncio.timeout(timeout_s): self.dtmf_buffer = "" while True: await self.dtmf_event.wait() @@ -183,7 +181,7 @@ async def read_dtmf_symbols(self, count: int, timeout_s: float = None) -> str: """ result = "" try: - async with async_timeout.timeout(timeout_s): + async with asyncio.timeout(timeout_s): self.dtmf_buffer = "" for _ in range(count): await self.dtmf_event.wait()