A command line utility to export Google Keep notes to markdown.

Overview

Keep-Exporter

A command line utility to export Google Keep notes to markdown files with metadata stored as a frontmatter header.

Supports exporting:

  • Simple notes
  • List notes
  • Images and Drawings
  • Audio clips
  • Link annotations

Usage

If you do not supply a username or password before running it, you will be prompted to input them.

Usage: keep_export [OPTIONS]
Options:
  --config FILE                   Read configuration from FILE.
  -u, --user TEXT                 Google account email (prompt if empty)  [env var: GKEEP_USER; required]
  -p, --password TEXT             Google account password (prompt if empty). Either this or token is required.  [env
                                  var: GKEEP_PASSWORD]

  -t, --token TEXT                Google account token from prior run. Either this or password is required.
  -d, --directory DIRECTORY       Output directory for exported notes  [default: ./gkeep-export]
  --header / --no-header          Choose to include or exclude the frontmatter header  [default: True]
  --delete-local / --no-delete-local
                                  Choose to delete or leave as-is any notes that exist locally but not in Google Keep
                                  [default: False]

  --rename-local / --no-rename-local
                                  Choose to rename or leave as-is any notes that change titles in Google Keep
                                  [default: False]

  --date-format TEXT              Date format to use for the prefix of the note filenames. Reflects the created date
                                  of the note.  [default: %Y-%m-%d]

  --skip-existing-media / --no-skip-existing-media
                                  Skip existing media if it appears unchanged from the local copy.  [default: True]
  -h, --help                      Show this message and exit.

Notes

If you are using 2 Factor Authentication (2FA) for your google account, you will need to generate an app password for keep. You can do so on your Google account management page.

Installation

There are many ways to install this, easiest are through pip or the releases page.

Pip

The easiest way is with pip from PyPi

pip3 install keep-exporter

Download the Wheel

Download the wheel from the releases page and then install with pip:

pip install keep_exporter*.whl

Building

Download or git clone

  1. Clone the repository https://github.com/ndbeals/keep-exporter or download from the releases page and extract the source code.
  2. cd into the extracted directory
  3. With poetry installed, run poetry install in the project root directory
  4. poetry build will build the installable wheel
  5. cd dist then run pip3 install

Troubleshooting

Some users have had issues with the requests library detailed in this issue when using pipx. The solution is to change the requests library version.

