Notion API Python 연동 방법|초보자도 따라하는 예제

Notion은 단순한 메모 앱을 넘어 강력한 올인원 워크스페이스로 자리 잡았습니다. 하지만 데이터베이스에 반복적인 정보를 수동으로 입력하는 작업은 여전히 번거로운 일입니다. Python과 Notion API를 연동하면 이러한 반복 업무를 자동화하고, 외부 데이터를 노션으로 실시간 동기화하거나, 나만의 커스텀 대시보드를 구축하는 등 무한한 확장이 가능합니다.

이 글에서는 개발 지식이 깊지 않은 초보자도 쉽게 따라 할 수 있도록, Notion API 토큰 발급부터 Python 코드를 이용한 데이터 조회 및 생성(CRUD) 과정까지 단계별로 상세히 설명합니다.

목차


1. Notion API 연동의 핵심 원리



Notion API를 다루기 전에 전체적인 흐름을 이해하는 것이 중요합니다. 우리가 Python 스크립트에서 노션 서버로 요청(Request)을 보내면, 노션은 이를 처리하여 결과를 응답(Response)으로 돌려줍니다. 이 과정에서 가장 중요한 두 가지 요소는 ‘인증(Authentication)’‘권한(Permission)’입니다.

  • Internal Integration Token (시크릿 키): 노션이 “누가 요청했는지”를 식별하는 비밀번호 역할을 합니다.
  • Database ID: “어디에 데이터를 넣을지”를 결정하는 주소입니다.
  • 연결(Connection): 보안을 위해, API 봇이 접근할 수 있는 페이지를 사용자가 직접 허용해 주어야 합니다.

이 세 가지 요소가 정확히 맞물려야 404 Not Found401 Unauthorized 오류 없이 데이터를 주고받을 수 있습니다.

2. 사전 준비: API 통합(Integration) 만들기

가장 먼저 노션 개발자 포털에서 API 사용을 위한 통합을 생성해야 합니다.

  1. Notion Developers 접속: Notion Developers 포털에 접속하여 로그인합니다.
  2. 내 통합(My integrations) 메뉴 이동: 우측 상단의 ‘My integrations’ 메뉴를 클릭합니다.
  3. 새 통합 만들기: + New integration 버튼을 클릭합니다.
  4. 기본 정보 입력:
    • Name: 식별하기 쉬운 이름(예: My Python Bot)을 입력합니다.
    • Associated workspace: 연동할 워크스페이스를 정확히 선택합니다.
    • Type: Internal(내부용)을 선택합니다.
  5. 시크릿 키 복사: 생성이 완료되면 Internal Integration Secret이 발급됩니다. secret_으로 시작하는 이 문자열을 복사하여 메모장 등 안전한 곳에 보관하세요. 이 키는 절대 외부에 노출되어서는 안 됩니다.

3. 데이터베이스 ID 확인 및 권한 부여



많은 초보자가 API 키만 있으면 모든 페이지에 접근할 수 있다고 오해하여 실패를 겪습니다. 노션 API는 사용자가 명시적으로 초대한 페이지에만 접근할 수 있습니다.

1. 연결(Connection) 추가
데이터를 연동할 노션 데이터베이스 페이지로 이동합니다. 우측 상단의 ... (더보기) 아이콘을 클릭하고, 아래쪽의 Add connections(연결 추가) 메뉴에서 방금 생성한 통합 앱(My Python Bot)을 찾아 선택합니다. 팝업 창이 뜨면 승인합니다.

2. 데이터베이스 ID 추출
해당 데이터베이스 페이지의 URL을 복사합니다. URL 구조는 보통 다음과 같습니다.

https://www.notion.so/myworkspace/{database_id}?v={view_id}

https://www.notion.so/?v= 사이의 32자리 영문/숫자 조합이 바로 Database ID입니다. 만약 페이지 안에 인라인(Inline)으로 데이터베이스가 있다면, 데이터베이스 제목을 클릭하여 ‘전체 페이지로 열기’를 한 후 URL을 확인하는 것이 정확합니다.

4. Python 개발 환경 설정

이제 Python 환경을 세팅합니다. HTTP 요청을 쉽게 처리하기 위해 requests 라이브러리를 사용합니다. 터미널(또는 CMD)을 열고 아래 명령어를 입력하여 설치합니다.

pip install requests

코드 작성을 위해 main.py 파일을 생성하고, 앞서 구한 시크릿 키와 데이터베이스 ID를 변수로 설정합니다.

import requests
import json

NOTION_TOKEN = "secret_YOUR_INTEGRATION_KEY_HERE"
DATABASE_ID = "YOUR_DATABASE_ID_HERE"

