2

I am currently trying to informally connect to the Notion homepage to upload an image. The reason for using informal API is that it does not allow us to upload images from our local folders.

With that said, I successfully connected to my homepage using token_v2 and created an image block using children.add_new('image'). However, when I tried to upload an image, I ran across 403 Client Error.

I've been trying to solve this issue for a few days so please let me know if there's anything I'm missing. Below is my code.

from notion.client import NotionClient

def uploadEvaluationJPG():
    token_v2 = secret.notion_API("token_v2")
    client = NotionClient(token_v2=token_v2)
    # connect page
    url = 'https://www.notion.so/Home-******************************'
    page = client.get_block(url)
            
    newchild = page.children.add_new('image')
    newchild.upload_file(r"C:\NotionUpdate\progress\jpg files\Monthly Evaluation\month.jpg")
    newchild.move_to(page.children[1],"before")
    page.children[0].remove()  

Error Code

Traceback (most recent call last):

  Input In [8] in <cell line: 11>
    newchild.upload_file(r"C:\NotionUpdate\progress\jpg files\Monthly Evaluation\month.jpg")

  File ~\AppData\Roaming\Python\Python39\site-packages\notion\block.py:641 in upload_file
    data = self._client.post(

  File ~\AppData\Roaming\Python\Python39\site-packages\notion\client.py:265 in post
    response.raise_for_status()

  File ~\AppData\Roaming\Python\Python39\site-packages\requests\models.py:909 in raise_for_status
    raise HTTPError(http_error_msg, response=self)

HTTPError: 403 Client Error: Forbidden for url: https://www.notion.so/api/v3/getUploadFileUrl
Andy Lee
  • 43
  • 4
  • almost identical code to the one you posted was working until recently. Now it has started failing with the same error you have reported. I can only assume something has changed in Notion's end that has broken that part of the integration. I've spent some time looking into it but I couldn't find a solution yet. – PaulaF Jun 07 '22 at 11:38
  • That's what I have figured after an extensive search. Please let me know if you ever find a solution. – Andy Lee Jun 08 '22 at 16:04
  • As an alternative, we are thinking of uploading the files to google drive and add the link to Notion. It's not as good as adding the file directly to Notion but it is better than nothing, maybe that works out for you too. – PaulaF Jun 13 '22 at 08:05

1 Answers1

8

The code is correct, it appears that Cloudflare is blocking the requests before they reach Notion.

If we run the request in Postman using the cloud agent, we get a successful response 200. Choosing the desktop agent, though, we get the 403 Forbidden message. Furthermore, we can also preview the reason for it. It says:

Please stand by, while we are checking your browser...

So it seems that Notion/Cloudflare doesn't like the origin of the request.

Notion has an official API now, but sadly file upload is not implemented yet and we will have to wait for it. Many other things may start failing in the unofficial API if they tighten security.

To replicate in Postman:

url: https://www.notion.so/api/v3/getUploadFileUrl

body:

{"bucket":"secure","name":"envs.toml","contentType":"text/plain; charset=utf-8"}

For authentication, create a header called cookie with the value token_v2=your_token

PaulaF
  • 106
  • 4
  • 1
    this would be too big for a comment anyway and looks very complete, why do you think this would be a comment? – nbk Jun 10 '22 at 12:13
  • It doesn't really offer a solution :) though I'm starting to think there isn't one! I'll edit that bit. – PaulaF Jun 10 '22 at 13:03
  • This post is being discussed on [meta]: [How should I handle this post in LQ review?](https://meta.stackoverflow.com/questions/418628/how-should-i-handle-this-post-in-lq-review) – Thom A Jun 10 '22 at 14:32
  • As it seems likely that this will be deleted, I've updated it to make it shorter in the hopes that it can stay... I still think that it might be useful to other people. – PaulaF Jun 10 '22 at 16:25
  • 1
    Shorter isn't always better; if there was useful info for future readers, it's totally fine to have that in a section at the end. The key thing is that an answer does have to at least try to answer the question, or explain why it's not possible or sensible to do so and propose an alternative. Sometimes that doesn't take much space, and can be a small section at the top. Or a TL:DR version at the top, and then a longer version of the same answer which explains how the pieces fit together, after readers know what the big picture is that they're trying to grok. – Peter Cordes Jun 12 '22 at 04:20
  • (I'm not familiar with the subject matter so I haven't really looked at the question, or your longer answer, so IDK how much of that is applicable. If you have wisdom to share, but it's not a good fit for this answer, you could consider posting a self-answered Q&A, then you can link it from any other answer where it's relevant. Or if there's a common problem that people often run into, a self-answered Q&A with a canonical answer can be a good target for closing duplicates with less clearly stated questions, if no existing question is a good place to put a canonical answer.) – Peter Cordes Jun 12 '22 at 04:23
  • The first time I answered it was because I had run into the same problem and maybe I gave too much detail into the process I followed to find out what was wrong without explicitly answering. I think the edited version now does indeed answer the question. There is no issue with the code, requests are being blocked by increased security. Maybe someone will find a better answer, like a way to bypass those security checks, or an alternative package that does indeed works. But if no one does, my answer will still help other people. – PaulaF Jun 12 '22 at 08:52