I'm trying to upload a PDF to OneNote using Python. According to the OneNote API, I need to post a request like this:
Content-Type:multipart/form-data; boundary=MyAppPartBoundary
Authorization:bearer tokenString
--MyAppPartBoundary
Content-Disposition:form-data; name="Presentation"
Content-type:text/html
<!DOCTYPE html>
<html>
<head>
<title>A page with an embedded and displayed PDF file</title>
</head>
<body>
<p>Attached is the lease agreement for the expanded offices!</p>
<object
data-attachment="OfficeLease.pdf"
data="name:OfficeLeasePartName"
type="application/pdf" />
<p>Here's the contents of our new lease.</p>
<img data-render-src="name:OfficeLeasePartName" width="900"/>
</body>
</html>
--MyAppPartBoundary
Content-Disposition:form-data; name="OfficeLeasePartName"
Content-type:application/pdf
... PDF binary data ...
--MyAppPartBoundary--
However, I have no idea how to do a multipart request in Python. I can do a basic text/html request just fine though:
url = ROOT_URL+"pages"
headers = {"Content-Type":"text/html",
"Authorization" : "bearer " + access_token}
# Format html (title & text)
html = "<html><head><title>" + title + "</title></head>"
html += "<body><p>" + text + "</p></body></html>"
# Send request
session = requests.Session()
request = requests.Request(method="POST", headers=headers,
url=url, data=html)
prepped = request.prepare()
response = session.send(prepped)
How would I modify that Python code for multi-part?
[########### UPDATE ############]
Based on jayongg's suggestion, I tried the following. When I do, the error I get switches from "Page create requests require the content to be multipart, with a presentation part" to "The multi-part payload was malformed." I think it's because I'm not actually attaching the pdf file somewhere? I'm also not sure what's the difference between OfficeLease.pdf in the OneNote api example and OfficeLeasePartName.
Here is my current code:
url = ROOT_URL+"pages"
path = os.path.join(pdfFolder, pdfName + ".pdf")
headers = {"Content-Type":"multipart/form-data; boundary=MyAppPartBoundary",
"Authorization" : "bearer " + access_token}
f = open(path, "rb").read()
txt = """--MyAppPartBoundary
Content-Disposition:form-data; name="Presentation"
Content-type:text/html
<!DOCTYPE html>
<html>
<head>
<title>A page with an embedded and displayed PDF file</title>
</head>
<body>
<p>Attached is the lease agreement for the expanded offices!</p>
<object
data-attachment="Sample5.pdf"
data="name:Sample5"
type="application/pdf" />
<p>Here's the contents of our new lease.</p>
<img data-render-src="name:Sample5" width="900"/>
</body>
</html>
--MyAppPartBoundary
Content-Disposition:form-data; name="OfficeLeasePartName"
Content-type:application/pdf
""" + f + """
--MyAppPartBoundary--"""
session = requests.Session()
request = requests.Request(method="POST", headers=headers,
url=url, data=txt)
prepped = request.prepare()
response = session.send(prepped)
[########## UPDATE 2 ##############]
If I make the code even simpler, it still results in a malformed error:
headers = {"Content-Type":"multipart/form-data; boundary=MyAppPartBoundary",
"Authorization" : "bearer " + access_token}
txt = """--MyAppPartBoundary
Content-Disposition:form-data; name="Presentation"
Content-type:text/html
<!DOCTYPE html>
<html>
<head>
<title>One Note Text</title>
</head>
<body>
<p>Hello OneNote World</p>
</body>
</html>
--MyAppPartBoundary--
"""
session = requests.Session()
request = requests.Request(method="POST", headers=headers,
url=url, data=txt)
I've also tried like this. Same thing:
headers = {"Content-Type":"multipart/form-data; boundary=MyAppPartBoundary",
"Authorization" : "bearer " + access_token}
txt = """<!DOCTYPE html>
<html>
<head>
<title>One Note Text</title>
</head>
<body>
<p>Hello OneNote World</p>
</body>
</html>"""
files = {'file1': ('Presentation', txt, 'text/html')}
session = requests.Session()
request = requests.Request(method="POST", headers=headers,
url=url, files=files)
prepped = request.prepare()
response = session.send(prepped)