Google Docs tabs to Markdown CLI sync tool
Project description
DocSync
doc is a Python CLI that syncs one Google Doc's tabs to local XML files and back using incremental Google Docs API patches.
Current feature scope
doc pull: materialize tabs as XML files and store sync metadata in.docsync_state.json.doc push: strict mode, aborts if remote revision changed since last pull.doc push -f: best-effort mode with a safe rebase policy; aborts on unsafe overlap.doc push -f --dry-run: preview operations and conflicts without writing.
Safety model
- Strict mode never writes when revision drift is detected.
- Force mode only applies minimal incremental edits (no full-document replacement).
- Force mode aborts with conflict reports for overlapping/unsafe edits.
Assumptions for v1
- Tabs are represented in editable XML (
.xml) files. - Simultaneous edits are uncommon; strict mode is default.
- Authentication uses Application Default Credentials (ADC).
Google authentication
The CLI uses the standard Google ADC flow from google-auth.
You have two common options:
-
User OAuth (great for local development):
Important for now: to request Docs/Drive scopes, you need your own OAuth client ID file. The default
gcloud auth application-default loginclient can be blocked for non-Cloud scopes. See Google's ADC troubleshooting guidance: https://docs.cloud.google.com/docs/authentication/troubleshoot-adc#access_blocked_when_using_scopesSteps:
-
Create an OAuth client in Google Cloud Console (Desktop app client is fine for local dev).
-
Download the client JSON file.
-
Run:
gcloud auth application-default login \ --client-id-file=/absolute/path/to/client_secret.json \ --scopes="https://www.googleapis.com/auth/documents,https://www.googleapis.com/auth/drive.readonly,openid,https://www.googleapis.com/auth/userinfo.email"
This is a temporary setup requirement until the project is reviewed/published and can use a simpler default flow.
-
-
Service account key (great for automation/CI):
- Create a service account and JSON key in Google Cloud.
- Share the target Google Doc with that service account email.
- Point ADC to the key file via
GOOGLE_APPLICATION_CREDENTIALS.
You can export that variable in your shell:
export GOOGLE_APPLICATION_CREDENTIALS="/absolute/path/to/service-account.json"
Or use a local .env file (loaded automatically by the CLI):
GOOGLE_APPLICATION_CREDENTIALS=/absolute/path/to/service-account.json
Required scope used by this tool: https://www.googleapis.com/auth/documents.
Quickstart
-
Install:
poetry install -
Authenticate with Google APIs (Application Default Credentials).
-
Pull:
poetry run doc pull <DOC_ID> --workspace . --verbose
If you used an older Markdown-based workspace, run
pullagain to migrate files/state to XML. -
Edit generated
.xmlfiles. -
Push:
poetry run doc push <DOC_ID> --workspace . --verbose
Force mode:
poetry run doc push <DOC_ID> --workspace . -f
For large documents, use incremental progress logs and tune batch size:
poetry run doc push <DOC_ID> --workspace . --verbose --batch-size 50
If you interrupt with Ctrl+C, DocSync now logs the current processing stage and stack context to .docsync.log by default. You can customize logging:
poetry run doc --log-file /tmp/docsync.log --log-level DEBUG push <DOC_ID> --verbose
PyPI and pipx
After publishing to PyPI, users can install globally with:
pipx install docsync
For maintainers, build and verify locally before upload:
poetry check
poetry build
poetry run python -m twine check dist/*
Publishing auth options:
-
Preferred: PyPI Trusted Publishing (OIDC in CI; no local token needed).
-
Alternative: PyPI API token (
pypi-...) configured for Poetry:poetry config pypi-token.pypi <YOUR_PYPI_TOKEN> poetry publish
Do not upload credential files (.env, OAuth client secrets, service account keys).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file docsync-0.2.1.tar.gz.
File metadata
- Download URL: docsync-0.2.1.tar.gz
- Upload date:
- Size: 15.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cee98887c8ca125f0a2db1950e9903550d79c7f6254b594dba84aae2e62d234
|
|
| MD5 |
9f178977deb759a8640d305f43853a00
|
|
| BLAKE2b-256 |
01a5619a63ae8da610419c2b7198e583f6759c3c4ee79b3cf867ad0bb9b067cf
|
Provenance
The following attestation bundles were made for docsync-0.2.1.tar.gz:
Publisher:
publish-pypi.yml on Telofy/DocSync
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docsync-0.2.1.tar.gz -
Subject digest:
8cee98887c8ca125f0a2db1950e9903550d79c7f6254b594dba84aae2e62d234 - Sigstore transparency entry: 1019301182
- Sigstore integration time:
-
Permalink:
Telofy/DocSync@f317e19eb095541d722f79cf975291a9215b04c8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Telofy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f317e19eb095541d722f79cf975291a9215b04c8 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file docsync-0.2.1-py3-none-any.whl.
File metadata
- Download URL: docsync-0.2.1-py3-none-any.whl
- Upload date:
- Size: 17.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06b7b0d5ea1d7d060e81b63143f926adcc0cb9713a5c7c0baabe7e627f6f4127
|
|
| MD5 |
a6285b34af68b8d35e36ec64fa49fb49
|
|
| BLAKE2b-256 |
62954dec489a833f5a87dfc33356d74d43f556f5205c6bf5201cda646546a0f8
|
Provenance
The following attestation bundles were made for docsync-0.2.1-py3-none-any.whl:
Publisher:
publish-pypi.yml on Telofy/DocSync
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
docsync-0.2.1-py3-none-any.whl -
Subject digest:
06b7b0d5ea1d7d060e81b63143f926adcc0cb9713a5c7c0baabe7e627f6f4127 - Sigstore transparency entry: 1019301185
- Sigstore integration time:
-
Permalink:
Telofy/DocSync@f317e19eb095541d722f79cf975291a9215b04c8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/Telofy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@f317e19eb095541d722f79cf975291a9215b04c8 -
Trigger Event:
workflow_dispatch
-
Statement type: