teebagz
teebagz

Reputation: 724

Zeep send request with missing mandatory tag

My SOAP services will be tested with various invalid payloads to confirm the appropriate responses are returned.

Before testing is carried out, i would like to do my own testing on my services. A few of the tests involve removal of a mandatory field. I would like to simulate these tests using zeep, but zeep will not allow me to send a request, giving me a zeep.exceptions.ValidationError if any of the mandatory fields are not present in the data i want to send.

Is there some setting i can configure so that zeep doesn't throw an error for the missing field and sends the invalid request anyway?

example code:

from zeep import Client
from datetime import datetime

wsdl_url = 'http://myservice.com/egservice?wsdl'

payload = {
    'ServiceType': 'EgService',
    'AvailabilityWindow': [
        {'StartDateTime': datetime.now(),
         'EndDateTime': datetime.now(),
         'Validation': 'VALID'}],
    'Confirmation': 'Confirmed',
    'DateTimeStamp': datetime.now()
}  # N.B No ContractID included

soap_client = Client(wsdl_url)
operation = 'myExampleOperation'
with soap_client.settings(raw_response=True):
    response = soap_client.service[operation](**payload)

relevant part of wsdl:

<xs:complexType name="EgMessage">
    <xs:sequence>
        <xs:element name="ServiceType" type="tns:EgMessage_ServiceTypeType"/>
        <xs:element name="ContractID" type="tns:EgMessage_ContractIDType"/>
        <xs:element name="AUI" type="tns:EgMessage_AUIType" minOccurs="0"/>
        <xs:element name="AvailabilityWindow" type="tns:AvailabilityWindowType" maxOccurs="unbounded"/>
        <xs:element name="Confirmation" type="tns:EgMessage_ConfirmationType"/>
        <xs:element name="FileReason" type="tns:EgMessage_FileReasonType" minOccurs="0"/>
        <xs:element name="DateTimeStamp" type="xs:dateTime"/>
</xs:sequence>
</xs:complexType>

traceback:

Traceback (most recent call last):
  File "C:/Users/Thomas.Gabereau/PycharmProjects/pas_rmq/pas_gateway/inbound/test_local_soap.py", line 157, in <module>
    status, fault_field, fault = send_to_grid(soap_client, operation, payload)
  File "C:/Users/Thomas.Gabereau/PycharmProjects/pas_rmq/pas_gateway/inbound/test_local_soap.py", line 129, in send_to_grid
    response = soap_client.service[operation](**payload)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\proxy.py", line 45, in __call__
    kwargs,
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\wsdl\bindings\soap.py", line 119, in send
    operation, args, kwargs, client=client, options=options
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\wsdl\bindings\soap.py", line 68, in _create
    serialized = operation_obj.create(*args, **kwargs)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\wsdl\definitions.py", line 215, in create
    return self.input.serialize(*args, **kwargs)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\wsdl\messages\soap.py", line 74, in serialize
    self.body.render(body, body_value)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\element.py", line 231, in render
    self._render_value_item(parent, value, render_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\element.py", line 255, in _render_value_item
    return self.type.render(node, value, None, render_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\types\complex.py", line 279, in render
    element.render(parent, element_value, child_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\indicators.py", line 242, in render
    element.render(parent, element_value, child_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\element.py", line 225, in render
    self.validate(value, render_path)
  File "C:\Users\Thomas.Gabereau\PycharmProjects\pas_rmq\venv\lib\site-packages\zeep\xsd\elements\element.py", line 280, in validate
    "Missing element %s" % (self.name), path=render_path
zeep.exceptions.ValidationError: Missing element ContractID(myExampleOperation.ContractID)

Upvotes: 4

Views: 2050

Answers (1)

Mukesh mohan
Mukesh mohan

Reputation: 101

I faced the same issue then found out a solution for this problem. There is a option to skip the validation for mandatory fields.you have to set the value as xsd.skipvalue for the property you want to skip. In your scenario set the value for contractId as xsd.skipvalue in the payload object

from zeep import xsd

payload = {
    'ServiceType': 'EgService',
    'ContractID':xsd.SkipValue,
    'AvailabilityWindow': [
        {'StartDateTime': datetime.now(),
         'EndDateTime': datetime.now(),
         'Validation': 'VALID'}],
    'Confirmation': 'Confirmed',
    'DateTimeStamp': datetime.now()
}   

Upvotes: 5

Related Questions