{"id":17302171,"url":"https://github.com/lolipopshock/notion-df","last_synced_at":"2025-05-07T09:45:27.440Z","repository":{"id":37744858,"uuid":"444271320","full_name":"lolipopshock/notion-df","owner":"lolipopshock","description":"Seamlessly Connecting Notion Database with Python Pandas DataFrame","archived":false,"fork":false,"pushed_at":"2023-09-08T13:42:30.000Z","size":62,"stargazers_count":88,"open_issues_count":22,"forks_count":14,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-16T03:17:59.326Z","etag":null,"topics":["notion","notion-api","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lolipopshock.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-04T03:17:48.000Z","updated_at":"2025-03-07T22:01:55.000Z","dependencies_parsed_at":"2024-06-19T19:03:16.880Z","dependency_job_id":"76acf601-185b-4423-ba97-c347937f46de","html_url":"https://github.com/lolipopshock/notion-df","commit_stats":{"total_commits":49,"total_committers":2,"mean_commits":24.5,"dds":"0.020408163265306145","last_synced_commit":"df9e78bec3a682dd71ed39729676342f1b05c855"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lolipopshock%2Fnotion-df","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lolipopshock%2Fnotion-df/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lolipopshock%2Fnotion-df/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lolipopshock%2Fnotion-df/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lolipopshock","download_url":"https://codeload.github.com/lolipopshock/notion-df/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252854011,"owners_count":21814618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["notion","notion-api","python"],"created_at":"2024-10-15T11:46:46.563Z","updated_at":"2025-05-07T09:45:27.421Z","avatar_url":"https://github.com/lolipopshock.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `notion-df`: Seamlessly Connecting Notion Database with Pandas DataFrame\n\n*Please Note: This project is currently in pre-alpha stage. The code are not appropriately documented and tested. Please report any issues you find. Thanks!*\n\n## Installation\n\n```bash\npip install notion-df\n```\n\n## Usage\n\n- Before starting, please follow the instructions to [create a new integration](https://www.notion.com/my-integrations) and [add it to your Notion page or database](https://developers.notion.com/docs/getting-started#step-2-share-a-database-with-your-integration). \n    - We'll refer `Internal Integration Token` as the `api_key` below.\n\n- Pandas-flavored APIs: Just need to add two additional lines of code:\n    ```python\n    import notion_df\n    notion_df.pandas() #That's it!\n    \n    page_url = \"paste your page url from Notion\"\n    api_key = \"paste your api key (internal integration key)\"\n    \n    import pandas as pd\n    df = pd.read_notion(page_url, api_key=api_key)\n    df.to_notion(page_url, api_key=api_key)\n    ```\n\n- Download your Notion table as a pandas DataFrame\n    ```python\n    import notion_df\n    df = notion_df.download(notion_database_url, api_key=api_key)\n    # Equivalent to: df = pd.read_notion(notion_database_url, api_key=api_key)\n    df.head()\n    ```\n    \u003cdetails\u003e\n    \u003csummary\u003eOnly downloading the first `nrows` from a database\u003c/summary\u003e\n    \n    ```python\n    df = notion_df.download(notion_database_url, nrows=nrows) #e.g., 10\n    ```\n\n    \u003c/details\u003e\n    \n    \u003cdetails\u003e\n    \u003csummary\u003eWhat if your table has a relation column?\u003c/summary\u003e\n    \n    ```python\n    df = notion_df.download(notion_database_url, \n                            resolve_relation_values=True)\n    ```\n    The `resolve_relation_values=True` will automatically resolve the linking for all the relation columns whose target can be accessed by the current notion integration.\n\n    In details, let's say the `\"test\"` column in df is a relation column in Notion. \n    1. When `resolve_relation_values=False`, the return results for that column will be a list of UUIDs of the target page: `['65e04f11-xxxx', 'b0ffcb4b-xxxx', ]`. \n    2.  When `resolve_relation_values=True`, the return results for that column will be a list of regular strings corresponding to the name column of the target pages: `['page1', 'page2', ]`. \n\n    \u003c/details\u003e\n\n- Append a local `df` to a Notion database:\n\n    ```python\n    import notion_df\n    notion_df.upload(df, notion_database_url, title=\"page-title\", api_key=api_key)\n    # Equivalent to: df.to_notion(notion_database_url, title=\"page-title\", api_key=api_key)\n    ```\n\n- Upload a local `df` to a newly created database in a Notion page:\n    \n    ```python\n    import notion_df\n    notion_df.upload(df, notion_page_url, title=\"page-title\", api_key=api_key)\n    # Equivalent to: df.to_notion(notion_page_url, title=\"page-title\", api_key=api_key)\n    ```\n\n- Tired of typing `api_key=api_key` each time?\n\n    ```python\n    import notion_df\n    notion_df.config(api_key=api_key) # Or set an environment variable `NOTION_API_KEY`\n    df = notion_df.download(notion_database_url)\n    notion_df.upload(df, notion_page_url, title=\"page-title\")\n    # Similarly in pandas APIs: df.to_notion(notion_page_url, title=\"page-title\")\n    ```\n\n## Development \n\n1. Clone the repo and install the dependencies:\n    ```bash\n    git clone git@github.com:lolipopshock/notion-df.git\n    cd notion-df\n    pip install -e .[dev]\n    ```\n2. How to run tests?\n    ```bash\n    NOTION_API_KEY=\"\u003cthe-api-key\u003e\" pytest tests/\n    ```\n    The tests are dependent on a list of notebooks, specified by the following environment variables:\n    \n| Environment Variable        | Description                             |\n| --------------------------- | --------------------------------------- |\n| `NOTION_API_KEY`            | The API key for your Notion integration |\n| `NOTION_ROLLUP_DF`          | -                                       |\n| `NOTION_FILES_DF`           | -                                       |\n| `NOTION_FORMULA_DF`         | -                                       |\n| `NOTION_RELATION_DF`        | -                                       |\n| `NOTION_RELATION_TARGET_DF` | -                                       |\n| `NOTION_LONG_STRING_DF`     | -                                       |\n| `NOTION_RICH_TEXT_DF`       | -                                       |\n    \n\n## TODOs\n\n- [ ] Add tests for\n    - [ ] `load` \n    - [ ] `upload` \n    - [ ] `values.py`\n    - [ ] `configs.py`\n    - [ ] `base.py`\n- [ ] Better class organizations/namings for `*Configs` and `*Values`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flolipopshock%2Fnotion-df","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flolipopshock%2Fnotion-df","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flolipopshock%2Fnotion-df/lists"}