【问题标题】:how to send SOAP request including a Base64 encoded .csv file with python requests?如何使用 python 请求发送包含 Base64 编码的 .csv 文件的 SOAP 请求?
【发布时间】:2022-01-23 23:59:59
【问题描述】:

我正在尝试使用 python 请求模块发送 SOAP 请求,其中 SOAP 正文的一部分包含 Base64 编码的 .csv 文件。基本请求正在工作。该文件作为 Base64 编码字符串附加在 <soapenv:Body> 内的任意标签内。

SOAP 服务是内部电子邮件服务的外观,我也维护它。我知道它可以正常工作,因为我收到了电子邮件,并且它有一个附件,但附件是乱码,因为没有更好的词。

我对 python 还很陌生,所以其中很多可能是糟糕的代码,而不是 pythonic 等。
但是我从另一个开发人员那里复制了大部分代码,其余的都可以工作,除了文件附件。

使用 python 3.8 和请求 2.26.0

我正在使用以下内容从本地文件中读取 .csv:

file = open('myfile.csv', 'rb')
file_content = file.read()
base64_data = base64.b64encode(file_content)

我也尝试使用base64.encodebytes(file_content) 得到类似的乱码结果,尽管它们略有不同。不知道这些方法的区别是什么,但其中一个似乎有更多的行,而另一个似乎有更少的行,我认为这是正确的,因为它是一个只有几行的小文件。

然后使用以下内容创建请求:

def _createRequest(self, toemail, emailsubject, emailbody, file_to_attach):

    soap_request = """<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Header>
      ...
   </soap:Header>
   <soap:Body>
      <EmailRequest xmlns="...">
         <AddressTo>
            {to_email}
         </AddressTo>
         <From>blah</From>
         <Subject>{subject}</Subject>
         <Body><![CDATA[
             {body}
         ]]></Body>
         <BinaryAttachment filename="myfile.csv" MediaServer="N">{file_base64_encoded}</BinaryAttachment>
         <ContentType>HTMLText</ContentType>
      </EmailRequest>
   </soap:Body>
</soap:Envelope>""".format(to_email=toemail, subject=emailsubject, body = emailbody, file_base64_encoded=file_to_attach)

    return soap_request

我想知道它是否与标题有关。我们在标题中使用基本身份验证:

def __getBasicAuthHeaders(self, user_name, password):
    authHeader = base64.b64encode(
        (user_name + ':' + password).encode()).decode()
    return {
        'Authorization': 'Basic ' + authHeader,
        'Content-Type': 'application/xml'
    }

【问题讨论】:

    标签: python soap python-requests base64


    【解决方案1】:

    您是否将base64_data 作为参数发送给_createRequest 函数?从您的代码中,您似乎期望一个字符串,但您在那里得到字节。例如:

    >>> file = open('test.txt', 'rb')
    >>> file_content = file.read()
    >>> base64_data = base64.b64encode(file_content)
    >>>
    >>> soap_request1 = "<BinaryAttachment>{file_base64_encoded}</BinaryAttachment>".format(file_base64_encoded=base64_data)
    >>> soap_request1
    "<BinaryAttachment>b'Tm90aGluZyB0byBzZWUgaGVyZSE='</BinaryAttachment>"
    >>>
    >>> soap_request2 = "<BinaryAttachment>{file_base64_encoded}</BinaryAttachment>".format(file_base64_encoded=base64_data.decode())
    >>> soap_request2
    '<BinaryAttachment>Tm90aGluZyB0byBzZWUgaGVyZSE=</BinaryAttachment>'
    >>>
    

    查看soap_request1soap_request2 之间的差异,您可能会找到罪魁祸首。也看看这个:Convert bytes to a string

    使用您需要的任何数据编码,很可能是 utf-8。

    您还想知道基本身份验证是否与此有关。它没有,但那些 encode() / decode() 可能提供了线索。

    【讨论】:

    • 是的,就是这样 - 谢谢!
    猜你喜欢
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 2017-10-06
    • 1970-01-01
    • 2011-12-12
    • 2019-06-19
    相关资源
    最近更新 更多