Python SUDS Error

I am trying to convert a PHP script to python, but I can’t understand for life why the following does not work.

Results returned from a SOAP service request:

Suds ( https://fedorahosted.org/suds/ ) version: 0.4 GA build: R699-20100913 Service ( ExternalQueryNameAvailabilityService ) tns="http://asic.gov.au/wsdl/name/availability/external" Prefixes (6) ns0 = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" ns1 = "http://www.w3.org/2005/05/xmlmime" ns2 = "uri:business.document.header.types.asic.gov.au" ns3 = "uri:external.query.name.availability.asic.gov.au" ns4 = "uri:fss.types.asic.gov.au" ns5 = "uri:types.asic.gov.au" Ports (1): (ExternalQueryNameAvailabilityPort) Methods (1): externalQueryNameAvailability(ns2:businessDocumentHeaderType businessDocumentHeader, ns3:requestDataType businessDocumentBody, ) Types (113): ns0:AttributedDateTime ns0:AttributedURI ns0:TimestampType ns5:abnApplicationReferenceNumberType ns5:abnType ns5:accountIdentifierType ns5:actionType ns5:addressType ns5:addressTypeType ns5:agentNameType ns5:agentType ns5:amountSignedType ns5:amountType ns5:applicationStatusType ns4:ascotDocumentNoType ns5:asicNumericIdType ns4:asicPaymentDetailsType ns5:asicSignatoryType ns2:attachmentType ns2:attachmentsType ns1:base64Binary ns5:birthDetailsType ns5:bnReferenceNumberType ns5:browserIdentifierType ns2:businessDocumentHeaderType ns2:businessDocumentRequestHeaderType ns5:businessNameIdentifierType ns5:codeType ns5:creditCardType ns4:customerReferenceNumberType ns4:debtorType ns5:descriptionType ns5:distinguishedNameType ns5:distinguishedWordType ns5:documentIdentifierType ns5:documentNoType ns5:emailType ns5:entityType ns5:exceptionListType ns5:exceptionType ns4:feeType ns4:feeWithAmountType ns4:feesType ns5:flagType ns4:fssAccountType ns4:fssCustomerType ns4:fssItemType ns4:fssSimpleAccountType ns4:fssTransactionType ns2:genericResultType ns1:hexBinary ns5:inboxIdentifierType ns5:intervalStatusType ns4:invoiceType ns5:itemSearchScopeType ns5:itemSummaryType ns5:itemTypeType ns5:keyType ns4:ledgerType ns5:lodgementIdentifierType ns2:messageEventType ns2:messageEventsType ns5:messageIdentifierType ns2:messageTimestampType ns2:messageTimestampsType ns5:nameAvailabilityType ns5:nameResultType ns5:nameResultWithObjectionsType ns5:nameType ns5:nniNameType ns5:nniNumberType ns5:objectionType ns5:organisationIdentifierType ns5:organisationNamePlusIdType ns5:originatingChannelType ns5:originatingServiceType ns5:outboundItemIdentifierType ns4:paymentDetailsType ns4:paymentMethodType ns5:paymentType ns5:personNameBirthType ns5:personNameType ns5:personNameWithRoleType ns4:priceType ns3:queryNameAvailabilityReplyType ns3:queryNameAvailabilityRequestType ns5:realmIdentifierType ns5:realmQualifierType ns4:receiptType ns5:referenceNoType ns5:rejectedType ns3:replyDataType ns5:replyType ns3:requestDataType ns5:requestFailedType ns5:requestRejectedType ns5:requestType ns5:resultType ns5:signatoryType ns5:soapSoftwareIdentifierType ns2:softwareInformationType ns5:standardHeaderType ns5:standardMessageHeaderType ns5:stateTerritoryCodeType ns5:statusType ns5:streetType ns4:suffixType ns0:tTimestampFault ns5:telephoneNumberType ns5:textType ns4:transactionType ns4:transactionsType ns5:trueType 

When trying to do the following:

 con = connect('ExternalQueryNameAvailabilityPort', test, {'Content-Type': 'application/soap+xml'}) q_header = con.factory.create('ns2:businessDocumentHeaderType') q_header.messageType = 'queryNameAvailability' q_header.messageVersion = '2' q_header.messageReferenceNumber = '100' q_header.senderType = 'REGA' q_header.senderId = '192' q_body = con.factory.create('ns3:businessDocumentBody') q_body.proposedName = 'Xtramedia.net PTY LTD' q_body.companyNameAvailabilityCheck = 'true' q_body.bnNameAvailabilityCheck = 'true' result = con.service.externalQueryNameAvailability(q_header, q_body) 

I get the following error:

 DEBUG:suds.client:http failed: <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"> <S:Body> <S:Fault xmlns:ns4="http://schemas.xmlsoap.org/soap/envelope/"> <S:Code> <S:Value>S:Receiver</S:V6alue> </S:Code> <S:Reason> <S:Text xml:lang="en">org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'ns1:businessDocumentHeader'. One of '{"uri:business.document.header.types.asic.gov.au":businessDocumentHeader}' is expected </S:Text> </S:Reason> </S:Fault> </S:Body> </S:Envelope> 

Any ideas why he would complain about this item? - I tried to remove the "nsX" part of the element declaration, but the same thing.

UPDATE: The following is what a PHP script generates and successfully creates;

  <?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="uri:business.document.header.types.asic.gov.au" xmlns:ns2="uri:external.query.name.availability.asic.gov.au"> <env:Body> <ns2:request> <ns1:businessDocumentHeader> <ns1:messageType>queryNameAvailability</ns1:messageType> <ns1:messageReferenceNumber>1</ns1:messageReferenceNumber> <ns1:messageVersion>2</ns1:messageVersion> <ns1:senderId>192</ns1:senderId> <ns1:senderType>REGA</ns1:senderType> </ns1:businessDocumentHeader> <ns2:businessDocumentBody> <ns2:proposedName>TEST</ns2:proposedName> <ns2:bnNameAvailabilityCheck>true</ns2:bnNameAvailabilityCheck> </ns2:businessDocumentBody> </ns2:request> </env:Body> </env:Envelope> 

Does anyone have any ideas?

UPDATE 2: I had to install the latest version of SUDS to get this to work. - Thank you all for your answers, which were highly appreciated.

Cheers, Ben

+4
source share
2 answers

Update (after output of PHP example)

It is not clear why suds uses {uri:external.query.name.availability.asic.gov.au} instead of {uri:business.document.header.types.asic.gov.au} for the businessDocumentHeader element.

A quick and dirty way to fix this is to use suds.plugin for example:

 from suds.plugin import MessagePlugin class NsHeaderPlugin(MessagePlugin): def sending(self, context): context.envelope = context.envelope.replace('ns1:businessDocumentHeader', 'ns0:businessDocumentHeader') 

Or

 class NsHeaderPlugin(MessagePlugin): def marshalled(self, context): hdr = context.envelope.childAtPath('Body/request/businessDocumentHeader') hdr.setPrefix('hdr', 'uri:business.document.header.types.asic.gov.au') 

The second argument should be ns3:requestDataType , not ns3:businessDocumentBody , as you indicated.

General code stream:

 from suds.client import Client # pip install suds #XXX: change envelope namespace from suds.bindings import binding binding.envns = (binding.envns[0], 'http://www.w3.org/2003/05/soap-envelope') del binding # change content type headers = {'Content-Type': 'application/soap+xml; charset="UTF-8"'} client = Client(wsdl_url, headers=headers, plugins=[NsHeaderPlugin()]) header = client.factory.create('{uri:business.document.header.types.asic.gov.au}' 'businessDocumentHeaderType') header.messageType = "queryNameAvailability" header.messageReferenceNumber = 1 header.messageVersion = 2 header.senderId = 192 header.senderType = "REGA" body = client.factory.create('{uri:external.query.name.availability.asic.gov.au}' 'requestDataType') body.proposedName = 'TEST' body.bnNameAvailabilityCheck = 'true' # make the call result = client.service.externalQueryNameAvailability(header, body) print result # for debugging, to find out what attributes are available 

I don't see the undefined namespace, so it seems that ImportDoctor not required in your case. But, for example, if you used the xs:string type and 'http://schemas.xmlsoap.org/soap/encoding/' , you could fix the wsdl scheme:

 from suds.xsd.doctor import Import, ImportDoctor imp = Import('http://schemas.xmlsoap.org/soap/encoding/') # add namespaces where the type is used (call `imp.filter.add` multiple times) imp.filter.add("http://asic.gov.au/wsdl/name/availability/external") doctor = ImportDoctor(imp) client = Client(wsdl_url, doctor=doctor) 
+2
source

The error pretty much tells you exactly where you need to look:

  <S:Text xml:lang="en">org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'ns1:businessDocumentHeader'. One of '{"uri:business.document.header.types.asic.gov.au":businessDocumentHeader}' is expected 

ns1 refers to the URL http://www.w3.org/2005/05/xmlmime . If you visit this in your browser, you can see that this is not enough. This further excludes that ns1 is correct.

Since ns1:businessDocumentHeader is not even on the list of types defined by WSDL, you may need to use ImportDoctor . In the past, I ran into a similar problem in a personal project where WSDL did not import types correctly.

I am sorry that this answer is not final, but it is very difficult to determine the exact fix, since I can not see your WSDL. Try working with documents for ImportDoctor and see if this helps.

Try to start with this:

 from suds.xsd.doctor import Import, ImportDoctor imp = Import("http://www.w3.org/2005/05/xmlmime") imp.filter.add("uri:business.document.header.types.asic.gov.au") doctor = ImportDoctor(imp) 

And then pass doctor=doctor to the client constructor.

0
source

Source: https://habr.com/ru/post/1398699/


All Articles