Open
Description
Adding the AccessToken to the header adds the AccessToken as a nested field in the sessionID field. I was very confused as posting raw xml files the the server did give the correct response but when i switched to zeep I suddenly got messages that my header was misformed.
When I show the header structure I get the correctly formed header:
Empty header structure: {
'SessionID': None,
'AccessToken': None,
'CompanyCode': None,
'CompanyId': None,
'_attr_1': None
}
When I then add the AccessToken, it is added to the SessionID:
Created header: {
'SessionID': {
'AccessToken': 'dummy_access_token_placeholder'
},
'AccessToken': None,
'CompanyCode': None,
'CompanyId': None,
'_attr_1': None
}
I also tried to add both the SessionID and AccessToken to see if that fixed it, but then they just both get added to the SessionID:
Created header: {
'SessionID': {
'SessionID': None,
'AccessToken': 'dummy_access_token_placeholder'
},
'AccessToken': None,
'CompanyCode': None,
'CompanyId': None,
'_attr_1': None
}
This is the code that I used to create this issue:
from zeep import Client
from zeep.plugins import HistoryPlugin
# zeep==4.3.1
def process_xml_with_zeep(wsdl_url: str, access_token: str):
client = Client(wsdl_url, plugins=[HistoryPlugin()])
header_element = client.get_element("ns0:Header")
print(f"Header element signature: {header_element.signature}")
print(f"Header element type: {header_element.type}")
# Empty header gives the correct structure
empty_header = header_element()
print(f"Empty header structure: {empty_header}")
# But the AccessToken somehow gets added to the sessionId as a nested list
header_data = {"AccessToken": access_token}
soap_header = header_element(header_data)
print(f"Created header: {soap_header}")
cluster_url = "https://api.accounting.twinfield.com"
url = f"{cluster_url}/webservices/processxml.asmx?wsdl"
access_token = "dummy_access_token_placeholder"
process_xml_with_zeep(
wsdl_url=url,
access_token=access_token,
)
My current solution is to use a manual header construction and avoid zeep for this step and that does work:
def process_xml_with_zeep_manual(access_token: str):
header = etree.Element(
"{http://www.twinfield.com/}Header",
nsmap={None: "http://www.twinfield.com/"},
)
# Add AccessToken as direct child
access_token_elem = etree.SubElement(header, "AccessToken")
access_token_elem.text = access_token
print(f"Manual header XML: {etree.tostring(header, pretty_print=True).decode()}")
cluster_url = "https://api.accounting.twinfield.com"
url = f"{cluster_url}/webservices/processxml.asmx?wsdl"
access_token = "dummy_access_token_placeholder"
process_xml_with_zeep_manual(access_token=access_token)
This gives:
Manual header XML: <Header xmlns="http://www.twinfield.com/">
<AccessToken>dummy_access_token_placeholder</AccessToken>
</Header>
Metadata
Metadata
Assignees
Labels
No labels