pipx install keep-exporter 
pipx inject keep-exporter requests===2.23.0
Comments
  • Add support for specifying the config in a file, (partially) add resume token support

    Add support for specifying the config in a file, (partially) add resume token support

    This is a ~90% PR, but I'm not going to have time to work on this for the rest of the week, so figured I'd get it in front of you to consider / comment on.

    This adds support for loading settings from a config file using the module https://github.com/phha/click_config_file - it's a pretty decent module - it just loads each command line argument from the specified config file and falls back to normal behavior if no config file or the option is not specified in the config.

    I also added support for reading (but not writing) the resume token and using that instead of the password. I couldn't find a good way in Click to make two options mutually exclusive - I wanted token to negate the need for password, but if neither was specified, then prompt for password.

    The closest I found to an out-of-the-box solution was this module https://pypi.org/project/click-option-group/ - and some discussions from the project maintainer about how this type of thing was out of scope of the project, which doesn't make much sense to me. Honestly, I got frustrated with trying to implement it and rolled my own that's good enough.

    If you have better ideas, please let me know.

    Re resume token - I'm not sure:

    • how long the resume token lasts for - I've been using the same one for two days now
    • if it's any more secure than just storing an app password - the API implies it's still a full account access

    I'm just thinking Google is less likely to lock an account that polls frequently as suspicious if it uses the token.

    I think the program should probably save an updated token after every run, and I don't consider this really complete until that's done.

    opened by mbafford 10
  • Use mdutils, replace checkboxes, add link annotations

    Use mdutils, replace checkboxes, add link annotations

    As mentioned in #3 and #4 , this:

    • uses a markdown library (mdutils) to generate the markdown
    • converts the unicode checkbox symbols to markdown syntax
    • adds the link annotations to the end of the note

    Also:

    • strips titles to not have trailing/leading spaces
    • adds an "untitled" default for notes with blank titles

    I think it's probably even better to use note.children and note.checked to build the check list manually if that's the type of note - so the formatting can be even more safely converted to markdown, but I didn't look to heavily into that.

    Hope this helps - but if you don't want to merge this in, that's fine, I'll likely keep my variation on my github for my own use.

    opened by mbafford 6
  • How to run?

    How to run?

    I've tried to follow the instructions as best as I can, but can't figure out how to get this working.

    First of all, the instructions mentions this file "keep_export", but it's not found in any of the folders.

    I've got poetry installed and ran poetry build to build the wheel and everything during the install process went OK. I can't just figure out how to run. I tried running the export.py file and initially I got a click-config-file module missing error. I fixed that by doing pip3 install click-config-file and then I tried again and I got no more errors, but nothing happens when I ran the export.py file.

    I've got nothing like what is mentioned in the help file.

    opened by chaoscreater 5
  • Remove meta info from top of notes exported

    Remove meta info from top of notes exported

    Is it possible to remove the extra meta data from the top of exported notes?

    color: White deleted: false id: xxxxxxxxxxxxxxxxxx parent_id: root pinned: false sort: '0' timestamps: created: 1414924214.261 edited: 1414929007.851 trashed: -3600.0 updated: 1526783775.947 title: xxxx trashed: false type: List url: https://keep.google.com/u/0/#LIST/xxxxxxxxxxxxxxxxxxxxxxxxx

    Other than this, it worked perfectly! Many thanks

    opened by f0rkth1s 3
  • Convert

    Convert "label" json metadata to "tag" YAML metadata

    Google Keep has a feature called Labels, basically it acts like tags or categories. It would be amazing if they could be converted as tags in the YAML frontmatter. When exporting Google Keep with Takeout it gives a .json file with the metadata and Labels looks as below.

    ...
        "labels": [
            {
                "name": "tag1"
            },
            {
                "name": "tag2"
            }
        ]
    ...
    

    Convert from the metadata above to YAML:

    tags: tag1, tag2
    
    opened by agichim 2
  • frontmatter scanning, rename/delete local files, custom date prefix support

    frontmatter scanning, rename/delete local files, custom date prefix support

    Details in: https://github.com/ndbeals/keep-exporter/discussions/9#discussioncomment-304904

    Differs from your proposed approach, but works well in my testing and gives nice filenames.

    opened by mbafford 2
  • Download images and reference them in the Markdown output

    Download images and reference them in the Markdown output

    See this commit for a first rough pass at this: https://github.com/mbafford/keep-exporter/commit/43447684fd7265866bfe5bd6cd5e386594cccd3d

    The images API is undocumented, but I was able to piece together how to get the image URL from looking at the image URL in Google Keep and the gkeepapi code. This commit works for all of my notes as far as I can tell, but I'm sure it fails on some other edge case.

    The URL generated by the API is simply:

    https://keep.google.com/u/0/media/v2/{note.server_id}/{image.server_id}
    

    when Google Keep references the image, it also adds these parameters:

    ?accept=image/gif,image/jpeg,image/jpg,image/png,image/webp,audio/aac&sz=4032
    

    There's interesting metadata available in:

    note.images[0].blob, e.g.:

    'kind':'notes#blob'
    'type':'IMAGE'
    'mimetype':'image/jpeg'
    'width':3024
    'height':4032
    'byte_size':3162748
    'extracted_text':'味全\nwei-chuart\nが\n薺菜態 蝦 .\nChinese Spinach[...]'
    'extraction_status':'VSS_SUCCEEDED'
    

    No original image filename that I can find.

    TODO

    • check mimetype and write files with correct filenames
    • write the extracted OCR text to the markdown file or a sidecar JSON file?
    • not sure if the download has to happen through the keepAPI requests session
    • other types of images (drawings?) may be very different
    opened by mbafford 2
  • Include annotations - attached links

    Include annotations - attached links

    When you add a link to a keep note, Google adds the link as an annotation. These persist even if the link text is removed from the note.

    These can be added with something like this:

        if note.annotations.links:
            text = text + "\n## Links \n\n"
    
            for a in note.annotations.links:
                text += "- [%s](%s)\n" % ( a.title, a.url )
    

    Probably better to use a Markdown formatter to ensure the link title/URL won't cause problems.

    opened by mbafford 2
  • authentication issues with pipx and wrong requests version [solution]

    authentication issues with pipx and wrong requests version [solution]

    Just leaving this here for anyone encountering the same issue. From: https://github.com/kiwiz/gkeepapi/issues/81#issuecomment-762884244

    If you install using pipx you might have issues with authentication failing. This isn't an issue with the username/password, but an issue with one of the Python libraries. If you use 2.23.0 of requests, it works perfectly:

    pipx install keep-exporter 
    pipx inject keep-exporter requests===2.23.0
    

    I was then able to set up keep-exporter and sync my notes, using a Google app password.


    Thank you for publishing this project.

    opened by mbafford 2
  • Pull keep labels as tags

    Pull keep labels as tags

    Discussed in https://github.com/ndbeals/keep-exporter/discussions/10

    Originally posted by mbafford January 22, 2021 Not sure if this is worth an issue or not.

    I don't think the labels are being pulled from keep - would be nice to have those added as tags (frontmatter) on the resulting markdown file.

    Also, an option (or default) to add a consistent tag to the frontmatter indicating it is a Google Keep export.

    opened by ndbeals 1
  • Archived status missing from frontmatter (but there is both trashed and deleted)

    Archived status missing from frontmatter (but there is both trashed and deleted)

    Discussed in https://github.com/ndbeals/keep-exporter/discussions/11 by @mbafford

    Originally posted by mbafford January 22, 2021 I don't see any indication of archive status making it to the frontmatter. I see trashed and deleted, but I don't have any notes with those set to true.

    Assuming trashed precedes deleted.

    When does deleted become deleted?

    Confirmed the order is trashed (goes in Google Keep's "Trash" label), then you delete the note, and it becomes deleted and isn't returned by the API. The deleted doesn't seem to get a value - at least not in my rapid test.

    So, unless the "deleted" frontmatter metadata is used to indicate a note no longer being returned by the gkeep API - then it may never be a useful value.

    opened by ndbeals 1
  • Authentication failing

    Authentication failing

    This has been broken for a couple of months, fails with this error:

    Error: Invalid value: Password login failed: ('NeedsBrowser', 'To access your account, you must sign in on the web. Touch Next to start browser sign-in.')

    opened by soabwahott 0
  • Split/Broken checkboxes every few lines

    Split/Broken checkboxes every few lines

    In almost all of my files every few lines, seemingly at random, the content of checkboxes have been split into several lines like this:

    - [ ] Lorem ipsum 
    dolor sit amet
    - [ ] Lorem ipsum dolor sit amet
    - [ ] Lorem ipsum dolor sit amet
    - [ ] Lorem 
    ipsum 
    

    Some even have been split like so, breaking the checkbox:

    - [
     ] Lorem ipsum dolor sit amet
    - 
    [ ] Lorem ipsum dolor sit amet
    
    bug 
    opened by ltctceplrm 4
Releases(2.0)
Microsoft Azure CLI - Azure Command-Line Interface

A great cloud needs great tools; we're excited to introduce Azure CLI, our next generation multi-platform command line experience for Azure.

Microsoft Azure 3.4k Dec 30, 2022
CLI tool for one-line installation of C++/CMake projects.

cmakip When working on virtual environments, Python projects can be installed with a single command invocation, for example pip install --no-deps . .

Artificial and Mechanical Intelligence 4 Feb 15, 2022
A CLI messenger for the Signum community.

A CLI messenger for the Signum community. Built for people who like using terminal for their work and want to communicate with other users in the Signum community.

Jush 5 Mar 18, 2022
DShell, a tool that combines with discord.py and Jishaku to present to you, shell channels.

Discord shell or dshell for short is a Python package that combines with discord.py and Jishaku to transform an ordinary Discord channel into one capable of running bash commands using a Discord bot.

11 Nov 15, 2022
A CLI tool for creating disposable environments.

dispenv - Disposable Python Environments ⚠️ WIP Need to make an environment to work on a GitHub issue? Want to try out a new package and not leave the

Peter Baumgartner 3 Mar 14, 2022
A command line tool made in Python for the popular rhythm game

osr!name A command line tool made in Python for the popular rhythm game "osu!" that changes the player name of a .osr file (replay file). Example: Not

2 Dec 28, 2021
Kattis shell for getting examples, testing and submitting.

Kattis shell for getting examples, testing and submitting.

Simon Green Kristensen 15 Sep 30, 2022
💻 Physics2Calculator - A simple and powerful calculator for Physics 2

💻 Physics2Calculator A simple and powerful calculator for Physics 2 🔌 Predefined constants pi = 3.14159... k = 8988000000 (coulomb constant) e0 = 8.

Dylan Tintenfich 4 Dec 01, 2021
Runs a command in P4wnP1 and displays the output on OLED screen (SH1106)

p4wnp1-oled-terminal Runs a command in P4wnP1 and displays the output on OLED screen (SH1106) Works on Raspberry Pi Zero 2 W Tested successfully on RP

PawnSolo 1 Dec 14, 2021
🦎 A NeoVim plugin for highlighting visual selections like in a normal document editor!

🦎 HighStr.nvim A NeoVim plugin for highlighting visual selections like in a normal document editor! Demo TL;DR HighStr.nvim is a NeoVim plugin writte

Pocco81 222 Jan 03, 2023
A mini command line tool to spellcheck text files using tadqeek.alsharekh.org

tadqeek_sakhr A mini command line tool to spellcheck text files using tadqeek.alsharekh.org Usage usage: python tadqeek_sakhr.py [-h] -i INPUT [-o OUT

Youssif Shaaban Alsager 5 Dec 11, 2022
Wordle-solver - A tool that helps people who struggle with vocabulary to enjoy the famous game of WORDLE

Wordle-Solver Wordle-Solver helps people who struggle with vocabulary to enjoy t

Jason Chao 104 Dec 31, 2022
A communist shell written in Python

kash A communist shell written in Python It doesn't support escapes, quotes, comment lines, |, &&, , or similar yet. If you need help, get it from

Çınar Yılmaz 1 Dec 10, 2021
WA Terminal is a CLI application that allows us to login and send message with WhatsApp with a single command.

WA Terminal is a CLI application that allows us to login and send message with WhatsApp with a single command.

Aziz Fikri 15 Apr 15, 2022
A simple CLI tool for converting logs from Poker Now games to other formats

🂡 Poker Now Log Converter 🂡 A command line utility for converting logs from Poker Now games to other formats. Introduction Poker Now is a free onlin

6 Dec 23, 2022
CLI for SQLite Databases with auto-completion and syntax highlighting

litecli Docs A command-line client for SQLite databases that has auto-completion and syntax highlighting. Installation If you already know how to inst

dbcli 1.8k Dec 31, 2022
A multipurpose discord bot with more than 220 commands

Welcome WM Bot A advanced bot with more than 220 commands to fit your needs Explore the commands » View Demo · Report Bug · Request Feature Table of C

Wasi Master 12 Dec 16, 2022
A curated list of awesome things related to Textual

Awesome Textual | A curated list of awesome things related to Textual. Textual is a TUI (Text User Interface) framework for Python inspired by modern

Marcelo Trylesinski 5 May 08, 2022
TermPair lets developers securely share and control terminals in real time🔒

View and control terminals from your browser with end-to-end encryption 🔒

Chad Smith 1.5k Jan 05, 2023
Logic-Sim - A clone of 'Digital Logic Sim' from Sebastian Lague

Logic Simulator This is a clone of 'Digital Logic Sim' from Sebastian Lague. But

Ethan 1 Feb 01, 2022