2008-10-28 2 views
19

SUDS를 Python 용 SOAP 클라이언트로 조사하고 있습니다. 지정된 서비스에서 사용할 수있는 메서드와 지정된 메서드에서 필요로하는 형식을 검사하고 싶습니다.SUDS - 메서드 및 형식에 대한 프로그래밍 방식의 액세스

목표는 사용자 인터페이스를 생성하여 사용자가 메소드를 선택한 다음 동적으로 생성 된 양식으로 값을 채우는 것입니다.

나는 특정 방법에 대한 몇 가지 정보를 얻을 수 있지만, 구문 분석하는 방법을 확실하지 오전 수 : 오브젝트 유형 무엇

client = Client(url) 
method = client.sd.service.methods['MyMethod'] 

내가 생각없는 그림 밖으로 programmaticaly에 내가 전화를 할 수 있도록 만들 필요를 서비스

obj = client.factory.create('?') 

res = client.service.MyMethod(obj, soapheaders=authen) 

어떤 샘플 코드가 있습니까?

답변

18

sudsdocumentation에 따르면 service 개체를 __str()__으로 검사 할 수 있습니다.

from suds.client import Client; 

url = 'http://www.webservicex.net/WeatherForecast.asmx?WSDL' 
client = Client(url) 

temp = str(client); 

위의 결과 다음 생성하는 코드 (temp의 내용) : 그래서 다음은 방법과 복잡한 유형의 목록을 가져옵니다

