{"id":13657997,"url":"https://github.com/MerkulovDaniil/notion4ever","last_synced_at":"2025-04-24T08:31:06.155Z","repository":{"id":37944965,"uuid":"452619821","full_name":"MerkulovDaniil/notion4ever","owner":"MerkulovDaniil","description":"🏛 Python tool for export all your content of Notion page using official Notion API. Includes: all nested subpages, markdown files and HTMLs, nice urls, downloading locally all its content.","archived":false,"fork":false,"pushed_at":"2025-01-04T18:13:17.000Z","size":10748,"stargazers_count":148,"open_issues_count":4,"forks_count":11,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-04T19:22:27.844Z","etag":null,"topics":["markdown","notion","notion-api","python","static-site"],"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/MerkulovDaniil.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-27T09:32:51.000Z","updated_at":"2025-01-04T18:13:20.000Z","dependencies_parsed_at":"2024-11-10T11:32:52.491Z","dependency_job_id":"6549d04b-db77-4195-b4cb-05ac61287dde","html_url":"https://github.com/MerkulovDaniil/notion4ever","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MerkulovDaniil%2Fnotion4ever","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MerkulovDaniil%2Fnotion4ever/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MerkulovDaniil%2Fnotion4ever/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MerkulovDaniil%2Fnotion4ever/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MerkulovDaniil","download_url":"https://codeload.github.com/MerkulovDaniil/notion4ever/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250591941,"owners_count":21455469,"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":["markdown","notion","notion-api","python","static-site"],"created_at":"2024-08-02T05:00:54.957Z","updated_at":"2025-04-24T08:31:01.138Z","avatar_url":"https://github.com/MerkulovDaniil.png","language":"Python","funding_links":[],"categories":["HarmonyOS","Python","APIs"],"sub_categories":["Windows Manager"],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/MerkulovDaniil/notion4ever/assets/cb.svg\" width=\"256\" alt=\"\"\u003e\n  \u003ch1\u003eNOTION4EVER\u003c/h1\u003e\n\u003c/div\u003e\n\nNotion4ever is a small python tool that allows you to free your content and export it as a collection of markdown and HTML files via the official Notion API.\n\n# ✨ Features\n* Export ready to deploy static HTML pages from your Notion.so pages.\n    ![root_page](https://raw.githubusercontent.com/MerkulovDaniil/notion4ever/assets/root_page.png)\n* Supports nice urls.\n* Downloads all your Notion content, which is accessible via API to a raw JSON file. \n* Uses official Notion API (via [notion-sdk-py](https://github.com/ramnes/notion-sdk-py), but you can use curls if you want).\n* Supports arbitrary page hierarchy.\n    ![breadcrumb](https://raw.githubusercontent.com/MerkulovDaniil/notion4ever/assets/breadcrumb.png)\n*  Supports galleries and lists\n    ![gallery](https://raw.githubusercontent.com/MerkulovDaniil/notion4ever/assets/gallery.png)\n\n    ![list](https://raw.githubusercontent.com/MerkulovDaniil/notion4ever/assets/list.png)\n\n    Note that Notion API does not provide information about the database view yet. That is why notion4ever will render the database as a list if any database entries do not have a cover. Suppose all entries have covers, then it will be displayed as a gallery.\n* Lightweight and responsive.\n* Downloads all your images and files locally (you can turn this off if you prefer to store images\\files somewhere else).\n\n# 💻 How to run it locally\nJust copy or clone the content of this repository and run.\n\n```python\npython -m notion4ever -n NOTION_TOKEN -p NOTION_PAGE_ID -bl True\n``` \n# 🤖 How to run it automatically with Github actions\nI will demonstrate it on the specific example of my site.\n[Notion page](https://fmin.notion.site/Danya-Merkulov-12e3d1659a444678b4e2b6a989a3c625) -\u003e [Github repository](https://github.com/MerkulovDaniil/merkulovdaniil.github.io/)\n\n## ✅ Step 1. Create/choose some page in Notion.\n1. We will need the page ID. For example, the page with URL\n`https://fmin.notion.site/Danya-Merkulov-12e3d1659a444678b4e2b6a989a3c625` has the following ID: `12e3d1659a444678b4e2b6a989a3c625`.\n1. Also, we will need to create a Notion API token. Go to [Notion.so/my-integrations](https://www.notion.so/my-integrations) -\u003e `Create new integration`. Type the name of the integration and press `submit`. Now you can see your token, which starts with `secret_***` under the `Internal Integration Token` field.\n1. Do not forget to grant access for your integration to edit your page. Go to `Share -\u003e invite -\u003e {YOUR INTEGRATION NAME}`.\n\n## ✅ Step 2. Set up a repository for your static site.\nIn my case, it is [github.com/MerkulovDaniil/merkulovdaniil.github.io/](https://github.com/MerkulovDaniil/merkulovdaniil.github.io/). \n1. You need to specify your Notion settings in a Github action secret. Jump to the `Settings -\u003e Secrets -\u003e Actions -\u003e New repository secret` and create two secrets:\n    a. NOTION_PAGE_ID\n    b. NOTION_TOKEN\n\n    ![github_secret](https://raw.githubusercontent.com/MerkulovDaniil/notion4ever/assets/github_secret.png)\n\n1. Create and configure the following GitHub action in your repository:\n\n\u003cdetails\u003e \u003csummary\u003e\u003ccode\u003epublish.yml\u003c/code\u003e\u003c/summary\u003e        \n\n```yaml\nname: Deploy from Notion to Pages\n\n# on: [workflow_dispatch]\non:\n  schedule:\n    - cron: \"0 */12 * * *\" \n    \njobs:\n  download_old-generate-push:\n    runs-on: ubuntu-latest\n    \n    steps:\n        # Download packages\n      - name: Submodule Update\n        run: |\n          wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb\n          sudo apt install ./google-chrome-stable_current_amd64.deb\n          sudo apt-get update\n          \n      - name: Set up Python\n        uses: actions/setup-python@v2\n        with:\n          python-version: 3.10.0\n          \n      - name: Download notion4ever\n        uses: actions/checkout@v2\n        with:\n          repository: 'MerkulovDaniil/notion4ever'\n          \n      - name: Install packages\n        run: pip install -r requirements.txt\n        \n      - name: Download current version of the site\n        uses: actions/checkout@v2\n        with:\n          # HERE, YOU NEED TO PLACE YOUR REPOSITORY\n          repository: 'MerkulovDaniil/merkulovdaniil.github.io'\n          # TARGET BRANCH\n          ref: main\n          # THE FOLDER, WHERE NOTION4EVER EXPORTS YOUR CONTENT BY DEFAULT\n          path: _site\n          \n      - name: Run notion4ever\n        run: python -m notion4ever\n        env:\n            # HERE YOU NEED TO PLACE URL OF THE ROOT PAGE. PROBABLY IT IS \"https://\u003cusername\u003e.github.io\"\n            SITE_URL: \"https://merkulov.top\"\n            NOTION_TOKEN: ${{secrets.NOTION_TOKEN}}\n            NOTION_PAGE_ID: ${{secrets.NOTION_PAGE_ID}}\n      \n      - name: Deploy to Pages\n        uses: JamesIves/github-pages-deploy-action@3.7.1\n        with:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          BRANCH: main\n          FOLDER: _site\n          COMMIT_MESSAGE: 🤖 Deployed via notion4ever.\n``` \n\u003c/details\u003e\n\nThis script will run every 12 hours, and you can change it. Note that the first run could be slow if your page contains a lot of content, but all the subsequent runs will not download existing files.\nCongratulations 🤗!\n\n# 🛠 How it works\n1. Given your notion token and ID of some page, notion4ever downloads all your content from this page and all nested subpages and saves it in a JSON file, `notion_content.json`.\n1. Given your raw Notion data, notion4ever structures the page's content and generates file `notion_structured.json` with markdown content of all pages and relations between them. Markdown parsing is done via modification of [notion2md](https://github.com/echo724/notion2md) library.\n1. Given structured notion content, notion4ever generates site from [jinja](https://github.com/pallets/jinja/) templates located in `./_templates` directory. All styles are located in `./_sass` directory and compiled with [libsass-python](https://github.com/sass/libsass-python) library. By default, site is located in `./_site` directory\n\n# 🌈 Alternatives\n## 🆓 Free\n* [loconotion](https://github.com/leoncvlt/loconotion) - Python tool to turn Notion.so pages into lightweight, customizable static websites.\n* [NotoCourse](https://github.com/MerkulovDaniil/NotoCourse) - properly configured github actions + structuring for loconotion.\n* [notablog](https://github.com/dragonman225/notablog) - blog-oriented static site generator from Notion database.\n* [popsy.co](popsy.co) - turns your Notion docs into a site with custom domain.\n\n## 💰 Paid\n* [helpkit.so](helpkit.so) - turns your Notion docs into a hosted self-service knowledge base. \n* [float.so](float.so) - turns your docs in Notion into online course.\n* [super.so](super.so) - turns your Notion docs into a site.\n* [potion.so](https://potion.so/) - turns your Notion docs into a site.\n\n# 🦄 Examples\nPlease, add your sites here if you are using Notion4ever.\n| \u003cimg src=\"https://raw.githubusercontent.com/MerkulovDaniil/notion4ever/assets/notion_logo.svg\" width=\"15\" height=\"15\"\u003e Notion public page | \u003cimg src=\"https://raw.githubusercontent.com/MerkulovDaniil/notion4ever/assets/cb.svg\" width=\"15\" height=\"15\"\u003e Notion4ever web page  |\n|---|---|\n| [My personal page](https://fmin.notion.site/Danya-Merkulov-12e3d1659a444678b4e2b6a989a3c625)  |  [My personal page](https://merkulov.top) |\n| [MIPT optimization course](https://fmin.notion.site/00ef4311866942fd8efd351cc976959c)  |  [MIPT optimization course](https://opt.mipt.ru) |\n \n\n# ToDo\n- [ ] Proper documentation.\n- [ ] Create pip package.\n- [ ] Add parallel files downloading.\n- [ ] Add search field. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMerkulovDaniil%2Fnotion4ever","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMerkulovDaniil%2Fnotion4ever","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMerkulovDaniil%2Fnotion4ever/lists"}