2017-10-11 622 views
1

通过以下步骤,我可以以编程方式在Google工作表中创建电子表格,但工作表的所有者是开发者帐户(以“gserviceaccount.com”结尾的疯狂字符串),我的普通帐户无法查看电子表格。为了向Google用户添加读/写权限,还需要做些什么?如何更改Google表格电子表格的所有者?

from oauth2client.service_account import ServiceAccountCredentials 
from googleapiclient import discovery 

# ... json_key is the json blob that has the credentials 
scope = ['https://spreadsheets.google.com/feeds'] 
credentials = ServiceAccountCredentials.from_json_keyfile_dict(json_key, scope) 
service = discovery.build('sheets', 'v4', credentials=credentials) 

spreadsheet = { 
    "properties": {"title": "my test spreadsheet"} 
} 

service.spreadsheets().create(body=spreadsheet).execute() 

编辑:
我试图改变范围['https://www.googleapis.com/auth/drive']但低于仍然回答不为我工作。当我运行

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

我得到

['new_batch_http_request', u'spreadsheets'] 

换句话说,permissions()不是service的方法,因为我已经定义的服务。我应该做什么不同?

回答

1

我从阅读Chris留下的评论中发现它。他的评论中缺少的是你实际上需要在他的drive_service中使用特定的范围。注意范围的变化我用它来构建不同的对象:

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': '[email protected]', 
    } 
).execute() 

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

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

所以逻辑是,一个“电子表格资源”从build制成,其所有属性和表数据,设置为服务业主帐户。接下来,创建“驱动器资源”,这是使用permissions()方法的资源。​​返回新创建的权限id用于update()电子表格文件。

0

尝试使用documentation中的方法Permissions: insert。您将能够插入文件或团队云端硬盘的权限。

下面是从文档中提供的sample code

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 

使用Try it now测试现场数据,看到了API请求和响应。请致电SO post

+0

嗯,你的'服务'和我的一样吗?我得到这个: 'AttributeError:'Resource'对象没有属性'permissions'' 上的''return service.permissions()。insert' ...“位。换句话说,当我在键入“'service.'”后,在IPython中选中标签时,''permissions()'“似乎不是成员方法。 – dslack

+0

哦,也许问题是我的'范围'? – dslack

+0

我在上面的帖子中添加了一个编辑,回复了您的建议,因为我认为阅读后的格式比评论格式更容易。 Upshot,'范围'似乎不是问题。(?) – dslack

1

服务只是discovery.build调用结果的通用名称。在这种情况下,没有'权限'方法只是它在相同的服务上不可用。如果不需要更改所有者,以下代码应该足够了。具有读某人添加和写入权限,以下工作对我来说:

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套件框。

相关问题