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 accountlists your gcloud accounts, marks the active one with*, and checks that each can reach Drive.gmdoc account other@gmail.comswitches to that account, logging in first if needed. Add--loginto redo the login (fixes "no Drive access").- Each file remembers the account it was synced with (
gmdoc_account), andpull,pushandstatususe that account whichever one is active. - New docs and
lsuse the active account.--account/-a <email>overrides it on any command.
Safety checks
pushrefuses if the doc was edited in Google after your last sync. It detects this by exporting the doc and comparing it togmdoc_hash, the hash of the text at last sync.pullrefuses if the local file has unpushed edits.--forceskips 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
drivescope 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)
| File | Size | Uploaded | |
|---|---|---|---|
| gmdoc-0.1.0.tar.gz | 9.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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}
|