# 공통 헤더 설정
headers = {
    "Authorization": "Bearer " + NOTION_TOKEN,
    "Content-Type": "application/json",
    "Notion-Version": "2022-06-28"  # 최신 API 버전 확인 권장
}

참고: Notion-Version 헤더는 필수입니다. 버전을 명시하지 않으면 요청이 거부될 수 있습니다.

5. 실전 코드: 노션 데이터베이스 읽기 (Read)



데이터베이스에 있는 정보를 가져오는(Query) 코드입니다. 필터링 없이 모든 데이터를 조회하는 가장 기본적인 형태입니다.

def read_database(database_id, headers):
    read_url = f"https://api.notion.com/v1/databases/{database_id}/query"

    response = requests.post(read_url, headers=headers)

    if response.status_code == 200:
        data = response.json()
        # 결과 출력 (보기 좋게 정렬)
        # print(json.dumps(data, indent=4, ensure_ascii=False)) 

        # 각 페이지의 제목만 추출하여 출력 예시
        for result in data["results"]:
            try:
                # 'Name'은 데이터베이스의 제목 속성 이름입니다. 상황에 맞게 변경하세요.
                title = result["properties"]["Name"]["title"][0]["text"]["content"]
                print(f"페이지 제목: {title}")
            except IndexError:
                print("제목이 없는 페이지입니다.")
    else:
        print(f"Error: {response.status_code}")
        print(response.text)

# 실행
read_database(DATABASE_ID, headers)

이 코드를 실행하면 JSON 형태의 방대한 데이터 중, results 리스트를 순회하며 각 행(Page)의 제목을 출력합니다. 노션 데이터 구조는 중첩이 깊기 때문에 json.dumps()로 전체 구조를 먼저 확인해보는 것이 좋습니다.

6. 실전 코드: 노션 페이지 생성하기 (Create)

Python에서 데이터를 가공하여 노션에 새로운 페이지(행)를 추가하는 방법입니다. 여기서는 제목(Title)과 간단한 텍스트(Rich Text), 태그(Select) 속성을 입력하는 예제를 다룹니다.

def create_page(database_id, headers, title_text, tag_name):
    create_url = "https://api.notion.com/v1/pages"

    new_page_data = {
        "parent": {"database_id": database_id},
        "properties": {
            "Name": { # 데이터베이스의 제목 열 이름 (기본값: Name)
                "title": [
                    {"text": {"content": title_text}}
                ]
            },
            "상태": { # '상태'라는 이름의 Select 속성이 있다고 가정
                "select": {
                    "name": tag_name
                }
            },
            "설명": { # '설명'이라는 이름의 Text 속성이 있다고 가정
                "rich_text": [
                    {"text": {"content": "Python API로 자동 생성된 페이지입니다."}}
                ]
            }
        }
    }

    data = json.dumps(new_page_data)
    response = requests.post(create_url, headers=headers, data=data)

    if response.status_code == 200:
        print("성공적으로 페이지가 생성되었습니다!")
    else:
        print(f"생성 실패: {response.status_code}")
        print(response.text)

# 실행
create_page(DATABASE_ID, headers, "API 테스트 페이지", "진행중")

위 코드를 실행한 뒤 노션 페이지를 새로고침 해보면, ‘API 테스트 페이지’라는 제목과 ‘진행중’ 태그가 달린 새 데이터가 추가된 것을 확인할 수 있습니다.

7. 트러블슈팅 및 마무리



연동 과정에서 자주 발생하는 오류는 대부분 다음과 같습니다.

  1. 401 Unauthorized: 토큰 값이 잘못되었거나 Bearer 접두사를 빼먹은 경우입니다.
  2. 404 Not Found: 데이터베이스 ID가 틀렸거나, 노션 페이지에서 봇(Integration)을 초대한 후 연결 권한을 주지 않은 경우입니다. 반드시 해당 데이터베이스 페이지의 설정에서 연결을 확인하세요.
  3. 400 Bad Request: JSON 페이로드 구조가 노션 API 스키마와 맞지 않는 경우입니다. 특히 properties 내부의 키 값(“Name”, “태그” 등)은 실제 노션 데이터베이스의 칼럼명과 정확히 일치해야 합니다.

Python과 Notion API의 연동은 업무 자동화의 시작입니다. 이를 응용하면 매일 아침 뉴스를 크롤링하여 노션에 요약 정리하거나, 구글 캘린더 일정을 노션으로 동기화하는 등 강력한 시스템을 구축할 수 있습니다. 지금 바로 작은 프로젝트부터 시작해 보시기 바랍니다.


관련 글 보기