Suds (https://fedorahosted.org/suds/) version: 0.3.4 (beta) build: R418-20081208 

Service (WeatherForecast) tns="http://www.webservicex.net" 
    Prefixes (1) 
     ns0 = "http://www.webservicex.net" 
    Ports (2): 
     (WeatherForecastSoap) 
     Methods (2): 
      GetWeatherByPlaceName(xs:string PlaceName,) 
      GetWeatherByZipCode(xs:string ZipCode,) 
     Types (3): 
      ArrayOfWeatherData 
      WeatherData 
      WeatherForecasts 
     (WeatherForecastSoap12) 
     Methods (2): 
      GetWeatherByPlaceName(xs:string PlaceName,) 
      GetWeatherByZipCode(xs:string ZipCode,) 
     Types (3): 
      ArrayOfWeatherData 
      WeatherData 
      WeatherForecasts 

이 구문 분석하기가 훨씬 쉬울 것입니다. 또한 모든 메서드는 매개 변수와 함께 해당 형식과 함께 나열됩니다. 아마도 정규 표현식을 사용하여 필요한 정보를 추출 할 수도 있습니다.

24

좋아요, 그래서 SUDS는 꽤 많은 마법을 나타냅니다. suds.client.Client

는 WSDL 파일에서 구축 :

client = suds.client.Client("http://mssoapinterop.org/asmx/simple.asmx?WSDL") 

그것은 WSDL을 다운로드하고 client.wsdl의 정의를 만듭니다. client.service.<method>을 통해 SUDS를 사용하여 메소드를 호출하면 실제로 해석 된 WSDL에 대해 많은 재귀 적 해결 마법을 수행하고 있습니다. 메소드의 매개 변수와 유형을 발견하려면이 객체를 인트로 스펙 트해야합니다. 이 같은 인쇄해야

for method in client.wsdl.services[0].ports[0].methods.values(): 
    print '%s(%s)' % (method.name, ', '.join('%s: %s' % (part.type, part.name) for part in method.soap.input.body.parts)) 

: 예를 들어

echoInteger((u'int', http://www.w3.org/2001/XMLSchema): inputInteger) 
echoFloatArray((u'ArrayOfFloat', http://soapinterop.org/): inputFloatArray) 
echoVoid() 
echoDecimal((u'decimal', http://www.w3.org/2001/XMLSchema): inputDecimal) 
echoStructArray((u'ArrayOfSOAPStruct', http://soapinterop.org/xsd): inputStructArray) 
echoIntegerArray((u'ArrayOfInt', http://soapinterop.org/): inputIntegerArray) 
echoBase64((u'base64Binary', http://www.w3.org/2001/XMLSchema): inputBase64) 
echoHexBinary((u'hexBinary', http://www.w3.org/2001/XMLSchema): inputHexBinary) 
echoBoolean((u'boolean', http://www.w3.org/2001/XMLSchema): inputBoolean) 
echoStringArray((u'ArrayOfString', http://soapinterop.org/): inputStringArray) 
echoStruct((u'SOAPStruct', http://soapinterop.org/xsd): inputStruct) 
echoDate((u'dateTime', http://www.w3.org/2001/XMLSchema): inputDate) 
echoFloat((u'float', http://www.w3.org/2001/XMLSchema): inputFloat) 
echoString((u'string', http://www.w3.org/2001/XMLSchema): inputString) 

그래서 부분의 형태 튜플의 첫 번째 요소는 당신이있어 무엇을 아마 후 :

>>> client.factory.create(u'ArrayOfInt') 
(ArrayOfInt){ 
    _arrayType = "" 
    _offset = "" 
    _id = "" 
    _href = "" 
    _arrayType = "" 
} 

업데이트 :

>>> client = suds.client.Client('http://www.webservicex.net/WeatherForecast.asmx?WSDL') 
>>> client.wsdl.services[0].ports[0].methods.values()[0].soap.input.body.parts[0].element 
(u'GetWeatherByZipCode', http://www.webservicex.net) 
>>> client.factory.create(u'GetWeatherByZipCode') 
(GetWeatherByZipCode){ 
    ZipCode = None 
} 

그러나이 라 client.service.GetWeatherByZipCode("12345") 메서드 호출 (의 매개 변수에 magic'd되어 날씨 서비스의 경우IT는 "매개 변수"는 element 아닌 type와 일부임을 나타납니다. IIRC 이것은 SOAP RPC 바인딩 스타일입니까? 나는 당신이 시작하기에 충분한 정보가 여기에 있다고 생각합니다. 힌트 : 파이썬 커맨드 라인 인터페이스는 여러분의 친구입니다!

+1

어떤 이유인지 이들은 wsdl에서 모두 "없음"이므로 매개 변수 나 형식을 얻지 못합니다. , 그들은 str (클라이언트)에 나타나고 거기에 매개 변수와 유형이 모두 있습니다. – Wyrmwood

8

위의 정보를 바탕으로 작성한 간단한 스크립트로 WSDL에서 사용할 수있는 입력 방법 suds 보고서를 나열합니다. WSDL URL을 전달하십시오. 현재 진행중인 프로젝트에서 작동합니다. 귀하의 경우 보증 할 수 없습니다.

import suds 

def list_all(url): 
    client = suds.client.Client(url) 
    for service in client.wsdl.services: 
     for port in service.ports: 
      methods = port.methods.values() 
      for method in methods: 
       print(method.name) 
       for part in method.soap.input.body.parts: 
        part_type = part.type 
        if(not part_type): 
         part_type = part.element[0] 
        print(' ' + str(part.name) + ': ' + str(part_type)) 
        o = client.factory.create(part_type) 
        print(' ' + str(o)) 
+0

감사합니다! 나를 위해 일하는 것도 :) –

3

suds의 ServiceDefinition 개체에 액세스 할 수 있습니다. 여기에 빠른 샘플 : 당신이 유형의 접두사 이름을 알고 싶다면

from suds.client import Client 
c = Client('http://some/wsdl/link') 

types = c.sd[0].types 

는, 지금, 그것은 아주 쉽게도의 : 유형이 (목록이기 때문에

c.sd[0].xlate(c.sd[0].types[0][0]) 

이 이중 대괄호 표기법입니다 따라서 첫 번째 [0])이 목록의 각 항목에는 두 개의 항목이있을 수 있습니다. 그러나 __unicode__의 비눗물의 내부 구현 정확히 않는 (즉, 목록에서 첫 번째 항목 소요) :

s.append('Types (%d):' % len(self.types)) 
    for t in self.types: 
     s.append(indent(4)) 
     s.append(self.xlate(t[0])) 

해피 코딩, 당신은 WSDL 방법 객체를 생성하면)

0

당신은 그것에 대해 정보를 얻을 수 있습니다 인수의 이름 목록을 포함하여 __metadata__입니다.

주어진 인수의 이름을 사용하면 생성 된 메소드에서 실제 인스턴스에 액세스 할 수 있습니다. 복잡한 WSDL 유형이 유일한 작품 : 그 경우도 있습니다 당신이 이름을

# creating method object 
method = client.factory.create('YourMethod') 
# getting list of arguments' names 
arg_names = method.__metadata__.ordering 
# getting types of those arguments 
types = [method.__getitem__(arg).__metadata__.sxtype.name for arg in arg_names] 

면책 조항을 입력의 얻을 수 있습니다, 그것은 __metadata__ 정보의 포함되어 있습니다. 문자열 및 숫자와 같은 간단한 유형은 기본적으로 없음으로 설정됩니다. 없음

0
from suds.client import Client 
url = 'http://localhost:1234/sami/2009/08/reporting?wsdl' 
client = Client(url) 
functions = [m for m in client.wsdl.services[0].ports[0].methods] 
count = 0 
for function_name in functions: 
    print (function_name) 
    count+=1 
print ("\nNumber of services exposed : " ,count) 
관련 문제