Notrition - Using Python and the Notion API
Everyone has different ways to unwind. For me, after a long day, I like to spend time in the kitchen trying out different recipes and making new meals I might not have tried before. If I find one I particularly like and I can use techniques and ingredients in other recipes, great! I want to save those! The main issue is, a lot of the more unique meals come from smaller blogs which may go offline. A broken link on an empty stomach is not ideal.
There’s also the problem of how long some recipes are before they get to the actual recipe itself. The backstory, the long information on why they love a certain ingredient, excessive photos etc. I wanted to have recipes saved where I control them, with the information I want.
Enter Notion. I use Notion for most of my note taking and record keeping. It’s the perfect place to store my recipes! But manually entering recipes into a Notion database and trying to maintain consistency among the recipes is time consuming and annoying. To fix this, I put together a quick Python script to automate this process with the Notion API.
Who doesn’t love finding a great library that fits the needs of your project and in active development? This recipe-scraper project has a huge number of supported websites and I’m finding it rare to run the script against a recipe from a website and for it to not be supported. And with the project being so active, new websites are always being added. So much food to eat!
Setting up Notion
The calls we make to the Notion API require a specific body to be sent that matches the Notion page and database that I’ve set up. Luckily users can clone this page with an empty database from my own Notion workspace. We just need a Notion API key and the Notion Database ID:
headers = {
"Authorization": "Bearer " + token,
"Content-Type": "application/json",
"Notion-Version": "2022-06-28"
}
payload = {
"parent": {
"database_id": database_id
},
This is not exactly the most user friendly method, but we can update these values in the script before running so Notion knows where to put this. Then we can see each column’s intended value being passed in the payload. For example, here’s the Cook Time portion of the request body:
"Cook Time ⏰ ": {
"type": "rich_text",
"rich_text": [
{
"type": "text",
"text": {
"content": cookingTime
}
}
]
},
Who doesn’t love API payload emojis? I promise it’s not needless complication - it does look good in Notion! One all of this is built, we can hit the API like so:
token = '' //enter your token here
database_id = '' //enter your Notion database ID here
url = "<https://api.notion.com/v1/pages>"
r = requests.post(url, data=json.dumps(payload), headers=headers)
We run the script with the recipe URL as the single parameter. Assuming we get a HTTP 201, let’s eat! If not, time to order a pizza and debug. This is a very hacky solution to a real problem I had, but it could definitely be better for UX and for hungry non-technical people. I’m working on building this into a mobile app that makes it easier to add recipes.