如何使用Python向OneNote发送多部分PDF请求 [英] How to Use Python to Send a Multipart PDF Request to OneNote

查看:165
本文介绍了如何使用Python向OneNote发送多部分PDF请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python将PDF上传到OneNote。根据OneNote API,我需要发布这样的请求:

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--

但是,我不知道如何在Python中执行多部分请求。我可以做一个基本的文本/ html请求就好了:

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)

如何修改多部分的Python代码?

How would I modify that Python code for multi-part?

[###########更新############]

[########### UPDATE ############]

根据jayongg的建议,我尝试了以下方法。当我这样做时,我得到的错误从页面创建请求要求内容为多部分,带有演示文稿部分切换为多部分有效负载格式错误。我想这是因为我实际上并没有在某处附加pdf文件?我也不确定OneNote api示例中的OfficeLease.pdf和OfficeLeasePartName之间有什么区别。

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.

这是我当前的代码:

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 ##############]

[########## 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)


推荐答案

结果是,Python将空行编码为\ n,但OneNote需要\\\\ n。在最终边界之后还需要一个空行(\\\\ n)。最后,它不能在Content-Type和Content-Disposition行的正文中有任何前导空格(没有缩进)。(每个Content-Disposition行后面也应该有一个空行。)

The answer it turns out is that Python encodes blank lines as "\n" but OneNote requires "\r\n". It also requires a blank line ("\r\n") after the final boundary. Finally, it can't have any leading whitespace in the body (no indents) for the Content-Type and Content-Disposition lines. (There should also be a blank line after each Content-Disposition line.)

例如,如果这是正文:

"""--MyBoundary
Content-Type: text/html
Content-Disposition: form-data; name="Presentation"

Some random text
--MyBoundary
Content-Type: text/text
Content-Disposition: form-data; name="more"; filename="more.txt"

More text
--MyBoundary--
"""

它应该用字符串表示

'--MyBoundary\r\nContent-Type: text/html\r\nContent-Disposition: form-data; name="Presentation"\r\n\r\nSome random text\r\n--MyBoundary\r\nContent-Type: text/text\r\nContent-Disposition: form-data; name="more"; filename="more.txt"\r\n\r\nMore text\r\n--MyBoundary--\r\n' 

哪个可以只需在三个引号内键入文本(在最后的字符串中自动创建\ n,只要有空行),然后将\ n替换为\\ n:

which can be made just by typing the text inside three """ quotes (which will automatically create \n in the final string wherever there's a blank line) and then replacing the "\n" with "\r\n":

body = body.replace("\n", "\r\n")

标题为:

headers = {"Content-Type":"multipart/form-data; boundary=MyBoundary",
           "Authorization" : "bearer " + access_token} 

最后,你会像这样发布一个电话:

Finally, you would POST the call like this:

session = requests.Session()
request = requests.Request(method="POST", headers=headers,
                           url=url,  data=body)
prepped = request.prepare()
response = session.send(prepped)

这篇关于如何使用Python向OneNote发送多部分PDF请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