简体   繁体   中英

Twisted-AMP : an unexpected keyword argument

I am creating an Network monitoring tool using python (twisted amp), its basicaly an rpc system, where the client is installed on systems and they send data to the server. One of my function at the client side is giving this error

[Failure instance: Traceback: <type 'exceptions.TypeError'>: status_list() got an unexpected keyword argument 'Process_stat'

I have failed to understand what is triggering this error. Here is the whole error msg:

[Failure instance: Traceback: <type 'exceptions.TypeError'>: status_list() got an unexpected keyword argument 'Process_stat'
C:\Python27\lib\site-packages\twisted\internet\defer.py:368:callback
C:\Python27\lib\site-packages\twisted\internet\defer.py:464:_startRunCallbacks
C:\Python27\lib\site-packages\twisted\internet\defer.py:551:_runCallbacks
C:\Users\Abhishek\Desktop\amp_client.py:171:status_list
--- <exception caught here> ---
C:\Python27\lib\site-packages\twisted\protocols\amp.py:818:callRemote

Here is the client side code :

from twisted.internet import reactor
from twisted.internet.protocol import ClientCreator
from twisted.protocols import amp
import psutil
import datetime
import socket
import platform,sys,os
Network_Status=0
main_protocol =0 
My_Mac= "NULL"

class status_list(amp.Command):
    arguments = [('MAC', amp.String()),
            ('Process_stat', amp.String()),
            ('Disk_Stat', amp.String()),
            ('IP', amp.String())]

    response = [
            ('req_status', amp.Integer()),
            ('ALIGN_FUNCTION',amp.String()),
            ('ALIGN_Confirmation',amp.Integer()),
            ('Callback_offset',amp.Integer())]


class logging_group(amp.Command):
    arguments =[('MAC', amp.String()),
            ('EVENT_MSG', amp.String()),
            ('EVENT_TYPE', amp.Integer()),
            ('EVENT_DATETIME', amp.String())]

    response = [('req_status', amp.String()),
            ('ALIGN_FUNCTION', amp.String()),
            ('ALIGN_Confirmation', amp.Integer()),
            ('Callback_offset',amp.Integer())]

class register_procedure(amp.Command):
    arguments = [('MAC',amp.String()),
            ('IP',amp.String()),
            ('Computer_Name',amp.String()),
            ('OS',amp.String())]

    response = [('req_status', amp.String()),
            ('ALIGN_FUNCTION', amp.String()),
            ('ALIGN_Confirmation', amp.Integer()),
            ('Callback_offset',amp.Integer())]

def startup_register(protocol):
    global main_protocol
    global Network_Status
    Network_Status=1
    main_protocol=protocol
    return main_protocol.callRemote(register_procedure, MAC=getMacAddress(), IP=socket.gethostbyname(socket.gethostname()),
    Computer_Name=socket.gethostname(),OS=platform.system()
    ).addCallback(status_list).addErrback(error_group)

def error_group(reason):
    print reason
    reactor.stop()

def process_listing():
    proc_list=[]
    for proc in psutil.process_iter():
            proc_list.append(proc.name)
    print "::/::".join(proc_list)
    return "::/::".join(proc_list)

 def disk_space():
    disk_stat={}
    partition_stat={}
    a=0
    try:
            for partition in psutil.disk_partitions():
                    partition_stat["Partition"]=partition.device
                    partition_stat["File_system"]=partition.fstype
                    if partition.opts=='rw,fixed':
                            print partition
                            usage=psutil.disk_usage(partition.device)
                            num=usage.total
                            for x in ['bytes','KB','MB','GB','TB']:
                                    if num < 1024.0:
                                            partition_stat["total"]= "%3.1f %s" % (num, x)
                                            break
                                    num /= 1024.0
                            num=usage.used
                            for x in ['bytes','KB','MB','GB','TB']:
                                    if num < 1024.0:
                                            partition_stat["used"]= "%3.1f %s" % (num, x)
                                            break
                                    num /= 1024.0
                            num=usage.free
                            for x in ['bytes','KB','MB','GB','TB']:
                                    if num < 1024.0:
                                            partition_stat["free"]= "%3.1f %s" % (num, x)
                                            break
                                    num /= 1024.0
                            partition_stat["percentage"]=usage.percent
                    disk_stat[a]=partition_stat
                    a=a+1
    except:
            error_group("Could not update Hard Disk Statistics ")
            return "Could not update Hard Disk Statistics "
    return disk_stat        

def getMacAddress():
    print "status"
    global My_Mac
    if sys.platform == 'win32':
            for line in os.popen("ipconfig /all"):
                    print line
                    if line.lstrip().startswith('Physical Address'):
                            mac = line.split(':')[1].strip().replace('-',':')
                            next
                    if line.lstrip().startswith('IPv4 Address'):
                            ip_addr=socket.gethostbyname(socket.gethostname())
                            if ip_addr in line:
                                    My_Mac=mac
                                    return mac
    else:
            for line in os.popen("/sbin/ifconfig"):
                    print line
                    if line.find('Ether') > -1:
                            mac = line.split()[4]
                            break
    return mac


def Network_Err(reason):
    print reason
    global main_protocol
    global Network_Status
    Network_Status=0
    print "fime dome "
    datetime.datetime.now().strftime("%I:%M%p %B %d, %Y")
    #dt=datetime.datetime.now().strftime("%I:%M%p %B %d, %Y")
    #result=main_protocol.callRemote(logging_group, MAC=My_Mac,EVENT_MSG=reason,EVENT_TYPE=1,
    #                       EVENT_DATETIME=dt).addCallback(status_list).addErrback(Network_Err)
    #if result['ALIGN_FUNCTION']=="status_lsit":
     #       return main_protocol.callRemote(status_list, MAC=My_Mac,Process_stat=process_listing(),Disk_Stat=disk_space(),
      #      IP=socket.gethostbyname(socket.gethostname())).addCallback(status_list).addErrback(Network_Err)


def status_list(result):
    print result
    print "status"
    global Network_Status
    Network_Status=1

    if result['req_status']==0:
            if result['ALIGN_FUNCTION']=="none":
                    if result['Callback_offset']==0:
                            return main_protocol.callRemote(status_list, MAC=My_Mac,Process_stat=process_listing(),Disk_Stat=disk_space(),
                                    IP=socket.gethostbyname(socket.gethostname())).addCallback(status_list).addErrback(Network_Err)
                    else:
                            sleep(result['Callback_offset']-0.1)
                            return main_protocol.callRemote(status_list, MAC=My_Mac,Process_stat=process_listing(),Disk_Stat=disk_space(),
                                    IP=socket.gethostbyname(socket.gethostname())).addCallback(status_list).addErrback(Network_Err)
            else:
                    #something has to be done to solve illegal looping
                    eval(result['ALIGN_FUNCTION'])
                    sleep(result['Callback_offset']-0.1)
                            #return status ?
    else :
                    #return status immediate untill rq_status not 0
            return main_protocol.callRemote(status_list, MAC=My_Mac,Process_stat=process_listing(),Disk_Stat=disk_space(),
                       IP=socket.gethostbyname(socket.gethostname())).addCallback(status_list).addErrback(Network_Err)

ClientCreator(reactor, amp.AMP).connectTCP(
'192.168.1.12', 3600).addCallback(startup_register).addErrback(Network_Err)

reactor.run()   

Here's the server side code :

from twisted.protocols import amp
from twisted.internet import reactor
from twisted.internet.protocol import Factory
import os
import sqlite3
root_dir=os.getcwd()
import datetime
import random
db_folder="""\\databases\\"""
if not os.path.exists(db_folder):
    os.makedirs(db_folder)  
reg_db=db_folder+"Device_list.db"
err_db=db_folder + "error_list.db"
cur_db=db_folder + "current_status.db"

conn_device = sqlite3.connect(reg_db,isolation_level=None)
cursor_device=conn_device.cursor()
conn_error_log = sqlite3.connect(err_db,isolation_level=None)
cusrsor_log=conn_error_log.cursor()
conn_current_status=sqlite3.connect(cur_db,isolation_level=None)
cursor_status=conn_current_status.cursor()


conn_device.execute("""CREATE TABLE devices (MAC varchar2 NOT NULL,IP varchar2                          ,Computer_name varchar2,OS varchar2,UNIQUE(MAC),PRIMARY KEY (MAC))""")

conn_error_log.execute("""CREATE TABLE errorLog (MAC varchar2 NOT NULL,EVENT_MSG varchar2 , EVENT_TYPE int,EVENT_DATETIME varchar2,UNIQUE(MAC),PRIMARY KEY (MAC))""")

conn_current_status.execute("""CREATE TABLE currStatus (MAC varchar2 NOT NULL,process_stat varchar2 , disk_stat varchar2,IP varchar2,UPdate_time datetime ,UNIQUE(MAC),PRIMARY KEY (MAC))""")


late_reg=bool('TRUE') 

def call_offset(priority):
if priority== 0:
    return 0
if priority == 1:
    return 10+random.randint(1,5)


class status_list(amp.Command):
arguments = [('MAC', amp.String()),
             ('Process_stat', amp.String()),
             ('Disk_Stat', amp.String()),
             ('IP', amp.String()),
             ('', amp.String())]

response = [('c_status', amp.Integer()),
            ('ALIGN_FUNCTION',amp.String()),
            ('ALIGN_Confirmation',amp.Integer()),
            ('Callback_offset',amp.Integer())]


class logging_group(amp.Command):
arguments =[('MAC', amp.String()),
             ('EVENT_MSG', amp.String()),
             ('EVENT_TYPE', amp.Integer()),
             ('EVENT_DATETIME', amp.DateTime())
            ]

response = [('req_status', amp.String()),
             ('ALIGN_FUNCTION', amp.String()),
             ('ALIGN_Confirmation', amp.Integer()),
             ('Callback_offset',amp.Integer())
            ]

class register_procedure(amp.Command):
arguments = [('MAC',amp.String()),
            ('IP',amp.String()),
            ('Computer_Name',amp.String()),
            ('OS',amp.String())
            ]
response = [('req_status', amp.String()),
             ('ALIGN_FUNCTION', amp.String()),
             ('ALIGN_Confirmation', amp.Integer()),
             ('Callback_offset',amp.Integer())
            ]

class Protocol(amp.AMP):
@status_list.responder
def status_list(self, MAC, Process_stat , Disk_Stat , IP ,):
    cursor_device.execute("""select * FROM devices where MAC = ?;""",[MAC])
    exists_val=cursor_device.fetchone()
    if exists_val ==0 and late_reg :
        register_group(MAC,IP,)
        return {'c_status': 3 ,'ALIGN_FUNCTION':'register','ALIGN_Confirmation':0,'Callback_offset':0}
    else:
        try :
            cursor_status.execute("""update currStatus set processStat= ? , diskStat= ? , sysIP = ? , UPdate_time = ? where MAC= ?;""",[Process_Stat,Disk_Stat,IP,datetime.datetime.now().strftime("%I:%M%p %B %d, %Y"),MAC])
            return {'c_status': 1 ,'ALIGN_FUNCTION':'none','ALIGN_Confirmation':0,'Callback_offset':Call_offset}
        except SQLException : 
            print "could not update database "

@logging_group.responder
def logging_group(self,MAC,EVENT_MSG,EVENT_TYPE,EVENT_DATETIME):
    cursor_device.execute("""IF EXISTS(select * FROM devices where MAC = ?);""",[(MAC)])
    exists_val=cursor_device.fetchone()
    if not exists_val and late_reg :
        register_group(MAC,IP,)
        return {'c_status': 3 ,'ALIGN_FUNCTION':'register','ALIGN_Confirmation':0,'Callback_offset':0}
    else:
        try :
            cusrsor_log.execute("""INSERT INTO errorLog(MAC,EventMsg ,EventType , EventDatetime) values (?,?,?);""",[MAC,EVENT_MSG,EVENT_TYPE,EVENT_DATETIME])
            return {'c_status': 1 ,'ALIGN_FUNCTION':'none','ALIGN_Confirmation':0,'Callback_offset':Call_offset}
        except SQLException : 
            print "could not update database "

@register_procedure.responder
def register_procedure(self,MAC,IP,Computer_Name,OS):
    cursor_device.execute("""select * FROM devices where MAC = ?;""",[(MAC)])
    exists_val=cursor_device.fetchone()
    cursor_device.fetchone()

    if not exists_val== "":
        cursor_device.execute("""update devices set IP= ? , Computer_name= ? , OS = ?  where MAC= ?;""",[IP,Computer_Name,OS,MAC])
        return {'req_status': "done" ,'ALIGN_FUNCTION':'none','ALIGN_Confirmation':0,'Callback_offset':call_offset(1)}
    else:
        cursor_device.execute("""INSERT INTO devices(Mac,Ip,Computer_name,Os) values (?,?,?,?);""",[MAC,IP,Computer_Name,OS])
        return {'req_status': "done" ,'ALIGN_FUNCTION':'main_loop()','ALIGN_Confirmation':0,'Callback_offset':0}

pf = Factory()
pf.protocol = Protocol
reactor.listenTCP(3600, pf) # listen on port 1234
reactor.run()      


def exit():
    conn_device.close()
    conn_error_log.close()
    conn_current_status.close()

i have traced the error to this line :

return main_protocol.callRemote(status_list, MAC=My_Mac,Process_stat=process_listing(),Disk_Stat=disk_space(),
                                    IP=socket.gethostbyname(socket.gethostname())).addCallback(status_list).addErrback(Network_Err)

Thanks in advance

The problem appears to be that your client code overwrites the name status_list ; using it first for the Command object, then for the function. Since callRemote calls its command argument with keywords, your function doesn't take those keywords and so you get an exception.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM