Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send a “multipart/related” with requests in python?

I'm trying to send a multipart/related message using requests in Python. The script seems simple enough, except that requests only seems to allow multipart/form-data messages to be sent, though their documentation does not clearly state this one way or another.

My use case is sending soap with attachments. I can provide a dictionary with the two files whose contents are a test soap-message, and a test document that I'm trying to send. The first contains the soap message with all the instructions, the second is the actual document.

However, if I don't specify a headers value, requests only seems to use multipart/form-data when using the files option. But if I specify headers in an attempt to specify a different multipart type, requests does not seem to add in the mime boundary information.

url = 'http://10.10.10.90:8020/foo'
headers = {'content-type': 'multipart/related'}
files = {'submission': open('submission_set.xml', 'rb'), 'document': open('document.txt', 'rb')}
response = requests.post(url, data=data, headers=headers)
print response.text

Is there a way to get this done using requests? Or is there another tool that I should be looking at?

like image 236
Zach Melnick Avatar asked Apr 01 '13 15:04

Zach Melnick


People also ask

What is multipart form data in Python?

A multipart form-post is an HTTP request sent using an HTML form, submitted with enctype set to "multipart/form-data". The request body is specially formatted as a series of "parts", separated with MIME boundaries.


1 Answers

You'll have to create the MIME encoding yourself. You can do so with the email.mime package:

import requests
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

related = MIMEMultipart('related')

submission = MIMEText('text', 'xml', 'utf8')
submission.set_payload(open('submission_set.xml', 'rb').read())
related.attach(submission)

document = MIMEText('text', 'plain')
document.set_payload(open('document.txt', 'rb').read())
related.attach(document)

body = related.as_string().split('\n\n', 1)[1]
headers = dict(related.items())

r = requests.post(url, data=body, headers=headers)

I presumed the XML file uses UTF-8, you probably want to set a character set for the document entry as well.

requests only knows how to create multipart/form-data post bodies; the multipart/related is not commonly used.

like image 68
Martijn Pieters Avatar answered Sep 22 '22 16:09

Martijn Pieters