python-ami
python-ami copied to clipboard
Fix EventList events handling
Hello. I've added fix to to the bug https://github.com/ettoreleandrotognoli/python-ami/issues/26.
Thank you.
@soloma83 this fix makes some trouble. Try this code (and make some call) before fix and after
import time
from settings import login, connection
from asterisk.ami import AMIClient, SimpleAction
def send_action(event):
print(1, event.status)
print(2, event.keys)
print(3, event.follows)
def event_listener(event, **kwargs):
if event.name == 'Newchannel':
action = SimpleAction('Status')
client.send_action(action, callback=send_action)
if event.name == 'Status':
print(4, event)
client = AMIClient(**connection)
future = client.login(**login)
client.add_event_listener(event_listener)
try:
while True:
time.sleep(10)
except (KeyboardInterrupt, SystemExit):
client.logoff()
Output before fix
1 Success
2 {'ActionID': '1', 'EventList': 'start', 'Message': 'Channel status will follow'}
3 None
4 Event : Status -> {'Privilege': 'Call', 'Channel': 'SIP/100-00000011'}
Output after fix
1 Success
2 {'ActionID': '1', 'EventList': 'start', 'Message': 'Channel status will follow'}
3 None
Hello. It is right fix. Your response is handled within request "synchronously", it has been pulled out of the event queue, and event listener must not get it. Here is my output after fix.
tests/integration/test_eventlist.py
1 Success
2 {'ActionID': '1', 'EventList': 'start', 'Message': 'Channel status will follow'}
3 ['', 'Event: Status', 'Privilege: Call', 'Channel: SIP/3030-00000000', 'ChannelState: 4', 'ChannelStateDesc: Ring', 'CallerIDNum: 3030', 'CallerIDName: 3030', 'ConnectedLineNum: <unknown>', 'ConnectedLineName: <unknown>', 'Accountcode: ', 'Context: from-users', 'Exten: 2020', 'Priority: 1', 'Uniqueid: 1544125642.0', 'Type: SIP', 'DNID: 2020', 'EffectiveConnectedLineNum: <unknown>', 'EffectiveConnectedLineName: <unknown>', 'TimeToHangup: 0', 'BridgeID: ', 'Linkedid: 1544125642.0', 'Application: (null)', 'Data: (null)', 'Nativeformats: (ulaw)', 'Readformat: ulaw', 'Readtrans: ', 'Writeformat: ulaw', 'Writetrans: ', 'Callgroup: 0', 'Pickupgroup: 0', 'Seconds: 0', 'ActionID: 1', '', 'Event: StatusComplete', 'ActionID: 1', 'EventList: Complete', 'ListItems: 1', 'Items: 1', '']
Process finished with exit code 0
I do not think that handling event list via callback is the right choice. It detaches output and to get response you need a lot supplementary things to do such as resolving resquest/response ID, sending data to reqesting process, etc...
Usualy, event lists are produced on bsic response without exact query e.g. "status', "queuestatus"
Thank you.
I do not think that handling event list via callback is the right choice. It detaches output and to get response you need a lot supplementary things to do such as resolving resquest/response ID, sending data to reqesting process, etc...
@soloma83 Yeah, but how can i listen all events and send some action with response if some conditions is matches for me from events?
Yeah, but how can i listen all events and send some action with response if some conditions is matches for me from events?
@romkazor It won't break events listening. This patch added handling for actions reqponses It is triggered by sequence Response: Success EventList: start Regular events do not satisfy this statement.
Thank you.
@soloma83 I finally found whats wrong! Your fix works, but regex for asterisk_end_list_regex will be:
re.compile(b'EventList: Complete\r\n, re.IGNORECASE | re.MULTILINE)
It works on asterisk 13+
Thank you.
Having EventList work correctly is essential. I wanted to use python-ami to get the list of PJSIP outbound registrations, but I find it really difficult and, from my experience, "OutboundRegistrationDetail" events are often not catched. I guess it is related to bug #26 and this PR tries to solve it. What is the problem with this PR?
Hello @alexis-via There is a lot of time that I'm not working with the asterisk, so I have no environment to test it at the moment. @romkazor suggested a fix for this PR, that makes sense for me, but I don't have an answer from @soloma83
Do you know if this PR fixes your issue? Or is it necessary to change what was suggested?
After more investigation on my code and reading the bug report again, my current conclusion is that there is no bug. The problem I had is that I was doing send_action() and then add_event_listener() to get the result via the EventList. To make it work correctly 100% of the time, you must do the add_event_listener() first and then call send_action().
My code is now the following (I post it here because I think it can help others). It works with Asterisk 18.6.0:
#! /usr/bin/python3
from asterisk.ami import AMIClient, SimpleAction, EventListener
import time
def event_listener(event, **kwargs):
print('START EVENT')
if event.keys.get('Status') and event.keys.get('ServerUri'):
status = event.keys['Status']
server = event.keys['ServerUri']
if status != 'Registered':
print('%s NOT REGISTERED' % server)
else:
print('%s REGISTRATION OK' % server)
print('END EVENT')
client = AMIClient(address='127.0.0.1', port=5038)
client.login(username='my_login', secret='xxxx')
client.add_event_listener(event_listener, white_list=['OutboundRegistrationDetail'])
action = SimpleAction('PJSIPShowRegistrationsOutbound')
future = client.send_action(action)
print('START SLEEP')
time.sleep(3) # sleep 3 sec to receive all the events
client.logoff()
And, so far, this code works well with the last release, no need for the patch proposed in this PR.
I'm sorry.I had missed this conversation. But I remember that case. I found the same solution as proposed by @romkazor it was working fine.
Thank you, Kirilll
On Tue, Nov 23, 2021 at 11:12 PM Alexis de Lattre @.***> wrote:
After more investigation on my code and reading the bug report again, my current conclusion is that there is not bug. The problem I had is that I was doing send_action() and then add_event_listener() to get the result via the EventList. To make it work correctly 100% of the time, you must do the add_event_listener() first and then call send_action().
My code is now the following (I post it here because I think it can help others). It works with Asterisk 18.6.0:
#! /usr/bin/python3
from asterisk.ami import AMIClient, SimpleAction, EventListener import time
def event_listener(event, **kwargs): print('START EVENT') if event.keys.get('Status') and event.keys.get('ServerUri'): status = event.keys['Status'] server = event.keys['ServerUri'] if status != 'Registered': print('%s NOT REGISTERED' % server) else: print('%s REGISTRATION OK' % server) print('END EVENT')
client = AMIClient(address='127.0.0.1', port=5038) client.login(username='my_login', secret='xxxx') client.add_event_listener(event_listener, white_list=['OutboundRegistrationDetail']) action = SimpleAction('PJSIPShowRegistrationsOutbound') future = client.send_action(action) print('START SLEEP') time.sleep(3) # sleep 3 sec to receive all the events client.logoff()
And, so far, this code works well with the last release, no need for the patch proposed in this PR.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ettoreleandrotognoli/python-ami/pull/27#issuecomment-977037985, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADBOSAKHO5RETCAZFGEWZQ3UNPRQTANCNFSM4GGOSJ6A . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
@ettoreleandrotognoli Maybe we could write an example of such a code at the end of the README of the projet... what do you think ?