Python 如何更改Google Sheets电子表格的所有者?

Python 如何更改Google Sheets电子表格的所有者?,python,google-sheets,permissions,google-sheets-api,Python,Google Sheets,Permissions,Google Sheets Api,通过以下内容,我可以在Google sheets中以编程方式创建电子表格,但该表格的所有者是开发人员帐户(一个以gserviceaccount.com结尾的疯狂字符串),我的普通帐户无法查看电子表格。我还需要做什么才能将Google用户添加到读/写权限 从oauth2client.service\u帐户导入ServiceAccountCredentials 从GoogleAppClient导入发现 ... json_键是具有凭据的json blob 范围=['https://spreadshee

通过以下内容,我可以在Google sheets中以编程方式创建电子表格,但该表格的所有者是开发人员帐户(一个以gserviceaccount.com结尾的疯狂字符串),我的普通帐户无法查看电子表格。我还需要做什么才能将Google用户添加到读/写权限

从oauth2client.service\u帐户导入ServiceAccountCredentials 从GoogleAppClient导入发现 ... json_键是具有凭据的json blob 范围=['https://spreadsheets.google.com/feeds'] credentials=ServiceAccountCredentials.from_json_keyfile_dictjson_key,作用域 服务=发现。生成'sheets','v4',凭据=凭据 电子表格={ 属性:{标题:我的测试电子表格} } service.spreadsheets.createbody=spreadsheet.execute 编辑: 我试着把范围改成['https://www.googleapis.com/auth/drive“]但下面的答案对我仍然不适用。当我跑的时候

print [xx for xx in dir(service) if not xx.startswith('_')]
我明白了

换句话说,权限不是我定义的服务中的方法。我应该采取哪些不同的做法?

尝试使用来自的方法。您将能够插入文件或团队驱动器的权限

以下是文件中提供的信息:

from apiclient import errors
# ...

def insert_permission(service, file_id, value, perm_type, role):
  """Insert a new permission.

  Args:
    service: Drive API service instance.
    file_id: ID of the file to insert permission for.
    value: User or group e-mail address, domain name or None for 'default'
           type.
    perm_type: The value 'user', 'group', 'domain' or 'default'.
    role: The value 'owner', 'writer' or 'reader'.
  Returns:
    The inserted permission if successful, None otherwise.
  """
  new_permission = {
      'value': value,
      'type': perm_type,
      'role': role
  }
  try:
    return service.permissions().insert(
        fileId=file_id, body=new_permission).execute()
  except errors.HttpError, error:
    print 'An error occurred: %s' % error
  return None
用于测试实时数据并查看API请求和响应


要进一步阅读,请选中此项。

服务只是discovery.build调用结果的通用名称。在这种情况下,没有“permissions”方法只是因为它在同一个服务上不可用。如果不需要更改所有者,则以下代码就足够了。要添加具有读写访问权限的用户,我可以使用以下方法:

def grant_permissions(spreadsheet_id, writer):
    drive_service = discovery.build('drive', 'v3')

    permission = drive_service.permissions().create(
        fileId=spreadsheet_id,
        body={
            'type': 'user',
            'role': 'writer',
            'emailAddress': writer,
        }
    ).execute()

    drive_service.files().update(
        fileId=spreadsheet_id,
        body={'permissionIds': [permission['id']]}
    ).execute()
要实际更改所有者,必须设置“转移所有权”标志:

def change_owner(spreadsheet_id, writer):
    drive_service = discovery.build('drive', 'v3')

    permission = drive_service.permissions().create(
        fileId=spreadsheet_id,
        transferOwnership=True,
        body={
            'type': 'user',
            'role': 'owner',
            'emailAddress': writer,
        }
    ).execute()

    drive_service.files().update(
        fileId=spreadsheet_id,
        body={'permissionIds': [permission['id']]}
    ).execute()

但是,正在使用的服务帐户必须具有正确的权限。我相信在我第一次创建服务帐户时,对我有效的方法是检查g套件框。

我从Chris留下的评论中找到了答案。他的评论中缺少的是,实际上您确实需要在他的drive_服务中使用特定的作用域。请注意,我用于构建不同对象的范围发生了变化:

from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.discovery import build

key = '/path/to/service_account.json'

# Build 'Spreadsheet' object

spreadsheets_scope = [ 'https://www.googleapis.com/auth/spreadsheets' ]
sheets_credentials = ServiceAccountCredentials.from_json_keyfile_name(key, spreadsheets_scope)

sheets_service = build('sheets', 'v4', credentials=sheets_credentials)

# returns 'Spreadsheet' dict
# https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets#resource-spreadsheet
spreadsheet = sheets_service.spreadsheets().create(
    body={
        "properties": {
            'title': 'spreadsheets test',
        },
        "sheets": [],
    }
).execute()


# id for the created file
spreadsheetId = spreadsheet['spreadsheetId']
# url of your file
spreadsheetUrl = spreadsheet['spreadsheetUrl']

# Build 'Permissions' object
drive_scope = [ 'https://www.googleapis.com/auth/drive' ]
drive_credentials = ServiceAccountCredentials.from_json_keyfile_name(key, drive_scope)

drive_service = build('drive', 'v3', credentials=drive_credentials)

# returns 'Permissions' dict
permissions = drive_service.permissions().create(
    fileId=spreadsheetId,
    transferOwnership=True,
    body={
        'type': 'user',
        'role': 'owner',
        'emailAddress': 'example@email.com',
    }
).execute()

# apply permission 
drive_service.files().update(
    fileId=spreadsheetId,
    body={'permissionIds': [permissions['id']]}
).execute()

print ('\nOpen me:\n\n%s\n' % spreadsheetUrl)

因此,逻辑是,“电子表格资源”是由build及其所有属性和工作表数据组成的,所有者设置为您的服务帐户。接下来,创建一个“驱动器资源”,这是具有权限方法的资源。execute返回一个新创建的用于更新电子表格文件的权限id。

Hmm,您的服务和我的服务是一样的吗?我得到以下信息:AttributeError:“资源”对象在返回服务上没有属性“权限”。权限。插入。。。一点换句话说,当我在输入service之后点击IPython中的tab时,权限似乎不是一个成员方法。哦,也许问题在于我的范围?我在上面的帖子中添加了一个编辑,回应了你的建议,因为我认为帖子格式比评论格式更容易阅读。结果,范围似乎不是问题。
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.discovery import build

key = '/path/to/service_account.json'

# Build 'Spreadsheet' object

spreadsheets_scope = [ 'https://www.googleapis.com/auth/spreadsheets' ]
sheets_credentials = ServiceAccountCredentials.from_json_keyfile_name(key, spreadsheets_scope)

sheets_service = build('sheets', 'v4', credentials=sheets_credentials)

# returns 'Spreadsheet' dict
# https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets#resource-spreadsheet
spreadsheet = sheets_service.spreadsheets().create(
    body={
        "properties": {
            'title': 'spreadsheets test',
        },
        "sheets": [],
    }
).execute()


# id for the created file
spreadsheetId = spreadsheet['spreadsheetId']
# url of your file
spreadsheetUrl = spreadsheet['spreadsheetUrl']

# Build 'Permissions' object
drive_scope = [ 'https://www.googleapis.com/auth/drive' ]
drive_credentials = ServiceAccountCredentials.from_json_keyfile_name(key, drive_scope)

drive_service = build('drive', 'v3', credentials=drive_credentials)

# returns 'Permissions' dict
permissions = drive_service.permissions().create(
    fileId=spreadsheetId,
    transferOwnership=True,
    body={
        'type': 'user',
        'role': 'owner',
        'emailAddress': 'example@email.com',
    }
).execute()

# apply permission 
drive_service.files().update(
    fileId=spreadsheetId,
    body={'permissionIds': [permissions['id']]}
).execute()

print ('\nOpen me:\n\n%s\n' % spreadsheetUrl)