具有Zeep的Python SOAP客户端-导入名称空间 [英] Python SOAP client with Zeep - import namespace

查看:141
本文介绍了具有Zeep的Python SOAP客户端-导入名称空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个小背景:在此之后,我在这里提出了这个问题.解决身份验证问题.我更喜欢打开一个新文件,以避免用与原始问题无关的评论来污染先前的文件,并为其提供适当的可见性.

我正在与服务器在同一Intranet中运行的SOAP客户端上工作,而没有Internet访问.

from requests.auth import HTTPBasicAuth
from zeep import Client
from zeep.transports import Transport

wsdl = 'http://mysite.dom/services/MyWebServices?WSDL'
client = Client(wsdl, transport=HTTPBasicAuth('user','pass'), cache=None)

问题:WSDL包含对位于Intranet外部的外部资源的导入('import namespace ="schemas.xmlsoap.org/soap/encoding/"'),因此Zeep客户端实例化失败并显示:

Exception: HTTPConnectionPool(host='schemas.xmlsoap.org', port=80): Max retries exceeded with url: /soap/encoding/ (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x7f3dab9d30b8>: Failed to establish a new connection: [Errno 110] Connection timed out',))

问题:是否有可能(而且有意义)创建Zeep客户端而无需访问外部资源?

作为一个额外的细节,基于XML rpc ServiceFactory的另一个用Java编写的客户端似乎对这种问题更具弹性,即使没有可用的互联网连接,该服务也会被创建(并且可以正常工作). 真的需要从xmlsoap.org导入名称空间吗?

在@mvt回答后

因此,我采用了建议的解决方案,该解决方案允许我同时控制对外部资源的访问(阅读:禁止访问与托管端点的服务器不同的服务器).

class MyTransport(zeep.Transport):
    def load(self, url):
        if not url:
            raise ValueError("No url given to load")
        parsed_url = urlparse(url)
        if parsed_url.scheme in ('http', 'https'):
            if parsed_url.netloc == "myserver.ext":
                response = self.session.get(url, timeout=self.load_timeout)
                response.raise_for_status()
                return response.content
            elif url == "http://schemas.xmlsoap.org/soap/encoding/":
                url = "/some/path/myfile.xsd"
            else:
                raise
        elif parsed_url.scheme == 'file':
            if url.startswith('file://'):
                url = url[7:]
        with open(os.path.expanduser(url), 'rb') as fh:
            return fh.read()

解决方案

您可以创建自己的tranport类的子类,并向load()方法添加其他逻辑,以便从文件系统重定向/加载特定的url./p>

我认为代码很容易: https://github.com/mvantellingen/python-zeep/blob/master/src/zeep/transports.py :-)

A little context: I am opening this question arose here, after solving an authentication problem. I prefer to open a new one to avoid polluting the previous with comments not related to the original issue, and to give it the proper visibility.

I am working on a SOAP client running in the same intranet as the server, without internet access.

from requests.auth import HTTPBasicAuth
from zeep import Client
from zeep.transports import Transport

wsdl = 'http://mysite.dom/services/MyWebServices?WSDL'
client = Client(wsdl, transport=HTTPBasicAuth('user','pass'), cache=None)

The problem: WSDL contains an import to an external resource located outside the intranet ('import namespace="schemas.xmlsoap.org/soap/encoding/"') and therefore Zeep Client instantiation fails with:

Exception: HTTPConnectionPool(host='schemas.xmlsoap.org', port=80): Max retries exceeded with url: /soap/encoding/ (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x7f3dab9d30b8>: Failed to establish a new connection: [Errno 110] Connection timed out',))

Question: is it possible (and does it make sense) to create the Zeep Client without accessing the external resource?

As an additional detail, another client written in Java, based on XML rpc ServiceFactory seems to be more resilient to this kind of problem, the service is created (and works) even if no internet connection is available. Is it really needed to import the namespace from xmlsoap.org?

Edit, after answer from @mvt:

So, I went for the proposed solution, which allows me at the same time to control the access to external resources (read: forbid access to servers different from the one hosting the endpoint).

class MyTransport(zeep.Transport):
    def load(self, url):
        if not url:
            raise ValueError("No url given to load")
        parsed_url = urlparse(url)
        if parsed_url.scheme in ('http', 'https'):
            if parsed_url.netloc == "myserver.ext":
                response = self.session.get(url, timeout=self.load_timeout)
                response.raise_for_status()
                return response.content
            elif url == "http://schemas.xmlsoap.org/soap/encoding/":
                url = "/some/path/myfile.xsd"
            else:
                raise
        elif parsed_url.scheme == 'file':
            if url.startswith('file://'):
                url = url[7:]
        with open(os.path.expanduser(url), 'rb') as fh:
            return fh.read()

解决方案

You could create your own subclass of the tranport class and add additional logic to the load() method so that specific url's are redirected / loaded from the filesystem.

The code is pretty easy i think: https://github.com/mvantellingen/python-zeep/blob/master/src/zeep/transports.py :-)

这篇关于具有Zeep的Python SOAP客户端-导入名称空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