ettoreleandrotognoli / python-ami Goto Github PK
View Code? Open in Web Editor NEWPython AMI Client
License: BSD 3-Clause "New" or "Revised" License
Python AMI Client
License: BSD 3-Clause "New" or "Revised" License
module 're' has no attribute '_pattern_type'
Conforme informado no site, estou abrindo um issue para o meu problema.
Tenho duas funções que atualizam de 5 em 5 segundos, uma atualiza as ligações para o agente e a outra atualiza as filas do agente, estou criando um modulo de agente no asterisk, geralmente tenho esse erro ao enviar a ACTION, trava o servidor e no log printa uma mensagem "None" que só retorna após reiniciar o servidor porém ao reinicia-lo as requisições ficam na fila e ao enviar as requisições atrasadas da fila as vezes ele dá esse erro de novo as vezes não, monitoro com base em meus print's no código e os erros no arquivo log porém não aparece nada neles por isso criei os PRINT's, ambas as funções são chamadas por AJAX e o retorno eu monto um JSON para apresentar na tela.
Obs: A lib foi instalada com o pip porém creio que seja a versão mais atual.
Segue as duas funções abaixo:
def atualizaAgentQueue():
print 'Processando...'
print 'Obtendo nome do agente'
member = 'Comercial'
print 'Logando no servidor'
client = AMIClient(address='x.x.x.x',port=5038)
login = client.login(username='username,secret='userpass')
print login.response
#verificando se login obteve erro
if login.response.is_error():
raise Exception(str(login.response))
adapter = AMIClientAdapter(client)
end = threading.Event()
agents = []
params = []
# recebe os eventos de PeerEntry
def add_agent_listener(event, **kwargs):
agents.append(event)
# recebe os eventos
def add_params_listener(event, **kwargs):
params.append(event)
# recebe o evento
def end_agent_listener(event, **kwargs):
end.set()
actionId = uuid.uuid1().hex
add_listener = client.add_event_listener(on_QueueMember=add_agent_listener, ActionID=actionId)
add_listener2 = client.add_event_listener(on_QueueParams=add_params_listener, ActionID=actionId)
end_listener = client.add_event_listener(on_QueueStatusComplete=end_agent_listener, ActionID=actionId)
print 'Ativando Action'
#filtro membro por fila
future = adapter.QueueStatus(Member=member,ActionID=actionId)
print future.response
# aguarda o PeerlistComplete
end.wait()
client.remove_event_listener(add_listener)
client.remove_event_listener(add_listener2)
client.remove_event_listener(end_listener)
fila = '{"fila":['
for agent in agents:
for param in params:
if param['Queue'] == agent['Queue']:
fila +='{"Queue":'+param['Queue']
fila +=',"Abandoned":'+param['Abandoned']
fila +=',"Wait":'+param['Calls']
fila +=',"Holdtime":'+param['Holdtime']+'},'
fila += ']}'
fila = json.dumps(fila).replace("'",'"').replace(",]","]")
fila = json.loads(fila)
print("Finalizando Thread ...")
end.clear()
print 'Processo Finalizado'
client.logoff()
return response.json(fila)
def atualizaAgentCall():
print 'Processando...'
ramal = 1016
print 'Recebendo parametros'
print 'Logando no servidor'
client = AMIClient(address='x.x.x.x',port=5038)
login = client.login(username='username,secret='userpass')
adapter = AMIClientAdapter(client)
end = threading.Event()
calls = []
# recebe os eventos de PeerEntry
def add_call_listener(event, **kwargs):
calls.append(event)
# recebe o evento de PeerlistComplete
def end_call_listener(event, **kwargs):
end.set()
actionId = uuid.uuid1().hex
add_listener = client.add_event_listener(on_CoreShowChannel=add_call_listener, ActionID=actionId)
end_listener = client.add_event_listener(on_CoreShowChannelsComplete=end_call_listener, ActionID=actionId)
print 'Chamando action'
#filtro membro por fila
future = adapter.CoreShowChannels(ActionID=actionId)
print future.response
# aguarda o PeerlistComplete
end.wait()
client.remove_event_listener(add_listener)
client.remove_event_listener(end_listener)
print 'Atribuindo e filtrando ligações'
fila = '{'
for call in calls:
print call
if ramal == call['CallerIDNum'] :
fila += '"canal":' +'"'+ call['Channel'] +'"'+','
fila += '"numero":' +'"'+ call['ConnectedLineNum'] +'"'+','
fila += '"duracao":' +'"'+ call['Duration'] +'"'
fila += '}'
fila = json.dumps(fila).replace("'",'"').replace(",]","]")
fila = json.loads(fila)
print("Finalizando Thread ...")
end.clear()
print 'Processo Finalizado.'
client.logoff()
return response.json(fila)
Error:
./event.py
Traceback (most recent call last):
File "./event.py", line 18, in <module>
event_listener, white_list=['Registry','PeerStatus']
File "/usr/local/lib/python3.7/site-packages/asterisk/ami/client.py", line 241, in add_event_listener
event_listener = EventListener(on_event=on_event, **kwargs)
File "/usr/local/lib/python3.7/site-packages/asterisk/ami/event.py", line 89, in __init__
self.white_list = [white_list] if isinstance(white_list, (basestring, re._pattern_type)) else white_list
AttributeError: module 're' has no attribute '_pattern_type'
Source code:
#!/usr/local/bin/python3
import os
import time
from settings import login, connection
from asterisk.ami import AMIClient
def event_listener(event,**kwargs):
print(event)
client = AMIClient(**connection)
future = client.login(**login)
if future.response.is_error():
raise Exception(str(future.response))
client.add_event_listener(
event_listener, white_list=['Registry','PeerStatus']
)
try:
while True:
time.sleep(10)
except (KeyboardInterrupt, SystemExit):
client.logoff()
/usr/local/bin/python3 -V
Python 3.7.3
/usr/local/bin/python3 /usr/bin/pip show asterisk-ami
Name: asterisk-ami
Version: 0.1.5
Summary: Python AMI Client
Home-page: https://github.com/ettoreleandrotognoli/python-ami/
Author: Éttore Leandro Tognoli
Author-email: [email protected]
License: BSD
Location: /usr/local/lib/python3.7/site-packages
Requires:
Required-by:
Looks like _pattern_type was removed in 3.7. here's what it is in 3.6 https://github.com/python/cpython/blob/3.6/Lib/re.py#L283
Olá, Parabéns pela Lib,
Eu to com um problema, não acho que seja a sua lib, mas se puder me dar um rumo eu seria grato.
No meu código abaixo o return da função me retorna:
<asterisk.ami.event.EventListener object at 0x7f0e54134c90>
queria acessar a informação em si para enviar para outra ação
from asterisk.ami import SimpleAction, AMIClient
client = AMIClient(address='192.168.1.204', port=5038)
client.login(username='user', secret='senha')
sip_peers = SimpleAction('SIPpeers')
client.send_action(sip_peers)
def ev_peers(event, **kwargs):
t = (event['Channeltype']+'/'+event['ObjectName'])
print (t)
return t
i = client.add_event_listener(ev_peers,
white_list='PeerEntry', IPaddress='iptronco')
print(i)
Primeiro Print: SIP/TRK_NUMERO
Segundo: <asterisk.ami.event.EventListener object at 0x7f3214785cd0>
Dear Author,
I would like to thanks your wonderful library, I doing small project with python2.7 combine asterisk-ami 0.1.5. I can see the even but can not use it like List can you help me
for example:
1- print(event) >>> Event : Newexten -> {u'Context': u'ext-did', u'Priority': u'9', u'Func': u'pbx_extension_helper', u'SequenceNumber': u'14026', u'Uniqueid': u'1508071217.86', u'Extension': u's', u'Application': u'Goto', u'File': u'pbx.c', u'Privilege': u'dialplan,all', u'Line': u'4738', u'AppData': u'ext-queues,9002,1', u'Channel': u'SIP/0979960842-00000056'}
2- print list >>> [<asterisk.ami.event.Event object at 0x00000000028F86A0>]
Thanks a lot
Verify python 3 compatibility
str, unicode... refactoring could have broken something like the sockets
Amigo, estou usando sua lib. Quando tenho muitos eventos reparo que ela desconecta do ami, mas não me retorna nenhum exception no uso dos filtros etc.
I spend 8 hours finding why my python script simple_event_notification.py from example did not work.
Spoiler: It is disconnected on time out because the test asterisk does not send any event.
I firewalled it from remote unneeded activity.
I suggest setting it to a bigger value.
Hello, how about to add option of secure connection to AMIClient?!
I see a successful connection in the asterisk console but no events are printed to the screen. There are also no errors. I have the same problem in other scripts which are similar.
Python 3.4.2
Asterisk 14.6.2
Hello 0/
My problem like Issue #3, but other error: on console I received error
utf-8' codec can't decode byte 0xd1 in position 146: invalid continuation byte
The fact is that my db contains values in latin-1 encoding.
I found the problem here. Yet I solved the problem so
# yield pack.decode('utf-8')
yield pack.decode('latin-1')
As a solution to propose to establish the value of the encoding parameter, which could be given when creating an instance AMIClient or do something like
try:
yield pack.decode('utf-8')
except UnicodeDecodeError:
yield pack.decode('latin-1')
Example of part byte received from asterisk:
b'CallerIDName: \xc2\xe8\xf2\xe0\xeb\xe8\xe9 \xca\xe0\xeb\xe8\xed\xe8\xed'
Action: UpdateConfig
ActionID:
SrcFilename:
DstFilename:
Reload:
PreserveEffectiveContext:
Action-000000:
Cat-000000:
Var-000000:
Value-000000:
Match-000000:
Line-000000:
Options-000000:
action = SimpleAction('UpdateConfig',
reload='yes',
dstfilename='test.conf',
srcfilename='test.conf',
Action-000000='NewCat',
Cat-000000='test',
Var-000000='foo',
Value-000000='bar')
SyntaxError: expression cannot contain assignment, perhaps you meant "=="?
Hey. Faced a problem. When a session fails, it often does not work through reconnection. The try_reconnect method goes into an infinite loop and always throws a BrokenPipeError exception: [Errno 32] Broken pipe
client = AMIClient(address=config.ami_host, port=config.ami_port,timeout=2)
AutoReconnect(ami_client=client,delay=1)
future = client.login(username=config.ami_user,secret=config.ami_pass)
client.add_event_listener(
"""
add listeners
"""
)
if future.response.is_error():
raise Exception(str(future.response))
try:
while True:
time.sleep(5)
except (KeyboardInterrupt, SystemExit):
client.logoff()
im having a recurring disconnection problem with ami action when i use muteaudio
Task exception was never retrieved
future: <Task finished name='Task-481' coro=<AsyncServer._handle_event_internal() done, defined at /usr/local/lib/python3.8/dist-packages/socketio/asyncio_server.py:522> exception=IndexError('list index out of range')>
Traceback (most recent call last):
File "/usr/local/lib/python3.8/dist-packages/socketio/asyncio_server.py", line 524, in _handle_event_internal
r = await server._trigger_event(data[0], namespace, sid, *data[1:])
File "/usr/local/lib/python3.8/dist-packages/socketio/asyncio_server.py", line 558, in _trigger_event
ret = await handler(*args)
File "main_v2.py", line 155, in click
pabx.para_intercom_bg()
File "/home/asterisk/apiinter/classes/pabxmanager.py", line 281, in para_intercom_bg
retorno = ret.split("Local/s@chegou"+str(ramal)+"-")[1]
IndexError: list index out of range
Desmutou saida de audio pro 11 None
CLICK SOCKET {'ramal': '12', 'token': 'T*$jA@f8HDpWZeqmBBdgvhN_z'}
atendimento
set intercomstatus true e muda pra fora
Toca intercom BG
---------ERRO---------
<class 'ConnectionResetError'> pabxmanager.py 144
-
[Errno 104] Connection reset by peer
Logme: 2023-10-16 19:43:08 -> erro: [Errno 104] Connection reset by peer, kwargs: <class 'ConnectionResetError'>, pabxmanager.py, 144
please some one can help me? or some one knows the same commando directly in asterisk Cli ?
Hi,
I'm having an issue while waiting for events. I'm trying to continuously listen for incoming events and do something based on the event. It seems like i'm doing something wrong since the logs show up nothing.
Could you please help?
`class AmiConnect(Thread):
amiClient = None
lock = RLock()
def __init__(self):
Thread.__init__(self)
# self.setStatus(SERVICE_STARTED)
self.connectToAmi()
def connectToAmi(self):
try:
self.amiClient = AMIClient(address='5.2.196.226',port=5038)
self.amiClient.login(username='admin',secret='Rapid2017')
self.amiClient.add_event_listener(RegistryEventListener())
self.amiClient.add_event_listener(AllEventListener())
logging.info('Connected');
except Exception as e:
logging.info(e);
def setStatus(self, status):
self.lock.acquire()
self.status = status
self.lock.release()
def shutDown(self):
self.setStatus( SERVICE_STOPPING )
if name == 'main':
service = AmiConnect()
service.start()
try:
while (service is not None and service.isAlive() ):
service.join(1)
except KeyboardInterrupt as k:
logging.info("Keyboard interruption!")
service.shutDown()`
The ping function in the AutoReconnect
is always returning None
, which makes it reconnect while the connection is working and is sending succesful actions.
I also tried a Ping
action outside the AutoReconnect
which is working just fine.
Is there a easy fix for this?
Hi,
First, thank you for this awesome library ;)
I'm developing a small app witch is working very well with this lib. But I have a problem when I need to Originate a call from a extension (6426) to another extension (6422) for example, both of them with a fisical terminal. If I use this code:
from asterisk.ami import AMIClient
from asterisk.ami import SimpleAction
client =AMIClient(address = 'SERVERIP', port=PORTNUMBER)
client.login(username = 'USER', secret = 'PASSWD')
action = SimpleAction(
'Originate',
Channel='SIP/4123216082108749',
Exten='6422',
Priority=1,
Context='default',
CallerID='python',
)
future = client.send_action(action)
response = future.response
print(response)
When I run this code the terminal (channel) start ringing, and if I answer the call is finished with this result:
Response: Success
ActionID: 1
Message: Originate successfully queued
What i need it to make a call from this channel to the another terminal with has the extension 6422. How to achieve that? I installed fop2 (https://www.fop2.com/) I they have implemented this: first original terminal rings and when you hang up it start ringing to the destination. When destinarion terminal hangups, they can start speaking.
Is there any way to do that with yout library?
Thanks in advance
#!/usr/bin/python
import os
import time
from asterisk.ami import AMIClient
from asterisk.ami import EventListener
def event_listener(event,**kwargs):
print(event)
client = AMIClient(address='127.0.0.1',port=5038)
future = client.login(username='astmanager',secret='Xn75CFbVfjRg71v')
if future.response.is_error():
raise Exception(str(future.response))
client.add_event_listener(event_listener)
try:
while True:
time.sleep(10)
except (KeyboardInterrupt, SystemExit):
client.logoff()
this code is running without error but shows no even on the terminal when I run it
client.login(username='username',secret='password')
what is username and secret?
I was unable to import SimpleAction until I added a reference to it on line 6 of client.py.
Hi,
I Need new version with Python3.7 compatibility,
I saw that you already pushed a fix with Python3.7 compatibility.
Could you please release a new version including the Python3.7 compatibility?
Thanks.
Hello! I am still learning python, but I ran
pip install asterisk-ami
and tried the code in the README.md page, but I still get
File "/home/scuba323/lulpy/asterisk.py", line 8, in <module> from asterisk.ami import AMIClient ImportError: No module named ami
My code:
from asterisk.ami import AMIClient
from asterisk.ami import SimpleAction
client = AMIClient(address='127.0.0.1',port=5038)
client.login(username='username',secret='password')
def event_listener(event,**kwargs):
print(event)
client.add_event_listener(event_listener, white_list=['EndpointDetail'])
action = SimpleAction(
'PJSIPShowEndpoint',
Endpoint='test'
)
res = client.send_action(action).response
print(event)
How to access the response at print(event)
? I want to access the returned data in the main thread.
with the demo , run it but response this error :
File "D:\Python\Python37\lib\site-packages\asterisk\ami\event.py", line 89, in init
self.white_list = [white_list] if isinstance(white_list, (basestring, re._pattern_type)) else white_list
AttributeError: module 're' has no attribute '_pattern_type'
my code is :
#!/usr/bin/python
from asterisk.ami import AMIClient
from asterisk.ami import SimpleAction
from asterisk.ami import AMIClientAdapter
from asterisk.ami import EventListener
def eventNotification(source,event):
print("notify-send %s %s",event.name,str(event))
def callbackResponse(response):
print("in the callback")
print(response)
client = AMIClient(address='127.0.0.1',port=5038)
client.login(username='manageTest',secret='managePassword1')
client.add_event_listener(EventListener(on_event=eventNotification))
try:
while True:
time.sleep(10)
except (KeyboardInterrupt, SystemExit):
client.logoff()
client.login
timeout
if client address is not reachable, the login function blocks for long time
Hello, can you help me me passing multiple variables to originate?
I have tried multiple ways without sucess:
adapter.Originate(
Channel='SIP/' + destination,
Async='True',
Context='demo-menu',
Extension='s',
Variable='destination=dest-message=mensagem'
in this case the variable destinations is set with the value "dest-message=mensagem" the same happens if I use |
adapter.Originate( Channel='SIP/' + destination, Async='True', Context='demo-menu', Extension='s', Variable='message=' + message, Variable='destination=' + destination )
in this case python gives error because of duplicated key (Variable)
what should I do? Thanks.
If use response.is_error, then the first event FullyBooted after login doesn't work.
client = AMIClient(**connection)
future = client.login(**login)
if future.response.is_error():
raise Exception(str(future.response))
hi, in the telenet I successfully get the queue state, the same thing in python comes empty. what's wrong?
client = AMIClient(address='чччччч',port=5038) client.login(username='python',secret='5bdadc4820df193691d5848b8cb566de') action = SimpleAction( 'QueueStatus',) resp1=client.send_action(action) response3 = resp1.response print(response3)
Hello.
Unfortunately, AMIClient dispatches responses and events incorrectly.
There are a few types of responses which is marked as EventList. These responses contain a several elements divided by '\r\n\r\n'. As soon, AMIClient wait for this separator to finish pack it cannot catch these types of response.
For example, Action: Status. This action might respond with list of active channels.
Action: Status
Response: Success
EventList: start
Message: Channel status will followEvent: Status
Privilege: Call
Channel: SIP/3030-00000002
ChannelState: 6
ChannelStateDesc: Up
CallerIDNum: 3030
CallerIDName: 3030
ConnectedLineNum:
ConnectedLineName:
Accountcode:
Context: exten-voicemail-sub
Exten: s
Priority: 5
Uniqueid: 1542489290.45
Type: SIP
DNID: 2020
EffectiveConnectedLineNum:
EffectiveConnectedLineName:
TimeToHangup: 0
BridgeID:
Linkedid: 1542489290.45
Application: VoiceMail
Data: 3030@default,b
Nativeformats: (ulaw)
Readformat: ulaw
Readtrans:
Writeformat: ulaw
Writetrans:
Callgroup: 0
Pickupgroup: 0
Seconds: 285Event: StatusComplete
EventList: Complete
ListItems: 1
Items: 1
But AMIClient passes only first element.
def fire_recv_pack(self, pack):
print("Received pack: \n{}\n\n".format(pack))
if Response.match(pack):
response = Response.read(pack)
self.fire_recv_reponse(response)
return
if Event.match(pack):
event = Event.read(pack)
self.fire_recv_event(event)
return
self._fire_on_unknown(pack=pack)
Output is
Received pack:
Response: Success
ActionID: 1
EventList: start
Message: Channel status will followReceived pack:
Event: StatusComplete
ActionID: 1
EventList: Complete
ListItems: 0
Items: 0
The event listener does not always work,
It will always stop logging, and, after a call, the event logger will always stop logging and calling back.
Hello, in some early version of asterisk ChanVariable looks a little differently, and event parser show only last ChanVariable (only CDR(dst)=102). In later version of asterisk event parser show dict of ChanVariable. How can I fix this?
Asterisk 11 (bug)
Event: Hangup
...
ChanVariable(Local/101@from-internal-00000023;1): CDR(dcontext)=from-internal
ChanVariable(Local/101@from-internal-00000023;1): CDR(dst)=101
ChanVariable(Local/102@from-internal-00000023;2): CDR(dcontext)=from-internal
ChanVariable(Local/102@from-internal-00000023;2): CDR(dst)=102
Asterisk 12+ (ok)
Event: Hangup
...
ChanVariable: CDR(dcontext)=from-internal
ChanVariable: CDR(dst)=101
DestChanVariable: CDR(dcontext)=from-internal
DestChanVariable: CDR(dst)=102
Hi
when asterisk server goes off and on again i must restart event listener because event listener do not get events any more until stop and start it again .
1- how can i debug it ?
2- how can i solve this problem ?!
Hello
If set up event listener, some time, on console received error
'utf-8' codec can't decode byte 0xd0 in position 1023: unexpected end of data
and listener stop working
I try find why and find that it came from here -> here
Example of byte received from asterisk:
b'Local/+38097XXXXXXX@corp-00000014;2\r\nContext: macro-out_roundrobin_gateway\r\nExtension: s\r\nPriority: 2\r\nApplication: Set\r\nAppData: GO_COUNT=0\r\nUniqueid: 1479133224.1443\r\n\r\nEvent: VarSet\r\nPrivilege: dialplan,all\r\nTimestamp: 1479133224.599046\r\nChannel: Local/+38097XXXXXXX@corp-00000014;2\r\nVariable: GO_COUNT\r\nValue: 0\r\nUniqueid: 1479133224.1443\r\n\r\nEvent: VarSet\r\nPrivilege: dialplan,all\r\nTimestamp: 1479133224.599134\r\nChannel: Local/+38097XXXXXXX@corp-00000014;2\r\nVariable: MACRO_DEPTH\r\nValue: 1\r\nUniqueid: 1479133224.1443\r\n\r\nEvent: VarSet\r\nPrivilege: dialplan,all\r\nTimestamp: 1479133224.599360\r\nChannel: Local/+38097XXXXXXX@corp-00000014;2\r\nVariable: DB_RESULT\r\nValue: 2\r\nUniqueid: 1479133224.1443\r\n\r\nEvent: Newexten\r\nPrivilege: dialplan,all\r\nTimestamp: 1479133224.599928\r\nChannel: Local/+38097XXXXXXX@corp-00000014;2\r\nContext: macro-out_roundrobin_gateway\r\nExtension: s\r\nPriority: 3\r\nApplication: NoOp\r\nAppData: -- \xd0\x93\xd0\xa0\xd0\xa3\xd0\x9f\xd0\x9f\xd0\x90 Kharkiv \xd0\xb1\xd1\x83\xd0\xb4\xd0\xb5\xd1\x82\xd1\x8c \xd0\xbf\xd1\x8b\xd1\x82\xd0\xb0\xd1\x82\xd1\x8c\xd1\x81\xd1\x8f \xd0\x97\xd0\x92\xd0\x9e\xd0\x9d\xd0\x98\xd0\xa2\xd0\xac \xd0\xbd\xd0\xb0 +38097XXXXXXX\xd1\x87\xd0\xb5\xd1\x80\xd0\xb5\xd0\xb7 LINEOUTKS \xd0\xbb\xd0'
Boa tarde. estou tentando dar um playback em uma extensão que esta ativa. mas ele so retorna None
action = SimpleAction(
'Originate',
Channel='SIP/12-0000002c',
Exten='12',
Application='Playback',
Data='/home/asterisk/apiinter/ativa.wav'
)
future = client.send_action(action)
response = future.response
print(response)
pode me ajudar ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.