通过REST API使用multipart / form-data上传文件

时间:2016-08-08 10:56:59

标签: rest multipartform-data robotframework

我试图通过Robot Framework上传4个文件以用作REST API调用中的请求主体。我使用Requests库来实现这一目标。

我认为我在设置正确的MIME类型/边界方面遇到了问题,因为如果我使用pybot运行该文件,则会抛出此错误:

{u'errorMessage': u"Couldn't find MIME boundary: ------Bound0901"}
  1. 这是设置MIME边界的正确方法吗?
  2. 我可以设置自定义MIME边界,就像我在下面给出的代码示例中一样吗?或者我是否需要设置由Web应用程序定义的边界?
  3. 以下是我用来完成此操作的代码:

    Library  |  RequestsLibrary
    
    *** TestCases ***
    
    1. Login
        Create Session  |  host  |  http://10.10.20.20
        &{headers}=  |  Create Dictionary  |  user=scott  |  password=tiger
        ${response}=  |  RequestsLibrary.Get Request  |  host  |  /api/login  |  ${headers}
        &{headers}    Create Dictionary  |  contentType=multipart/form-data;boundary=----Bound0901
        ${file1}=  |  Get Binary File  |  File1.au
        ${file2}=  |  Get Binary File  |  File2.crs
        ${file3}=  |  Get Binary File  |  File3.cst
        ${file4}=  |  Get Binary File  |  File4.des
    
        ${data}  |  Create Dictionary  |  ----Bound0901Detail={"Name":"APIContent1","isAICC": true,"version": "1.1","availableOffline": false}----Bound0901${file1}----Bound0901${file2}----Bound0901${file3}----Bound0901${file4}----Bound0901
    
        ${response}=  |  RequestsLibrary.Post Request  |  host  |  /api/contentimport  |  data=${data}  |  headers=${headers}
    
        Log    ${response.status_code}
        Log    ${response.json()}
    

1 个答案:

答案 0 :(得分:1)

其实你正在尝试两件事,

  1. 上传多个文件
  2. 发送数据/ Json以及文件附件
  3. 上传多个文件

    创建一个字典,每个文件有一个条目,part name为关键字,file content为值。

    *** Settings ***
    Library  RequestsLibrary
    
    *** TestCases ***
    
    1. Login
      Create Session  host  http://10.10.20.20
      &{headers}=  Create Dictionary  user=scott  password=tiger
      ${response}=  RequestsLibrary.Get Request  host  /api/login  ${headers}
    
      ${fileData1}=  Get Binary File  File1.au
      ${fileData2}=  Get Binary File  File2.crs
      ${fileData3}=  Get Binary File  File3.cst
      ${fileData4}=  Get Binary File  File4.des
    
      &{fileParts}=  Create Dictionary
      Set To Dictionary  ${fileParts}  file1=${fileData1}
      Set To Dictionary  ${fileParts}  file2=${fileData2}
      Set To Dictionary  ${fileParts}  file3=${fileData3}
      Set To Dictionary  ${fileParts}  file4=${fileData4}
    
      ${response}=  RequestsLibrary.Post Request  host  /api/contentimport  files=${fileParts}  headers=${headers}
    
      Log  ${response.status_code}
      Log  ${response.json()}
    

    在MultiPart中提交数据

    我不得不深入挖掘Python Requests库来弄清楚要做些什么。 要在multipart中发送数据,必须在相应的multipart中将content-type属性设置为application/json。 为此,以及设置多部分的filename属性,条目值必须是包含fileNamefileContentcontentType的列表。

    *** Settings ***
    Library  Collections
    Library  OperatingSystem
    Library  RequestsLibrary
    
    *** TestCases ***
    Login And Import
      Create Session  host  http://10.10.20.20
      &{headers}=  Create Dictionary  user=scott  password=tiger
      ${response}=  RequestsLibrary.Get Request  host  /api/login  ${headers}
    
      &{fileParts}=  Create Dictionary
      Create Multi Part   ${fileParts}  file1  File1.au
      Create Multi Part   ${fileParts}  file2  File2.crs
      Create Multi Part   ${fileParts}  file3  File3.cst
      Create Multi Part   ${fileParts}  file4  File4.des
    
      ${data}=  Set Variable  {"Name":"APIContent1", "isAICC": true, "version": "1.1", "availableOffline": false}
      Create Multi Part  ${fileParts}  Detail  data.json  contentType=application/json  content=${data}
    
      ${response}=  RequestsLibrary.Post Request  host  /api/contentimport  files=${fileParts}  headers=${headers}
    
      Log  ${response.status_code}
      Log  ${response.json()}
    
    *** Keywords ***
    Create Multi Part
      [Arguments]  ${addTo}  ${partName}  ${filePath}  ${contentType}=${None}  ${content}=${None}
      ${fileData}=  Run Keyword If  '''${content}''' != '''${None}'''  Set Variable  ${content}
      ...            ELSE  Get Binary File  ${filePath}
      ${fileDir}  ${fileName}=  Split Path  ${filePath}
      ${partData}=  Create List  ${fileName}  ${fileData}  ${contentType}
      Set To Dictionary  ${addTo}  ${partName}=${partData}
    

    导致以下内容:

    POST http://10.10.20.20/api/contentimport HTTP/1.1
    Host: 10.10.20.20
    Connection: keep-alive
    Accept-Encoding: gzip, deflate
    Accept: */*
    User-Agent: python-requests/2.13.0
    user: scott
    password: tiger
    Content-Length: 761
    Content-Type: multipart/form-data; boundary=363f55556da84a4083532ce822b09259
    
    --363f55556da84a4083532ce822b09259
    Content-Disposition: form-data; name="file1"; filename="File1.au"
    
    contents of File1
    --363f55556da84a4083532ce822b09259
    Content-Disposition: form-data; name="file2"; filename="File2.crs"
    
    contents of File2
    --363f55556da84a4083532ce822b09259
    Content-Disposition: form-data; name="file3"; filename="File3.cst"
    
    contents of File3
    --363f55556da84a4083532ce822b09259
    Content-Disposition: form-data; name="file4"; filename="File4.des"
    
    contents of File4
    --363f55556da84a4083532ce822b09259
    Content-Disposition: form-data; name="Detail"; filename="data.json"
    Content-Type: application/json
    
    {"Name":"APIContent1", "isAICC": true, "version": "1.1", "availableOffline": false}
    --363f55556da84a4083532ce822b09259--