如何访问Zeep插件类中函数内的http_headers变量?
问题描述
我使用Zeep发起SOAP调用,通过插件处理响应头。定义的ResponseHeader类作为插件传入Client后,执行resp = service.listChange()时会打印响应头,但我需要直接获取ingress方法中的http_headers变量,而非仅打印。尝试在类外部定义http_headers未果,相关代码如下:
class ResponseHeader( Plugin ): def ingress( self, envelope, http_headers, operation ): print( f'\nResponse\n-------\nHeaders:\n{http_headers}\n' ) session = Session() session.verify = False urllib3.disable_warnings( urllib3.exceptions.InsecureRequestWarning ) session.auth = HTTPBasicAuth(username, password) transport = Transport( session = session, timeout = 10 ) settings = Settings(xml_huge_tree = True ) plugin = [ ResponseHeader() ] if DEBUG else [] client = Client( WSDL_FILE, settings = settings, transport = transport, plugins = plugin ) service = client.create_service( '{http://www.cisco.com/AXLAPIService/}AXLAPIBinding', 'https://server:8443/axl/' ) try: resp = service.listChange() header = ResponseHeader() print(header) except Exception as err: logging.error( f'\nZeep error: initial listChange: { err }' ) sys.exit( 1 )
我也曾尝试在类外部定义http_headers,但同样无效。
解决方案
要获取http_headers,核心是让插件实例自行存储响应头数据,后续直接从该实例读取即可,具体修改如下:
- 修改
ResponseHeader类,添加属性存储响应头:
class ResponseHeader(Plugin): def __init__(self): self.http_headers = None # 初始化用于存储响应头的属性 def ingress(self, envelope, http_headers, operation): self.http_headers = http_headers # 将响应头赋值给实例属性 print(f'\nResponse\n-------\nHeaders:\n{http_headers}\n')
- 保留插件实例的引用,确保和传入
Client的是同一个实例:
# 创建插件实例并保存引用 response_header_plugin = ResponseHeader() if DEBUG else None plugin = [response_header_plugin] if DEBUG else [] client = Client(WSDL_FILE, settings=settings, transport=transport, plugins=plugin)
- 调用接口后,从插件实例中读取响应头:
try: resp = service.listChange() if DEBUG and response_header_plugin: # 直接获取存储的响应头 print("获取到的响应头:", response_header_plugin.http_headers) # 此处可直接使用response_header_plugin.http_headers变量做后续处理 except Exception as err: logging.error(f'\nZeep error: initial listChange: { err }') sys.exit(1)
说明
之前的问题在于,你在调用接口后新建了ResponseHeader()实例,这个实例和传入Client的插件实例不是同一个,自然拿不到响应头数据。通过复用同一个插件实例,让它在ingress方法中保存响应头,就能在调用后直接读取。
内容的提问来源于stack exchange,提问作者Chad
相关产品推荐
相关产品推荐

