Changing Google Sheet permissions with Python Google API Client
Firstly, let’s create a list consisting of the Google Sheet file IDs for which we are going to change the permissions:
google_sheet_ids = [
'abc-1234',
'def-5678',
'ghi-9123',
]
Now the second thing we need to do is to infer the application default credentials and create the service for Google Drive.
import google.auth
from googleapiclient.discovery import build def create_service() -> Resource:
"""
Creates a Google Drive (v3) service to interact with the API
"""
scopes = [
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive',
]
creds, project_id = google.auth.default(scopes=scopes)
service = build('drive', 'v3', credentials=creds, cache_discovery=False)
return service
Now, let’s create a dataclass that contains (only) the fields required to specify a permission, based on the Permissions
REST Resource.
from dataclasses import dataclass@dataclass
class Permission:
"""
Class that corresponds to the `permission` REST resource
https://developers.google.com/drive/api/reference/rest/v3/permissions#Permission
"""
type: str
role: str
emailAddress: str
def __post__init__(self):
"""Validate input"""
allowed_types = ['user', 'group', 'domain', 'anyone']
if self.type not in allowed_types:
raise ValueError(f'`{self.type}` is not a valid type. {allowed_types=}')
allowed_roles = ['commenter', 'reader', 'writer', 'fileOrganizer', 'organizer', 'owner']
if self.role not in allowed_roles:
raise ValueError(f'`{self.role}` is not a valid role. {allowed_roles=}')
In the next step, we are going to write a function that essentially takes instances of a service and a permission along with a file ID, and attempts to create a new permission.
from typing import Optionalfrom googleapiclient.discovery import Resource
from googleapiclient.errors import HttpError
def create_permission(
service: Resource,
permission: Permission,
file_id: str,
skip_on_failure: Optional[bool] = True,
):
"""
Creates a new `permission` for the specified `file_id`
"""
logging.info(f'Creating new permission {permission} for {file_id=}')
try:
request = service.permissions().create(
fileId=file_id,
body=asdict(permission),
sendNotificationEmail=False,
)
response = request.execute()
logging.info(f'New permission for {file_id=}: {response=}')
except HttpError as error:
logging.error(f'An error has occurred while trying to grant {permission=} to {file_id=}')
logging.error(f'Error was: {error}')
if not skip_on_failure:
raise error
Now, let’s write our main()
method to put all the pieces together and eventually share the Google Sheets of interest with our target user.
def main():
google_sheet_ids = [
'abc-1234',
'def-5678',
'ghi-9123',
]service = create_service()
permission = Permission(type='user', role='writer', emailAddress='example@example.com')
for file_id in google_sheet_ids:
create_permission(service=service, permission=permission, file_id=file_id)