如何使用 Google Drive API v3 将可恢复的上传到 Python 中的共享文件夹?
How do I do a resumable upload to a shared folder in Python using Google Drive API v3?
我正在尝试使用 Google 驱动器 API v3 和 Python 3.10.4 将文件上传到 Google 驱动器。我正在尝试进行可恢复的上传。我成功地获取了开始上传的 URI 位置,但是当我尝试将文件上传到该位置时,我从 Google.
返回了 404
原因:'notFound',
消息:'File not found: #FileIdHere',
位置类型:'parameter',
位置:'fileId'
Google 为我提供了我要上传到的文件夹的 fileId。它与我从 get_folderId 函数中获得的 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)
在上述函数的参数变量中,我尝试添加 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.
,在您的情况下,我认为您可能想要将文件上传到共享云端硬盘中的文件夹。
如果我的理解是正确的,从你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
我正在尝试使用 Google 驱动器 API v3 和 Python 3.10.4 将文件上传到 Google 驱动器。我正在尝试进行可恢复的上传。我成功地获取了开始上传的 URI 位置,但是当我尝试将文件上传到该位置时,我从 Google.
返回了 404原因:'notFound', 消息:'File not found: #FileIdHere', 位置类型:'parameter', 位置:'fileId'
Google 为我提供了我要上传到的文件夹的 fileId。它与我从 get_folderId 函数中获得的 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)
在上述函数的参数变量中,我尝试添加 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.
,在您的情况下,我认为您可能想要将文件上传到共享云端硬盘中的文件夹。
如果我的理解是正确的,从你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