簡體   English   中英

如何使用 Google 雲端硬盤 API v3 向 Python 中的共享文件夾進行可續傳上傳?

[英]How do I do a resumable upload to a shared folder in Python using Google Drive API v3?

我正在嘗試使用 Google Drive API v3 和 Python 3.10.4 將文件上傳到 Google Drive。 我正在嘗試進行可恢復的上傳。 我成功獲取了開始上傳的 URI 位置,但是當我嘗試將文件上傳到該位置時,我從 Google 收到了 404 返回。

原因:'notFound',消息:'找不到文件:#FileIdHere',位置類型:'參數',位置:'fileId'

Google 為我提供了我嘗試上傳到的文件夾的 fileId。 它與我從 get_folderId function 獲得的 ID 相同。

def backup(drive: Drive, cam_name: str):
    logger.info('Backup drive has been plugged in')
    logger.info(f'Backing up {drive.letter}')

    #Grab the folder ID of the folder we are uploading files to
    folderId = get_folderId(cam_name)
    access_token = get_access_token()

    rootDirectory = drive.letter + "\\FILE\\"
    if not os.path.isdir(rootDirectory):
        rootDirectory = drive.letter + "\\DCIM"
    for root, dirs, files in os.walk(rootDirectory):
        for fileName in files:
            #Get file path
            filePath = os.path.join(root, fileName)

            #Grab mimetype for file
            mime = magic.Magic(mime=True)
            mimeType = mime.from_file(filePath)

            #Get size of file
            fileSize = os.path.getsize(filePath)

            #Retrieve session for resumable upload
            headers = {"Authorization": "Bearer "+access_token, "Content-Type": "application/json"}
            parameters = {
                "name": fileName,
                "mimeType": mimeType,
                "parents" : [folderId]
                
            }
            response = requests.post(
                    "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable",
                    headers=headers,
                    data=json.dumps(parameters)
            )
            #Location to upload file
            uploadLocation = response.headers['Location']

            #Upload the file
            headers = {"Content-Range": "bytes 0-" + str(fileSize - 1) + "/" + str(fileSize)}
            response = requests.put(
                uploadLocation,
                headers = headers,
                data=open(filePath, 'rb')
            )
            logger.info(response.text)

在上述 function 的參數變量中,我嘗試添加 supportsAllDrives = True 無濟於事,所以我不確定為什么找不到該文件夾。

#Gets the folder ID of the provided folder name from Google Drive
def get_folderId(cam_name: str):
    service = get_google_service()
    page_token = None
    queryString = "mimeType='application/vnd.google-apps.folder' and name='{}' and trashed = false".format(cam_name)
    response = service.files().list(q = queryString,
                                    spaces='drive',
                                    corpora='drive',
                                    supportsAllDrives=True,
                                    includeItemsFromAllDrives=True,
                                    driveId= #DriveIdGoesHere,
                                    fields='nextPageToken, files(id, name)',
                                    pageToken=page_token).execute()
    folderId = response.get('files')[0].get('id')
    return folderId
#Gets the Google service
def get_google_service():
        SCOPES = ['https://www.googleapis.com/auth/drive']
        SERVICE_ACCOUNT_FILE = 'service.json'
        credentials = service_account.Credentials.from_service_account_file(
                SERVICE_ACCOUNT_FILE, scopes=SCOPES)
        creds = credentials.with_subject(#EmailGoesHere)
        service = build('drive', 'v3', credentials=creds)

        return service

我相信你的目標如下。

  • How do I do a resumable upload to a shared folder in Python using Google Drive API v3? ,我認為您可能想要將文件上傳到 Google 雲端硬盤中的共享文件夾。
  • 從您的顯示腳本來看,您似乎正在使用服務帳戶。
  • 但是, Google gives me the fileId of the folder I'm attempting to upload to. Its the same id I get from my get_folderId function. Google gives me the fileId of the folder I'm attempting to upload to. Its the same id I get from my get_folderId function. 。在您的情況下,我認為您可能想要將文件上傳到共享驅動器中的文件夾。

如果我的理解是正確的,從你的錯誤信息reason: 'notFound', message: 'File not found: #FileIdHere', locationType: 'parameter', location: 'fileId' ,下面的修改怎么樣?

從:

response = requests.post(
        "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable",
        headers=headers,
        data=json.dumps(parameters)
)

到:

response = requests.post(
        "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&supportsAllDrives=true",
        headers=headers,
        data=json.dumps(parameters)
)
  • 當您要上傳文件到共享Drive中的文件夾,且folderId的值為共享Drive中文件夾的文件夾ID時,需要在查詢參數中包含supportsAllDrives=true

筆記:

  • 當我使用您的端點https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable測試您的腳本時,我確認同樣的錯誤File not found:
  • 當我使用修改后的端點https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&supportsAllDrives=true測試您的腳本時,我確認可以正確上傳文件。
  • 但是,如果您的服務帳戶沒有共享驅動器的寫入權限,則會發生錯誤。 請注意這一點。

參考

我希望這個片段有幫助

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from openpyxl import load_workbook
from openpyxl.drawing.image import Image as pyImage
from PIL import Image
import progressbar
import requests

def upload_as_csv(df, ver):

   title = "doc-{fver}.csv".format(fver=ver)

   path = 'output/{ftit}'.format(ftit=title)

   df.to_csv(path)

   gauth = GoogleAuth()
   drive = GoogleDrive(gauth)

   uploaded = drive.CreateFile({'title': title})
   uploaded.SetContentFile(path)
   uploaded.Upload()
   print('Uploaded file with ID {}'.format(uploaded.get('id')))
   print('Version number {}'.format(ver))

   return True

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM