Gzip compression
by Daniel Rodriguez
Hi Jeff et al,
If I am not wrong (I may have missed a configuration option), suds is not
using or requesting gzip compression.
I have added a few lines and tested at least requesting and accepting gzip
compression. My changes have been trivial and this could be possibly added
as an option to suds.
The changes I have made (against 3.9):
*File*: suds/transport/http.py:
*
*
*Extra imports*:
import gzip
import StringIO
*Class*: HttpTransport
*Method*: send
*Added:*
After:
- headers = request.headers
added the following line
- headers.update([('Accept-Encoding', 'gzip')])
*Changed:*
- result = Reply(200, fp.headers.dict, fp.read())
to
- replydata = fp.read()
- for header in fp.headers.dict.keys():
- if header.lower() == 'content-encoding' and
fp.headers.dict[header] == 'gzip':
- replydatacompressedstream = StringIO.StringIO(replydata)
- gzipper = gzip.GzipFile(fileobj=replydatacompressedstream)
- replydata = gzipper.read()
- result = Reply(200, fp.headers.dict, replydata)
Best regards
Daniel
13 years, 3 months
Possible problem with Yahoo WSDL
by Joshua J. Kugler
Howdy!
I have one for you to argue with Yahoo about. :)
I am making this call:
client.deleteReports([5283740314, 528350731])
It is generating this XML:
<ns1:Body>
<ns0:deleteReports>
<ns0:reportIDs>5283740314</ns0:reportIDs>
<ns0:reportIDs>5283507314</ns0:reportIDs>
</ns0:deleteReports>
</ns1:Body>
Which generates a server-side error. Pinging yahoo about this, they
tell me it should be:
<v7:reportIDs>
<v7:long>5283740314</v7:long>
<v7:long>5283507314</v7:long>
</v7:reportIDs>
The WSDL, in part, has this:
<xsd:element name="deleteReports">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="reportIDs"
nillable="true" type="tns:ArrayOfLong"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
The full WSDL is here:
http://developer.searchmarketing.yahoo.com/docs/V7/wsdl/V7/BasicReportSer...
Who is wrong? Suds, the WSDL, or tech support? :)
Something I've noticed about Yahoo is that they seem to like named
parameters. Example: their docs will say that a call, say,
getReportList, returns:
ReportInfo[] - A list of all requested reports that you have access to
in the master account.
But the response will be a response will be a single attribute (length
1), with a name of ReportInfo, which will then be a list of all
reports. Stated another way, instead of returning a list directly, it
returns an object with an attribute of ReportInfo, which is a list. At
least, that's what it does when called via Suds.
This is trunk, R671-20100405
Thanks!
j
--
Joshua Kugler
Part-Time System Admin/Programmer
http://www.eeinternet.com
PGP Key: http://pgp.mit.edu/ ID 0x73B13B6A
13 years, 5 months
Recent Posts
by Jeff Ortel
All,
For those of you who have posted to the list without reply, sorry. I've been pretty
slammed the last few weeks. I'll catch up ASAP.
Thanks,
Jeff
13 years, 5 months
DSN: failed (Delivery reports about your e-mail)
by Mailbot for etexusa.com
This is a Delivery Status Notification (DSN).
I was unable to deliver your message to
tdb2(a)ecs.soton.ac.uk.
I said
RCPT TO:<tdb2(a)ecs.soton.ac.uk>
And they gave me the error;
550 5.7.1 sender <fedora-suds-list(a)redhat.com> via etexusa.com (etexusa.com [65.49.16.198]) SPF result Fail; #702 (m3Y77F045380508700)
13 years, 5 months
Proposal for a re-work of exceptions in Suds
by Daniel Rodriguez
Hi Jeff,
I was reworking the error managing of the library I have built on top of
Suds and I think that the Exceptions raised by Suds could be reworked to
allow a finer "catching" granularity, without impacting the current system.
I assume that Suds does only raise exceptions defined in suds/__init__.py
and then:
- All defined exceptions but WebFault belong to the pre-network stage.
- WebFault belongs to the the post-network stage (suds can only detect a
"webfault" once it has seen the answer from the server
It is obvious, in my opinion, that some people would like to treat those 2
groups of exceptions differently and maybe have just to "excepts" handling
the potential cases. But this is difficult, given that all exceptions are
derived from "Exception".
An initial proposal would then be:
- Have a "SudsError" (derived from Exception) that will act as a base
class for all Suds exceptions.
- Derive (obviously) all exceptions from "SudsError"
This would allow implementing the following:
try:
mysudsclient.callmethod(param)
except suds.WebFault as wf:
doSomethingWithTheWebFault(wf)
except suds.SudsError as se:
doSomethingWithSudsError(se)
except Exception as ex:
doSomethingWithRegularPythonException(ex)
Even standard SudsError exceptions can be separated from standard Python
Exceptions and handled separately.
This is, again in my opinion, straightforward and poses no change to the
existing interface, while delivering (as stated above) a greater control
over exception handling in suds.
I can implement a patch if you think that this approach is something
interesting for suds.
Best regards
Daniel
13 years, 5 months
DSN: failed (Message could not be delivered)
by Mailbot for etexusa.com
This is a Delivery Status Notification (DSN).
I was unable to deliver your message to
ithelp(a)ucdavis.edu.
I said
(end of message)
And they gave me the error;
550 5.7.1 virus detected by ClamAV - Suspect.DoubleExtension-zippwd-9
13 years, 5 months
Re: [Fedora-suds-list] suds client and soaplib
by John Aherne
On Fri, Apr 23, 2010 at 2:16 PM, Jeff Ortel <jortel(a)redhat.com> wrote:
> Hey John,
>
> I'm sure we can figure this out. But, as you can understand by the trace,
> these things are must more easily resolved by stepping through the
> unmarshalling in the debugger. Can you provide me a copy of the wsdl and
> the reply that is giving you the problem?
>
> Oh, sorry for the delayed reply -- been busy ;)
>
> Thanks,
>
> Jeff
>
>
>
Jeff
I have done more experimenting.
When I try to add a job via suds, the job gets added, but the subordinate
complextype does not get added. No error message is shown. When I try to see
what comes through it shows each element as None.
When I try to do the same with soapui, it all gets added correctly. And my
list_jobs returns the jobs plus the extra detail from special instructions
etc.
Just grist to the mill.
Regards
John Aherne
13 years, 5 months
suds client and soaplib
by John Aherne
Jeff
I have moved on a bit.
I have only sent you part of the wsdl due to misunderstanding how the wsdl
is used.
When the client requests each time the wsdl, I wondered why the wsdl that
seemed to get generated only covered part of the wsdl.
I assumed that was how it was supposed to work.
I did try to find some other code in soaplib or suds that might be clearer
about getting the wsdl but did not find what I wanted.
Now I have used the soapui project to check what was happening. The code
that gets sent back is identical for suds and soapui, which is encouraging.
The full wsdl is below. If you need it as an attachment let me know.
Regards
John Aherne
<?xml version="1.0" encoding="UTF-8"?>
<definitions targetNamespace="CreateJob.CreateJob" name="CreateJob"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:tns="CreateJob.CreateJob" xmlns:typens="CreateJob.CreateJob"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="
http://www.w3.org/1999/XMLSchema-instance" xmlns:soap="
http://schemas.xmlsoap.org/wsdl/soap/" xmlns="
http://schemas.xmlsoap.org/wsdl/">
<types>
<schema targetNamespace="CreateJob.CreateJob" xmlns="
http://www.w3.org/2001/XMLSchema">
<xs:element name="JobArray" type="tns:JobArray"/>
<xs:complexType name="SpecialInstructionArray">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded"
type="tns:SpecialInstruction" name="SpecialInstruction"/>
</xs:sequence>
</xs:complexType>
<xs:element name="SpecialInstruction" type="tns:SpecialInstruction"/>
<xs:element name="cancel_job" type="tns:cancel_job"/>
<xs:complexType name="StopArray">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" type="tns:Stop"
name="Stop"/>
</xs:sequence>
</xs:complexType>
<xs:element name="amend_job" type="tns:amend_job"/>
<xs:element name="amend_jobResponse" type="tns:amend_jobResponse"/>
<xs:complexType name="GeoLocation">
<xs:sequence>
<xs:element name="town" minOccurs="0" type="xs:string"/>
<xs:element name="latitude" minOccurs="0" type="xs:float"/>
<xs:element name="postcode" minOccurs="0" type="xs:string"/>
<xs:element name="longitude" minOccurs="0" type="xs:float"/>
<xs:element name="address" minOccurs="0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="get_jobResponse">
<xs:sequence>
<xs:element name="get_jobResult" type="tns:Job"/>
</xs:sequence>
</xs:complexType>
<xs:element name="MeetingPointArray" type="tns:MeetingPointArray"/>
<xs:element name="list_jobs" type="tns:list_jobs"/>
<xs:complexType name="SpecialInstruction">
<xs:sequence>
<xs:element name="type" minOccurs="0" type="xs:string"/>
<xs:element name="id" minOccurs="0" type="xs:integer"/>
<xs:element name="value" minOccurs="0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="get_job" type="tns:get_job"/>
<xs:element name="SpecialInstructionArray"
type="tns:SpecialInstructionArray"/>
<xs:complexType name="cancel_job">
<xs:sequence>
<xs:element name="number" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="add_job">
<xs:sequence>
<xs:element name="job" type="tns:Job"/>
</xs:sequence>
</xs:complexType>
<xs:element name="SpecialPlace" type="tns:SpecialPlace"/>
<xs:element name="StopArray" type="tns:StopArray"/>
<xs:element name="add_job" type="tns:add_job"/>
<xs:element name="get_jobResponse" type="tns:get_jobResponse"/>
<xs:element name="TerminalArray" type="tns:TerminalArray"/>
<xs:element name="add_jobResponse" type="tns:add_jobResponse"/>
<xs:complexType name="add_jobResponse">
<xs:sequence>
<xs:element name="add_jobResult" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="amend_jobResponse">
<xs:sequence/>
</xs:complexType>
<xs:element name="ActorArray" type="tns:ActorArray"/>
<xs:element name="Actor" type="tns:Actor"/>
<xs:element name="cancel_jobResponse" type="tns:cancel_jobResponse"/>
<xs:element name="list_jobsResponse" type="tns:list_jobsResponse"/>
<xs:complexType name="Airport">
<xs:sequence>
<xs:element name="terminals" minOccurs="0"
type="tns:TerminalArray"/>
<xs:element name="location" minOccurs="0" type="tns:GeoLocation"/>
<xs:element name="name" minOccurs="0" type="xs:string"/>
<xs:element name="id" minOccurs="0" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Job" type="tns:Job"/>
<xs:complexType name="MeetingPoint">
<xs:sequence>
<xs:element name="id" minOccurs="0" type="xs:integer"/>
<xs:element name="location" minOccurs="0" type="tns:GeoLocation"/>
<xs:element name="name" minOccurs="0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SpecialPlace">
<xs:sequence>
<xs:element name="name" minOccurs="0" type="xs:string"/>
<xs:element name="cashCustomerAllowed" minOccurs="0"
type="xs:boolean"/>
<xs:element name="meetingPoints" minOccurs="0"
type="tns:MeetingPointArray"/>
<xs:element name="location" minOccurs="0" type="tns:GeoLocation"/>
<xs:element name="type" minOccurs="0" type="xs:string"/>
<xs:element name="id" minOccurs="0" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Stop" type="tns:Stop"/>
<xs:complexType name="JobArray">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" type="tns:Job"
name="Job"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MeetingPointArray">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded"
type="tns:MeetingPoint" name="MeetingPoint"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Actor">
<xs:sequence>
<xs:element name="id" minOccurs="0" type="xs:integer"/>
<xs:element name="email" minOccurs="0" type="xs:string"/>
<xs:element name="role" minOccurs="0" type="xs:string"/>
<xs:element name="name" minOccurs="0" type="xs:string"/>
<xs:element name="telephone" minOccurs="0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Airport" type="tns:Airport"/>
<xs:complexType name="list_jobs">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="cancel_jobResponse">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="Stop">
<xs:sequence>
<xs:element name="note" minOccurs="0" type="xs:string"/>
<xs:element name="meetingPoint" minOccurs="0" type="xs:string"/>
<xs:element name="airportStop" minOccurs="0" type="xs:boolean"/>
<xs:element name="specialPlace" minOccurs="0"
type="tns:SpecialPlace"/>
<xs:element name="arrivalFrom" minOccurs="0" type="xs:string"/>
<xs:element name="terminal" minOccurs="0" type="tns:Terminal"/>
<xs:element name="airport" minOccurs="0" type="tns:Airport"/>
<xs:element name="location" minOccurs="0" type="tns:GeoLocation"/>
<xs:element name="operationType" minOccurs="0" type="xs:integer"/>
<xs:element name="id" minOccurs="0" type="xs:integer"/>
<xs:element name="flightNo" minOccurs="0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TerminalArray">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded"
type="tns:Terminal" name="Terminal"/>
</xs:sequence>
</xs:complexType>
<xs:element name="MeetingPoint" type="tns:MeetingPoint"/>
<xs:complexType name="get_job">
<xs:sequence>
<xs:element name="number" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ActorArray">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" type="tns:Actor"
name="Actor"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="amend_job">
<xs:sequence>
<xs:element name="job" type="tns:Job"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Job">
<xs:sequence>
<xs:element name="specialInstructions" minOccurs="0"
type="tns:SpecialInstructionArray"/>
<xs:element name="asSoonAsPossible" minOccurs="0"
type="xs:boolean"/>
<xs:element name="callerName" minOccurs="0" type="xs:string"/>
<xs:element name="lastDrop" minOccurs="0" type="xs:string"/>
<xs:element name="jobDate" minOccurs="0" type="xs:dateTime"/>
<xs:element name="callerPhone" minOccurs="0" type="xs:string"/>
<xs:element name="number" minOccurs="0" type="xs:integer"/>
<xs:element name="stops" minOccurs="0" type="tns:StopArray"/>
<xs:element name="pinCode" minOccurs="0" type="xs:string"/>
<xs:element name="delay" minOccurs="0" type="xs:string"/>
<xs:element name="cancelledOnArrival" minOccurs="0"
type="xs:boolean"/>
<xs:element name="actors" minOccurs="0" type="tns:ActorArray"/>
<xs:element name="firstPickUp" minOccurs="0" type="xs:string"/>
<xs:element name="cancelled" minOccurs="0" type="xs:boolean"/>
<xs:element name="mainPassenger" minOccurs="0" type="xs:string"/>
<xs:element name="price" minOccurs="0" type="xs:float"/>
<xs:element name="callerEmail" minOccurs="0" type="xs:string"/>
<xs:element name="id" minOccurs="0" type="xs:integer"/>
<xs:element name="serviceCode" minOccurs="0" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="list_jobsResponse">
<xs:sequence>
<xs:element name="list_jobsResult" type="tns:JobArray"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Terminal">
<xs:sequence>
<xs:element name="location" minOccurs="0" type="tns:GeoLocation"/>
<xs:element name="meetingPoint" minOccurs="0" type="xs:string"/>
<xs:element name="name" minOccurs="0" type="xs:string"/>
<xs:element name="id" minOccurs="0" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:element name="GeoLocation" type="tns:GeoLocation"/>
<xs:element name="Terminal" type="tns:Terminal"/>
</schema>
</types>
<message name="add_job">
<part name="add_job" element="tns:add_job"/>
</message>
<message name="add_jobResponse">
<part name="add_jobResponse" element="tns:add_jobResponse"/>
</message>
<message name="amend_job">
<part name="amend_job" element="tns:amend_job"/>
</message>
<message name="amend_jobResponse"/>
<message name="cancel_job">
<part name="cancel_job" element="tns:cancel_job"/>
</message>
<message name="cancel_jobResponse"/>
<message name="get_job">
<part name="get_job" element="tns:get_job"/>
</message>
<message name="get_jobResponse">
<part name="get_jobResponse" element="tns:get_jobResponse"/>
</message>
<message name="list_jobs"/>
<message name="list_jobsResponse">
<part name="list_jobsResponse" element="tns:list_jobsResponse"/>
</message>
<portType name="CreateJob">
<operation name="add_job" parameterOrder="add_job">
<documentation/>
<input name="add_job" message="tns:add_job"/>
<output name="add_jobResponse" message="tns:add_jobResponse"/>
</operation>
<operation name="amend_job" parameterOrder="amend_job">
<documentation/>
<input name="amend_job" message="tns:amend_job"/>
<output name="amend_jobResponse" message="tns:amend_jobResponse"/>
</operation>
<operation name="cancel_job" parameterOrder="cancel_job">
<documentation/>
<input name="cancel_job" message="tns:cancel_job"/>
<output name="cancel_jobResponse" message="tns:cancel_jobResponse"/>
</operation>
<operation name="get_job" parameterOrder="get_job">
<documentation/>
<input name="get_job" message="tns:get_job"/>
<output name="get_jobResponse" message="tns:get_jobResponse"/>
</operation>
<operation name="list_jobs" parameterOrder="list_jobs">
<documentation/>
<input name="list_jobs" message="tns:list_jobs"/>
<output name="list_jobsResponse" message="tns:list_jobsResponse"/>
</operation>
</portType>
<plnk:partnerLinkType name="CreateJob">
<plnk:role name="CreateJob">
<plnk:portType name="tns:CreateJob"/>
</plnk:role>
</plnk:partnerLinkType>
<binding name="CreateJob" type="tns:CreateJob">
<soap:binding style="document" transport="
http://schemas.xmlsoap.org/soap/http"/>
<operation name="add_job">
<soap:operation soapAction="add_job" style="document"/>
<input name="add_job">
<soap:body use="literal"/>
</input>
<output name="add_jobResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="amend_job">
<soap:operation soapAction="amend_job" style="document"/>
<input name="amend_job">
<soap:body use="literal"/>
</input>
<output name="amend_jobResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="cancel_job">
<soap:operation soapAction="cancel_job" style="document"/>
<input name="cancel_job">
<soap:body use="literal"/>
</input>
<output name="cancel_jobResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="get_job">
<soap:operation soapAction="get_job" style="document"/>
<input name="get_job">
<soap:body use="literal"/>
</input>
<output name="get_jobResponse">
<soap:body use="literal"/>
</output>
</operation>
<operation name="list_jobs">
<soap:operation soapAction="list_jobs" style="document"/>
<input name="list_jobs">
<soap:body use="literal"/>
</input>
<output name="list_jobsResponse">
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="CreateJob">
<port name="CreateJob" binding="tns:CreateJob">
<soap:address location="http://localhost:7789/CreateJob?wsdl"/>
</port>
</service>
</definitions>
13 years, 5 months
May Suds be introducing an extra level of indirection?
by Daniel Rodriguez
Hi Jeff,
I am by no means a WSDL/XSD expert, but I think that Suds might be
introducing an extra level of indirection, although this can also be my
misinterpretation.
Definition of a complex type in the WSDL file:
<xsd:complexType abstract="true" name="APIResponse">
<xsd:sequence>
<xsd:element name="header" nillable="true"
type="types:APIResponseHeader"/>
</xsd:sequence>
<xsd:complexType name="GetCurrentBitsResp">
<xsd:complexContent>
<xsd:extension base="types:APIResponse">
<xsd:sequence>
<xsd:element name="bits" nillable="true"
type="types:ArrayOfBit"/>
<xsd:element name="errorCode" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="ArrayOfBit">
<xsd:sequence>
<xsd:element form="qualified" maxOccurs="unbounded" minOccurs="0"
name="Bit" nillable="true" type="types:Bit"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Bit">
<xsd:sequence>
<xsd:element name="size" nillable="false" type="xsd:double"/>
<xsd:element name="remaining" nillable="false" type="xsd:double"/>
</xsd:sequence>
</xsd:complexType>
The returned XML looks like:
<n:Result xsi:type="n2:GetCurrentBitsResp">
<header xsi:type="n2:APIResponseHeader">
...
</header>
<bits xsi:type="n2:ArrayOfBit">
<n2:Bit xsi:type="n2:Bit">
<size xsi:type="xsd:double">1.02</size>
<remaining xsi:type="xsd:double">0.0</remaining>
</n2:Bit>
<n2:Bit xsi:type="n2:Bit">
<size xsi:type="xsd:double">5.03</size>
<remaining xsi:type="xsd:double">3.51</remaining>
</n2:Bit>
</bits>
<errorCode xsi:type="xsd:string">OK</errorCode>
</n:Result>
In the generated Python objects the ArrayofBit is accessible with:
- result.bits.Bit
When I would expect (seeing the XML) to access the array with:
- result.bits
Maybe you or any other with a better knowledge of WSDL and XSD could clarify
if this should be the case or not.
Best regards
Daniel
13 years, 5 months