简体   繁体   English

Google Drive API for Python:如何创建凭证?

[英]Google Drive API for Python: how to create credential?

I was writing a Python script to automate uploading some files to Google Drive.我正在编写一个 Python 脚本来自动将一些文件上传到 Google Drive。 Since I'm still a newbie Python programmer and this is an exercise as much as anything else, I started following the Google Quickstart and decided to use their quickstart.py as a basis on which to base my own script.由于我还是一个新手 Python 程序员,这和其他任何事情一样都是一个练习,我开始关注Google Quickstart并决定使用他们的quickstart.py作为我自己脚本的基础。 In the part where it talks about how to create credentials for your Python script, it refers to the "Create credentials" link, at https://developers.google.com/workspace/guides/create-credentials在讨论如何为您的 Python 脚本创建凭据的部分中,它指的是“创建凭据”链接,位于https://developers.google.com/workspace/guides/create-credentials

I follow the link, get into one of my Google Cloud projects, and try to set up the OAuth consent screen, using an "Internal" project, as they tell you... but I can't.我点击链接,进入我的一个 Google Cloud 项目,并尝试使用“内部”项目设置 OAuth 同意屏幕,正如他们告诉你的那样......但我不能。 Google says:谷歌说:

“Because you're not a Google Workspace user, you can only make your app available to external (general audience) users. “由于您不是 Google Workspace 用户,因此您只能将您的应用提供给外部(一般受众)用户。

So I try to create an "External" project, and then proceed to create a new client ID, using a Desktop application.所以我尝试创建一个“外部”项目,然后继续使用桌面应用程序创建一个新的客户端 ID。 Then I download the JSON credentials and put them in the same folder as my Python script, as "credentials.json" .然后我下载 JSON 凭据并将它们放在与我的 Python 脚本相同的文件夹中,作为"credentials.json" I then execute the Python script in order to authenticate it: the browser opens, I log into my Google account, give it my permissions... and then the browser hangs, because it's redirecting to a localhost URL and obviously my little Python script isn't listening in my computer at all. I then execute the Python script in order to authenticate it: the browser opens, I log into my Google account, give it my permissions... and then the browser hangs, because it's redirecting to a localhost URL and obviously my little Python script isn根本不听我的电脑。

I believe they must have changed this recently, because a year ago I started following the same Python tutorial and could create credentials without problems, but the Google Drive API docs haven't been updated yet.我相信他们最近一定改变了这一点,因为一年前我开始遵循相同的 Python 教程并且可以毫无问题地创建凭据,但 Google Drive API 文档尚未更新。 So... how do I create credentials for a Python script now?那么......我现在如何为 Python 脚本创建凭据?

EDIT: adding here the source code for my script.编辑:在此处添加我的脚本的源代码。 As I said, it's very similar to Google's "quickstart.py":正如我所说,它与 Google 的“quickstart.py”非常相似:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.errors import HttpError


# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata', 'https://www.googleapis.com/auth/drive']



def main():
    """Shows basic usage of the Drive v3 API.
    Prints the names and ids of the first 10 files the user has access to.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token_myappname.pickle'):
        with open('token_myappname.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token_myappname.pickle', 'wb') as token:
            pickle.dump(creds, token)



    service = build('drive', 'v3', credentials=creds)

    # Call the Drive v3 API
    results = service.files().list(
        pageSize=10, fields="nextPageToken, files(id, name)").execute()
    items = results.get('files', [])


    if not items:
        print('No files found.')
    else:
        #print(items[0])
 
        print('Files:')
        for item in items:
            #print (item)
            print(u'{0}   {1}   {2}'.format(item['name'], item['owners'], item['parents']))
 

I propose you to use a service account to access to the Drive.我建议您使用服务帐户来访问云端硬盘。

For that, you need to share the drive (or the folder) with the service account email.为此,您需要与服务帐户 email 共享驱动器(或文件夹)。 And then use this code然后使用此代码

from googleapiclient.discovery import build
import google.auth

SCOPES = ['https://www.googleapis.com/auth/drive.metadata', 'https://www.googleapis.com/auth/drive']



def main():
    credentials, project_id = google.auth.default(scopes=SCOPES)


    service = build('drive', 'v3', credentials=credentials)

    # Call the Drive v3 API
    results = service.files().list(
        q=f"'1YJ6gMgACOqVVbcgKviJKtVa5ITgsI1yP' in parents",
        pageSize=10, fields="nextPageToken, files(id, name, owners, parents)").execute()
    items = results.get('files', [])


    if not items:
        print('No files found.')
    else:
        #print(items[0])

        print('Files:')
        for item in items:
            #print (item)
            print(u'{0}   {1}   {2}'.format(item['name'], item['owners'], item['parents']))

If you run your code on Google Cloud, in a compute engine instance for example, you need to customize the VM with the service account that you authorized in your drive.如果您在 Google Cloud 上运行代码,例如在计算引擎实例中,您需要使用您在驱动器中授权的服务帐户自定义 VM。 (Don't use the compute engine default service account, else you will need extra configuration on your VM) (不要使用计算引擎默认服务帐户,否则您需要在 VM 上进行额外配置)

If you run your script outside GCP, you need to generate a service account key file and to store it on your local server.如果您在 GCP 之外运行脚本,则需要生成服务帐户密钥文件并将其存储在本地服务器上。 Then, create an environment variable GOOGLE_APPLICATION_CREDENTIALS that reference the full path of the stored key file.然后,创建一个引用存储的密钥文件的完整路径的环境变量GOOGLE_APPLICATION_CREDENTIALS

Aside from the other solution posted by Guillaume Blaquiere, I also found another one on my own, which I wanted to post here in case it's helpful.除了 Guillaume Blaquiere 发布的其他解决方案之外,我还自己找到了另一个解决方案,我想在这里发布它以防万一。 All I had to do is to... erm, actually read the code I was copying and pasting, in particular this line:我所要做的就是......呃,实际上阅读我正在复制和粘贴的代码,特别是这一行:

creds = flow.run_local_server(port=0)

I checked Google's documentation outside of the Quickstart and found in the following: https://google-auth-oauthlib.readthedocs.io/en/latest/reference/google_auth_oauthlib.flow.html我在快速入门之外查看了 Google 的文档,发现如下: https://google-auth-oauthlib.readthedocs.io/en/latest/reference/google_auth_oauthlib.flow.html

It turns out, the example code was opening a local port in my computer to listen to the request, and it wasn't working probably due to the "port 0" part, or some other network problem.事实证明,示例代码在我的计算机打开了一个本地端口来监听请求,它可能由于“端口 0”部分或其他网络问题而无法正常工作。

So the workaround I found was to use a different auth method found in the docs:所以我发现的解决方法是使用文档中的不同身份验证方法:

  creds = flow.run_console()  

In this case, you paste manually in the command line the auth code given to you by Google.在这种情况下,您可以在命令行中手动粘贴 Google 提供给您的身份验证代码。 I just tried it, and have my credentials happily stored in my local pickle file.我刚试了一下,我的凭据愉快地存储在我的本地泡菜文件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM