Skip to main content

gmdoc

Pull and push Google Docs as Markdown, using the Drive API's built-in text/markdown conversion.

gmdoc borrows your access token from gcloud, so you don't need a Google Cloud project, OAuth client, or config file. It talks to the Drive REST API with the standard library, so its only dependency is cyclopts.

Install

brew install --cask gcloud-cli
gcloud auth login --enable-gdrive-access   # browser login, click Allow

uv tool install gmdoc
# or: pipx install gmdoc

Running the script directly also works — gmdoc.py declares its own dependencies in a PEP 723 header, so uv run gmdoc.py ... (or ./gmdoc.py ...) works anywhere, even if you copy just that one file.

Usage

gmdoc ls [name]                    # list recent docs
gmdoc pull <doc-url|id> [out.md]   # download (default name: <title>.md)
gmdoc pull notes.md                # re-pull an already-linked file
gmdoc push notes.md                # upload edits (replaces the doc body)
gmdoc new draft.md -t "My Doc"     # create a new doc from markdown
gmdoc status [files...]            # in sync / local / remote / CONFLICT
gmdoc account [email] [--login]    # list/check/switch Google accounts

Each pulled file gets front matter linking it to the doc:

---
gmdoc_id: 1AbC...
gmdoc_title: My Doc
gmdoc_modified: 2026-01-01T12:00:00.000Z
gmdoc_hash: 3f2a...
gmdoc_account: me@gmail.com
---

Multiple accounts

  • gmdoc account lists your gcloud accounts, marks the active one with *, and checks that each can reach Drive.
  • gmdoc account other@gmail.com switches to that account, logging in first if needed. Add --login to redo the login (fixes "no Drive access").
  • Each file remembers the account it was synced with (gmdoc_account), and pull, push and status use that account whichever one is active.
  • New docs and ls use the active account. --account/-a <email> overrides it on any command.

Safety checks

  • push refuses if the doc was edited in Google after your last sync. It detects this by exporting the doc and comparing it to gmdoc_hash, the hash of the text at last sync.
  • pull refuses if the local file has unpushed edits.
  • --force skips both checks.

Troubleshooting

If Drive complains that the API isn't enabled for the project, set GMDOC_QUOTA_PROJECT=<your-project-id> (a project with the Drive API enabled).

Caveats

  • A push replaces the whole doc body. Comments become detached, and suggestions and some formatting (colors, complex tables, images) may be lost.
  • After a push the file is re-exported, so it matches Google's version of the markdown.
  • The drive scope is used so it can edit any doc you have access to.

License

MIT

Metadata

Release files for gmdoc 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gmdoc 0.1.0
File Size Uploaded
gmdoc-0.1.0.tar.gz 9.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gmdoc 0.1.0
File Interpreter ABI Platform
gmdoc-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.3 kB

Release files / gmdoc-0.1.0.tar.gz

Download URL gmdoc-0.1.0.tar.gz
Size 9.3 kB
Tags Source
SHA-256 checksum
How to use checksums
70d40dda600e17e8bb36ac814e07bb17814e5c98220534cfef5c357289098a2d
BLAKE2b-256 checksum
How to use checksums
96d766bba63c2e73911c2f59636718795bf8bd97b437c91a91bc5c5245da6e7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / gmdoc-0.1.0-py3-none-any.whl

Download URL gmdoc-0.1.0-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
159c32e66267805106c99c2a1053a361610287e575ec68c3a73e34d550bba74c
BLAKE2b-256 checksum
How to use checksums
1f15416657354737b0b7a31ad6ce746abc99fd5d06345c46153393867f57bb96
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page