2

I am trying to make a SOAP request with python and zeep, I need to add a soap:Header with the security (wsse:Security) and timestamp (wsu:Timestamp) labels

I do have this code:

from zeep import Client
from zeep.wsse import UsernameToken
from zeep.wsse import utils
from datetime import datetime, timedelta

# Create a SOAP client for the service
url = 'https://XXXXXXXXX/wsdlXXXXXX'
client = Client(url)

# Create a Object UsernameToken auth credentials
username = 'USERNAME'
password = 'PASSWORD'
token = UsernameToken(username, password)

# Add object UsernameToken to the tag wsse:Security
security = client.get_element('wsse:Security')
security_value = security(namelist=[token])

# Create a object Timestamp with date an time (now)
timestamp = utils.Timestamp()
timestamp_created = datetime.utcnow()
timestamp_expires = timestamp_created + timedelta(minutes=10)
timestamp.created = timestamp_created
timestamp.expires = timestamp_expires

# Add the tag wsu:Timestamp to the hader SOAP
timestamp_value = timestamp.xml

# add the tags in header SOAP
header = client.service._binding.create_message_header()
header.append(security_value)
header.append(timestamp_value)

# Send request SOAP with header
result = client.service.addressTown(_soapheaders=[header], arg1='28001')

My error is this:

Traceback (most recent call last):
  File "test3.py", line 16, in <module>
    security = client.get_element('wsse:Security')
  File "C:\Users\USER\Documents\Projects\Eva Seguros\comparatupoliza\venv\lib\site-packages\zeep\client.py", line 182, in get_element
    return self.wsdl.types.get_element(name)
  File "C:\Users\USER\Documents\Projects\Eva Seguros\comparatupoliza\venv\lib\site-packages\zeep\xsd\schema.py", line 126, in get_element
    qname = self._create_qname(qname)
  File "C:\Users\USER\Documents\Projects\Eva Seguros\comparatupoliza\venv\lib\site-packages\zeep\xsd\schema.py", line 265, in _create_qname
    raise ValueError("No namespace defined for the prefix %r" % prefix)
ValueError: No namespace defined for the prefix 'wsse'

1 Answers1

0

There is a missing namespace for the wsse prefix, define it before using them in the get_element method.

Here what it would be below, dont forget to replace the XXXXXXXXX/wsdlXXXXXX with the actual URL of the WSDL and correct username and password for the UsernameToken object.

from zeep import Client, Settings
from zeep.wsse import UsernameToken
from zeep.wsse.utils import Timestamp
from datetime import datetime, timedelta
from lxml import etree

# Create a SOAP client for the service
url = 'https://XXXXXXXXX/wsdlXXXXXX'
settings = Settings(strict=False, xml_huge_tree=True)
client = Client(url, settings=settings)

# Define the required namespaces
client.wsdl.types.prefix_map['wsse'] = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
client.wsdl.types.prefix_map['wsu'] = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'

# Create a Object UsernameToken auth credentials
username = 'USERNAME'
password = 'PASSWORD'
token = UsernameToken(username, password)

# Add object UsernameToken to the tag wsse:Security
security = client.get_element('wsse:Security')
security_value = security(namelist=[token])

# Create a object Timestamp with date an time (now)
timestamp = Timestamp()
timestamp_created = datetime.utcnow()
timestamp_expires = timestamp_created + timedelta(minutes=10)
timestamp.created = timestamp_created
timestamp.expires = timestamp_expires

# Add the tag wsu:Timestamp to the header SOAP
timestamp_value = timestamp.xml

# Create SOAP header
header = etree.Element("SOAP-ENV:Header", nsmap=client.wsdl.types.prefix_map)
header.append(security_value)
header.append(timestamp_value)

# Send request SOAP with header
result = client.service.addressTown(_soapheaders=[header], arg1='28001')
Saxtheowl
  • 4,136
  • 5
  • 23
  • 32
  • 1
    Sorry, I've tried your example and it still returns the same error. ValueError: No namespace defined for the prefix 'wsse' (correctly replace url and credentials) – Jahir Unzueta Apr 05 '23 at 08:02