Pull, edit, and push Google Forms using local files
Project description
ExtraForm
Pull, edit, and push Google Forms using local files.
ExtraForm transforms Google Forms into a file-based representation optimized for LLM agents. It follows the same pull/diff/push workflow as ExtraSheet.
Installation
pip install extraform
Or with uvx:
uvx extraform pull <form_url>
Quick Start
# 1. Login (one-time)
extraform login
# 2. Pull a form
extraform pull https://docs.google.com/forms/d/1FAIpQLSd.../edit
# 3. Edit form.json in your editor or with an AI agent
# 4. Preview changes
extraform diff 1FAIpQLSd...
# 5. Apply changes
extraform push 1FAIpQLSd...
Commands
pull
Download a Google Form to a local folder:
extraform pull <form_url_or_id> [output_dir]
Options:
--responses- Include form responses (read-only)--max-responses N- Maximum responses to fetch (default: 100)--no-raw- Don't save raw API responses
diff
Preview changes without applying them:
extraform diff <folder>
Outputs the batchUpdate JSON to stdout.
push
Apply changes to the Google Form:
extraform push <folder>
On-Disk Format
After pulling a form, you'll have:
<form_id>/
form.json # Form structure - edit this!
responses.tsv # Read-only snapshot of responses
.raw/
form.json # Raw API response
responses.json # Raw responses (if fetched)
.pristine/
form.zip # Original state for diff
form.json
The form structure mirrors the Google Forms API but is cleaned up for readability:
{
"formId": "1FAIpQLSd...",
"info": {
"title": "My Survey",
"description": "Please fill out this survey"
},
"items": [
{
"itemId": "abc123",
"title": "What is your name?",
"questionItem": {
"question": {
"required": true,
"textQuestion": {
"paragraph": false
}
}
}
}
]
}
Question Types
| Type | JSON Key | Example |
|---|---|---|
| Short answer | textQuestion |
{"paragraph": false} |
| Long answer | textQuestion |
{"paragraph": true} |
| Multiple choice | choiceQuestion |
{"type": "RADIO", "options": [...]} |
| Checkboxes | choiceQuestion |
{"type": "CHECKBOX", "options": [...]} |
| Dropdown | choiceQuestion |
{"type": "DROP_DOWN", "options": [...]} |
| Linear scale | scaleQuestion |
{"low": 1, "high": 5} |
| Date | dateQuestion |
{"includeYear": true} |
| Time | timeQuestion |
{"duration": false} |
| Rating | ratingQuestion |
{"iconType": "STAR", "ratingScaleLevel": 5} |
Non-Question Items
| Type | Purpose |
|---|---|
pageBreakItem |
Section divider |
textItem |
Static text/instructions |
imageItem |
Embedded image |
videoItem |
Embedded YouTube video |
Limitations
- File upload questions: Cannot be created via API (read-only)
- Responses: Read-only, cannot modify submitted responses
- documentTitle: Read-only, update via Google Drive
Development
cd extraform
uv sync
uv run pytest tests/ -v
uv run ruff check . && uv run ruff format .
uv run mypy src/extraform
License
MIT
Project details
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 extraform-0.2.1.tar.gz.
File metadata
- Download URL: extraform-0.2.1.tar.gz
- Upload date:
- Size: 61.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5d114ed9890b504ffaf1c1b3dd0ba7997799b6d6ba30836277fbfd2976f536d
|
|
| MD5 |
ce04f8717b99aa5677a71a007ae6cfe4
|
|
| BLAKE2b-256 |
3c2fc884f0f9af0c972e79bad39bfbe50b684103cf15a65d231d0c057d3b11e0
|
Provenance
The following attestation bundles were made for extraform-0.2.1.tar.gz:
Publisher:
publish-extraform.yml on think41/extrasuite
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
extraform-0.2.1.tar.gz -
Subject digest:
b5d114ed9890b504ffaf1c1b3dd0ba7997799b6d6ba30836277fbfd2976f536d - Sigstore transparency entry: 940365049
- Sigstore integration time:
-
Permalink:
think41/extrasuite@25a2af58b293c3a6e0a7aec8d207fe26947eab47 -
Branch / Tag:
refs/tags/extraform-v0.2.1 - Owner: https://github.com/think41
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-extraform.yml@25a2af58b293c3a6e0a7aec8d207fe26947eab47 -
Trigger Event:
push
-
Statement type:
File details
Details for the file extraform-0.2.1-py3-none-any.whl.
File metadata
- Download URL: extraform-0.2.1-py3-none-any.whl
- Upload date:
- Size: 20.3 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 |
4bfd5d28b7a700b672765e44830838896c18ecd5a06ffac1e544189db576a626
|
|
| MD5 |
0904c67389d3a5a05d05bd33f82bc9cc
|
|
| BLAKE2b-256 |
9b19ae40c6db6953085b230fddedd72ee1c34424418ff3480c36b613ead9b009
|
Provenance
The following attestation bundles were made for extraform-0.2.1-py3-none-any.whl:
Publisher:
publish-extraform.yml on think41/extrasuite
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
extraform-0.2.1-py3-none-any.whl -
Subject digest:
4bfd5d28b7a700b672765e44830838896c18ecd5a06ffac1e544189db576a626 - Sigstore transparency entry: 940365050
- Sigstore integration time:
-
Permalink:
think41/extrasuite@25a2af58b293c3a6e0a7aec8d207fe26947eab47 -
Branch / Tag:
refs/tags/extraform-v0.2.1 - Owner: https://github.com/think41
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-extraform.yml@25a2af58b293c3a6e0a7aec8d207fe26947eab47 -
Trigger Event:
push
-
Statement type: