gformlib.client
Main client for the Google Forms API.
This module exposes GoogleFormsClient, the primary public interface
of the gformlib library. The client handles authentication, delegates
request-body construction to FormBuilder, and
wraps the raw Google API responses in typed FormInfo
objects.
Supported authentication strategies
Service Account (server-to-server) –
GoogleFormsClient.from_service_account()OAuth 2.0 installed app –
GoogleFormsClient.from_oauth_credentials()Pre-built credentials – pass any
google.oauth2credentials object directly to the constructor.
Required Google API scopes
https://www.googleapis.com/auth/forms.body– create and modify formshttps://www.googleapis.com/auth/drive.file– required for file-upload questions
Example:
from gformlib import GoogleFormsClient
client = GoogleFormsClient.from_service_account("service_account.json")
info = client.create_form(
{
"title": "Quick Survey",
"description": "Tell us what you think.",
"questions": [
{"title": "Your name", "type": "short_answer", "required": True},
{
"title": "Rating",
"type": "scale",
"low": 1,
"high": 5,
"low_label": "Poor",
"high_label": "Excellent",
},
],
}
)
print(info.responder_uri)
- gformlib.client.DEFAULT_SCOPES: List[str] = ['https://www.googleapis.com/auth/forms.body', 'https://www.googleapis.com/auth/drive.file']
Default OAuth scopes required by the Google Forms API.
- class gformlib.client.GoogleFormsClient(credentials, scopes=None)[source]
Bases:
objectHigh-level client for creating and managing Google Forms.
Do not instantiate this class directly with the constructor unless you already have a
google.oauth2credentials object. Use one of the class-method factories instead:from_service_account()– recommended for server-side code.from_oauth_credentials()– for installed / desktop apps.
- Parameters:
credentials (Any) – Any
google.oauth2credentials object that has been authorised for the required scopes.scopes (Optional[List[str]]) – OAuth scopes to request. Defaults to
DEFAULT_SCOPES.
- Raises:
AuthenticationError – If the credentials object is
Noneor invalid.
Example:
from google.oauth2.service_account import Credentials from gformlib import GoogleFormsClient creds = Credentials.from_service_account_file("sa.json", scopes=[...]) client = GoogleFormsClient(credentials=creds)
- classmethod from_service_account(service_account_file, scopes=None, subject=None)[source]
Create a client authenticated as a Google Service Account.
This is the recommended approach for server-side applications that do not have a logged-in user context.
- Parameters:
service_account_file (str | PathLike[str]) – Path to the service account JSON key file downloaded from the Google Cloud Console.
scopes (List[str] | None) – OAuth scopes to request. Defaults to
DEFAULT_SCOPES.subject (str | None) – The email address of the user account to impersonate (requires Domain-Wide Delegation to be configured).
- Returns:
An authenticated
GoogleFormsClient.- Raises:
AuthenticationError – If the key file cannot be read or the credentials are invalid.
FileNotFoundError – If service_account_file does not exist.
- Return type:
Example:
client = GoogleFormsClient.from_service_account( "path/to/service_account.json" )
- classmethod from_service_account_info(info, scopes=None, subject=None)[source]
Create a client from a service account info dict.
Useful when credentials are stored in environment variables or a secrets manager rather than on the file system.
- Parameters:
- Returns:
An authenticated
GoogleFormsClient.- Raises:
AuthenticationError – If info is invalid.
- Return type:
Example:
import json, os info = json.loads(os.environ["SERVICE_ACCOUNT_JSON"]) client = GoogleFormsClient.from_service_account_info(info)
- classmethod from_oauth_credentials(client_secrets_file, token_file=None, scopes=None)[source]
Create a client using the OAuth 2.0 installed-app flow.
On the first run the user is prompted to grant access in their browser. The resulting token is saved to token_file so subsequent runs are non-interactive.
- Parameters:
client_secrets_file (str | PathLike[str]) – Path to the
client_secrets.jsonfile downloaded from the Google Cloud Console (OAuth 2.0 client ID of type Desktop app).token_file (str | PathLike[str] | None) – Path where the OAuth token will be cached. Defaults to
"token.json"in the current directory.scopes (List[str] | None) – OAuth scopes to request. Defaults to
DEFAULT_SCOPES.
- Returns:
An authenticated
GoogleFormsClient.- Raises:
AuthenticationError – If the OAuth flow fails.
FileNotFoundError – If client_secrets_file does not exist.
- Return type:
Example:
client = GoogleFormsClient.from_oauth_credentials( "client_secrets.json", token_file="my_token.json", )
- create_form(config)[source]
Create a new Google Form from a configuration dict or
FormConfig.This method:
Validates config (if it is a dict) with
parse_form_config().Calls
forms().create()to create the bare form skeleton.Calls
forms().batchUpdate()to add questions and description.
- Parameters:
config (Dict[str, Any] | FormConfig) – Either a raw configuration dict (see Quickstart) or a pre-built
FormConfigobject.- Returns:
A
FormInfowith the form’s ID, responder URL, and other metadata.- Raises:
InvalidConfigError – If config fails validation.
FormCreationError – If the
forms().create()call fails.FormUpdateError – If the
forms().batchUpdate()call fails.APIError – On unexpected HTTP errors from the Forms API.
- Return type:
Example:
info = client.create_form( { "title": "My Survey", "questions": [ {"title": "Name", "type": "short_answer", "required": True}, ], } ) print(info.responder_uri)
- update_form(form_id, config)[source]
Update an existing Google Form.
Modifies the title, description, and/or appends new questions to an existing form identified by form_id. Only the fields explicitly set in config are changed; everything else is left untouched.
This method:
Validates config (if it is a dict) with
parse_update_config().If new questions are being added, calls
forms().get()first to determine the current item count so that questions are appended at the correct position.Calls
forms().batchUpdate()with the generated request list.Returns a
FormInforeflecting the updated form state.
- Parameters:
form_id (str) – The ID of the form to update.
config (Dict[str, Any] | UpdateFormConfig) –
Either a raw update configuration dict or a pre-built
UpdateFormConfigobject.Recognised dict keys:
"title"(str) – new form title."description"(str) – new form description."add_questions"(list) – question dicts to append.
- Returns:
A
FormInfowith the updated metadata.- Raises:
InvalidConfigError – If config fails validation.
APIError – If the
forms().get()call to fetch the current form state fails.FormUpdateError – If the
forms().batchUpdate()call fails.
- Return type:
Example:
info = client.update_form( "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", { "title": "Revised Survey", "add_questions": [ {"title": "Any comments?", "type": "paragraph"}, ], }, ) print(info.title)
- get_form(form_id)[source]
Retrieve the full metadata of an existing form.
- Parameters:
form_id (str) – The ID of the form to retrieve.
- Returns:
The raw JSON response dict from the
forms().get()call.- Raises:
APIError – If the form is not found or the API returns an error.
- Return type:
Example:
data = client.get_form("1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms")
- list_responses(form_id, page_size=100, filter_str=None)[source]
Retrieve all responses submitted to a form.
Automatically handles pagination via the
nextPageTokenreturned by the API.- Parameters:
- Returns:
A list of raw response dicts from the API.
- Raises:
APIError – If the API call fails.
- Return type:
Example:
responses = client.list_responses(form_id) for r in responses: print(r["responseId"])
- delete_form(form_id)[source]
Delete a form by moving it to the Google Drive trash.
The Google Forms API does not expose a direct
deleteendpoint; this method calls the Drive API to trash the backing document.- Parameters:
form_id (str) – The ID of the form (same as the Drive file ID).
- Raises:
APIError – If the Drive API call fails.
- Return type:
None
Note
This requires the
https://www.googleapis.com/auth/drive.filescope to be included in the credentials.Example:
client.delete_form("1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms")