Twisted-AMP:意外的关键字参数

Posted

技术标签:

【中文标题】Twisted-AMP:意外的关键字参数【英文标题】:Twisted-AMP : an unexpected keyword argument 【发布时间】:2013-06-01 06:47:13 【问题描述】:

我正在使用 python (twisted amp) 创建一个网络监控工具,它基本上是一个 rpc 系统,客户端安装在系统上并将数据发送到服务器。我在客户端的一个功能是给出这个错误

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

我无法理解触发此错误的原因。 这是整个错误消息:

[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

这是客户端代码:

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()   

这是服务器端代码:

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()

我已将错误追溯到这一行:

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)

提前致谢

【问题讨论】:

请附上完整的、可运行的程序。这些 sn-ps 只允许某人猜测。 @Glyph 这是整个可运行程序。 【参考方案1】:

问题似乎是您的客户端代码覆盖了名称status_list;首先将它用于 Command 对象,然后用于函数。由于callRemote 使用关键字调用其命令参数,因此您的函数不会使用这些关键字,因此您会遇到异常。

【讨论】:

以上是关于Twisted-AMP:意外的关键字参数的主要内容,如果未能解决你的问题,请参考以下文章

为啥此 Django API 调用出现意外的关键字参数错误?

get() 得到了一个意外的关键字参数 'title'

Scikit 管道参数 - fit() 得到了一个意外的关键字参数“gamma”

fit() 得到了一个意外的关键字参数“标准”

IPython(jupyter)中的完成现在可以工作(意外的关键字参数'column')

动态表单抱怨“步数”作为意外的关键字参数