I'm as eager to know as you are.

So i tried a few things and found the following to work, though
not as they way you'd like it to work:

----- [start service snippet]
@service.soap('GetQuote1', returns={'result':{'c':[{'c':float}],'b':
{'name':str,'value':str}}}, args={'symbol':str})
def stock_quote(symbol):
    "Return stock quote info - everything is hardcoded..."
    return dict(result={'c':[dict(c=1.0),dict(c=2.0)],
            'b':dict(name='remco')})
----- [end service snippet]

which produces the following WSDL (snippet)
----- [start wsdl snippet]
<xsd:element name="GetQuote1Response">
        <xsd:complexType>
                <xsd:all>
                        <xsd:element name="result" 
type="tns:GetQuote1Responseresult"/>
                </xsd:all>
        </xsd:complexType>
</xsd:element>
<xsd:complexType name="GetQuote1Responseresult">
        <xsd:all>
                <xsd:element name="c" 
type="tns:ArrayOfGetQuote1Responseresultc"/>
                <xsd:element name="b" type="tns:GetQuote1Responseresultb"/>
        </xsd:all>
</xsd:complexType>
<xsd:complexType name="ArrayOfGetQuote1Responseresultc">
        <xsd:sequence>
                <xsd:element maxOccurs="unbounded" minOccurs="0" name="c"
type="xsd:float"/>
        </xsd:sequence>
</xsd:complexType>
<xsd:complexType name="GetQuote1Responseresultb">
        <xsd:all>
                <xsd:element name="name" type="xsd:string"/>
                <xsd:element name="value" type="xsd:string"/>
        </xsd:all>
</xsd:complexType>
----- [end wsdl snippet]

now if you call this like

----- [start client snippet]
from gluon.contrib.pysimplesoap.client import SoapClient
print '*** crafting client '
client = SoapClient(wsdl='http://127.0.0.1:8000/welcome/default/call/
soap/?WSDL')
print '*** query '
print client.GetQuote1(symbol='google')
----- [end client snippet]

this *does* successfully output the following:

 {'result': {'c': [{'c': 1.0}, {'c': 2.0}], 'b': {'name': 'remco'}}}

which is exactly what it should be.

What I've encountered and couldn't solve on my own:
 * c Can't be a list of float, it has to be a list of a dictionary
   with the key equal to the parent's key ('c' in this example).
   Try some different things for yourself and see the errors.

 * When returning result you have to return a complex type instead
   of (the more intuitive):
       return {'c':[dict(c=1.0),dict(c=2.0)], 'b':dict(name='remco')}

 * Internally it seems to use Ordered dictionaries, but the actual
   use of it is missing (somewhere in pysimplesoap\server.py@228)
   so you might run into errors of the ordering of keys in
   dictionaries. WSDL might be picky about it.

 * depending on your client you might need to patch a little in the
   source that produces the WSDL. I haven't tried a WSDL lint or
   similar but i am not surprised if not all clients properly handle
   pysimplesoaps wsdl because most clients are quite picky...

Hope this helps.

On 8 sep, 04:47, David Mitchell <[email protected]> wrote:
> Bump
>
> On 6 September 2011 19:13, David Mitchell <[email protected]> wrote:
>
>
>
>
>
>
>
> > Hello all,
>
> > I'm looking at using web2py to build a SOAP service to work as a test
> > harness for an infrastructure upgrade we're planning.  Unfortunately, all
> > the web2py SOAP info I've found has been trivial services such as adding 2
> > numbers together - in my case, I need my SOAP server to be able to do
> > something more complicated.
>
> > The sort of complexity I need to build is something like
> >http://www.webservicex.com/stockquote.asmx?WSDL
> > When I query this service from suds, the code looks something like:
> > >>> import suds
> > >>> url = 'http://www.webservicex.com/stockquote.asmx?WSDL'
> > >>> client = suds.client.Client(url)
> > >>> print client
>
> > Suds (https://fedorahosted.org/suds/)  version: 0.4 GA  build:
> > R699-20100913
>
> > Service ( StockQuote ) tns="http://www.webserviceX.NET/";
> >    Prefixes (0)
> >    Ports (2):
> >       (StockQuoteSoap)
> >          Methods (1):
> >             GetQuote(xs:string symbol, )
> >          Types (0):
> >       (StockQuoteSoap12)
> >          Methods (1):
> >             GetQuote(xs:string symbol, )
> >          Types (0):
>
> > >>> client.service.GetQuote('IBM')
> > <StockQuotes><Stock><Symbol>IBM</Symbol><Last>166.98</Last><Date>9/2/2011</ 
> > Date><Time>4:00pm</Time><Change>0.00</Change><Open>N/A</Open><High>N/A</Hig 
> > h><Low>N/A</Low><Volume>200</Volume><MktCap>199.4B</MktCap><PreviousClose>1 
> > 66.98</PreviousClose><PercentageChange>0.00%</PercentageChange><AnnRange>12 
> > 5.39
> > - 185.63</AnnRange><Earns>12.315</Earns><P-E>13.56</P-E><Name>International
> > Bus</Name></Stock></StockQuotes>
>
> > I figure my web2py controller code to do this would look something like:
>
> > from gluon.tools import Service
> > service = Service(globals())
>
> > @service.soap('GetQuote', returns={SOMETHING_HERE}, args={'symbol':str})
> > def stock_quote(stock):
> >     "Return stock quote info - everything is hardcoded..."
> >     symbol = "IBM"
> >     last = 166.98
> >     date = '9/2/2011'
> >     quote_time = '4:00pm'
> >     change = 0.00
> >     #...
> >     return SOMETHING_HERE
>
> > def call():
> >     return service()
>
> > I'm trying to work out what the 2 SOMETHING_HERE pieces should look like in
> > the above code.
>
> > Could someone please point me in the right direction?
>
> > Thanks in advance
>
> > Dave M.

Reply via email to