Currently, XOP compliant serialization is implemented in a very hacky way.
- First,
xop=True must be true, and there should be attachments stored on the client instance. Otherwise, no XOP serialization will take place.
- A SOAP message body string is generated using the
create_message method of the Zeep client instance. Note that all base64Binary values will have been encoded during message generation.
- A multipart message HTTP request is built compliant with MTOM/XOP specification. Then, for each attachment on the clilent instance a body part will be built.
- The only thing left to do is to create
<xop:Include/> elements for the base64 fields in the body. Since I'm not too familiar with the Zeep codebase, I've achieved this in a very hacky way currently:
- Just before sending the generated HTTP multipart request, the body is scanned for XML nodes which have text values that might be base64 encoded (based on what character alphabet is used and string length being divisible by four).
- For these candidate elements, the text value is base64-decoded. If the decoded value starts with
cid:, this apparently is a element in which an attachment is referenced, so for those elements a<xop:Include/> child element is generated with an href attribute that contains the cid:... value
For those familiar with SOAP UI this pattern of working should be familiar.
I'm not opposed to the SOAP UI like magic here, it's quite user-friendly and makes things somewhat easier. An improvement however would be to make better use of Zeep:
- There should be a better way to determine which fields are of type
base64Binary. Surely somewhere within the Document instance (or something like it) this should be possible. I don't know how and when I can access this instance however.
- The XML manipulation is now done by parsing the body string using lxml. This is overkill, since the
Document instance already contains/is an lxml Element.
Maybe more improvement is possible. I've seen Zeep is capable of handling XOP already, but it seems only in responses, and regardless: I don't know how to utilitize the code in xop.py.
Currently, XOP compliant serialization is implemented in a very hacky way.
xop=Truemust be true, and there should be attachments stored on the client instance. Otherwise, no XOP serialization will take place.create_messagemethod of the Zeep client instance. Note that allbase64Binaryvalues will have been encoded during message generation.<xop:Include/>elements for the base64 fields in the body. Since I'm not too familiar with the Zeep codebase, I've achieved this in a very hacky way currently:cid:, this apparently is a element in which an attachment is referenced, so for those elements a<xop:Include/>child element is generated with anhrefattribute that contains thecid:...valueFor those familiar with SOAP UI this pattern of working should be familiar.
I'm not opposed to the SOAP UI like magic here, it's quite user-friendly and makes things somewhat easier. An improvement however would be to make better use of Zeep:
base64Binary. Surely somewhere within theDocumentinstance (or something like it) this should be possible. I don't know how and when I can access this instance however.Documentinstance already contains/is an lxmlElement.Maybe more improvement is possible. I've seen Zeep is capable of handling XOP already, but it seems only in responses, and regardless: I don't know how to utilitize the code in
xop.py.