4

ちょっとした文脈:認証の問題を解決した後、ここでこの質問が発生しました。元の問題に関係のないコメントで以前の問題を汚染するのを避け、適切な可視性を与えるために、新しい問題を開くことを好みます。

インターネットにアクセスせずに、サーバーと同じイントラネットで実行されている SOAP クライアントで作業しています。

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 には、イントラネットの外部にある外部リソースへのインポート ('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()
4

2 に答える 2

3

tranport クラスの独自のサブクラスを作成し、load() メソッドに追加のロジックを追加して、特定の URL がファイルシステムからリダイレクト/ロードされるようにすることができます。

コードはかなり簡単だと思います: https://github.com/mvantellingen/python-zeep/blob/master/src/zeep/transports.py :-)

于 2016-10-27T08:58:30.710 に答える