You never can tell with bees (dil) wrote in ru_python,
You never can tell with bees
dil
ru_python

WSDL в SUDS

По советам лучших собаководов попробовал использовать suds (0.4.1) вместо SOAPpy. Немедленно наткнулся на грабли с неопознанным типом string:
Traceback (most recent call last):
  File "skybox_api.py", line 43, in 
    client=Client(SKYBOX_SESSION_WSDL)
  File "/usr/lib/python2.7/dist-packages/suds/client.py", line 119, in __init__
    sd = ServiceDefinition(self.wsdl, s)
  File "/usr/lib/python2.7/dist-packages/suds/servicedefinition.py", line 57, in __init__
    self.addports()
  File "/usr/lib/python2.7/dist-packages/suds/servicedefinition.py", line 85, in addports
    method = (m.name, binding.param_defs(m))
  File "/usr/lib/python2.7/dist-packages/suds/bindings/rpc.py", line 39, in param_defs
    return self.bodypart_types(method)
  File "/usr/lib/python2.7/dist-packages/suds/bindings/binding.py", line 441, in bodypart_types
    raise TypeNotFound(query.ref)
suds.TypeNotFound: Type not found: '(string, http://schemas.xmlsoap.org/soap/encoding/, )'


Насколько я понимаю, ошибка вызвана использованием soapenc:string вместо обычного xsd:string в описаниях message'й. Этот soapenc ссылается на xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/". Если в локальном файле в definitions заменить у soapenc урл на xsd'шный - xmlns:soapenc="http://www.w3.org/2001/XMLSchema", то ошибка исчезает. Но хочется таки использовать не локальный файл, а wsdl с сервера, а там я ничего поменять не могу.

Гугление показало, что ошибка типичная, должна лечиться ручным присобачиванием location к namespace посредством suds.xsd.sxbasic.Import.bind(). Причём для этого конкретного namespace оно уже даже прибито гвоздиками в suds/xsd/sxbasic.py:
#######################################################
# Static Import Bindings :-(
#######################################################
Import.bind(
    'http://schemas.xmlsoap.org/soap/encoding/',
    'suds://schemas.xmlsoap.org/soap/encoding/')

но не работает ни автоматом, ни вручную.

Альтернативный нагуглённый способ - приделать suds.xsd.doctor.ImportDoctor к клиенту. Но попытка использовать в этом докторе imp = Import('http://schemas.xmlsoap.org/soap/encoding/', location='http://www.w3.org/2001/XMLSchema') приводит к таймауту, потому что прямой доступ из локалки закрыт, а переменную среды http_proxy оно игнорирует.
А если эту XMLSchema скачать вручную и подсунуть в location в виде локального файла, на выходе получаем дамп из 1200 строк, заканчивающийся сообщением RuntimeError: maximum recursion depth exceeded.

Как эту хрень победить?!

Если кто захочет поэкспериментировать, wsdl можно взять тут.


Update: кажется, удалось победить, вручную скачав http://schemas.xmlsoap.org/soap/encoding/ и подсунув его доктору из локального файла.
Но вопрос "Какого хрена эта якобы реализация SOAP не понимает стандартную SOAP'овскую схему?" остаётся открытым.
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments