如何使用 Python API 在 Google Cloud Storage 上上传文件夹
Posted
技术标签:
【中文标题】如何使用 Python API 在 Google Cloud Storage 上上传文件夹【英文标题】:How to upload folder on Google Cloud Storage using Python API 【发布时间】:2014-10-25 07:24:33 【问题描述】:我已在Google Cloud Storage
上成功上传单个文本文件。但是当我尝试上传whole folder
时,它会授予权限denied error.
filename = "d:/foldername" #here test1 is the folder.
Error:
Traceback (most recent call last):
File "test1.py", line 142, in <module>
upload()
File "test1.py", line 106, in upload
media = MediaFileUpload(filename, chunksize=CHUNKSIZE, resumable=True)
File "D:\jatin\Project\GAE_django\GCS_test\oauth2client\util.py", line 132, in positional_wrapper
return wrapped(*args, **kwargs)
File "D:\jatin\Project\GAE_django\GCS_test\apiclient\http.py", line 422, in __init__
fd = open(self._filename, 'rb')
IOError: [Errno 13] Permission denied: 'd:/foldername'
【问题讨论】:
整个文件夹。?我想你需要检查developers.google.com/appengine/docs/python/blobstore/… 压缩文件夹并上传。 【参考方案1】:该解决方案也可用于 Windows 系统。只需提供文件夹名称即可上传目标存储桶名称。此外,它可以处理文件夹中的任何级别的子目录。
import os
from google.cloud import storage
storage_client = storage.Client()
def upload_files(bucketName, folderName):
"""Upload files to GCP bucket."""
bucket = storage_client.get_bucket(bucketName)
for path, subdirs, files in os.walk(folderName):
for name in files:
path_local = os.path.join(path, name)
blob_path = path_local.replace('\\','/')
blob = bucket.blob(blob_path)
blob.upload_from_filename(path_local)
【讨论】:
【参考方案2】:没有递归函数的版本,它适用于“***文件”(与***答案不同):
import glob
import os
from google.cloud import storage
GCS_CLIENT = storage.Client()
def upload_from_directory(directory_path: str, dest_bucket_name: str, dest_blob_name: str):
rel_paths = glob.glob(directory_path + '/**', recursive=True)
bucket = GCS_CLIENT.get_bucket(dest_bucket_name)
for local_file in rel_paths:
remote_path = f'dest_blob_name/"/".join(local_file.split(os.sep)[1:])'
if os.path.isfile(local_file):
blob = bucket.blob(remote_path)
blob.upload_from_filename(local_file)
【讨论】:
这个脚本对我有用,但我只需要修改:bucket = GCS_CLIENT.bucket(dest_bucket_name) 而不是 bucket = GCS_CLIENT.get_bucket(dest_bucket_name)【参考方案3】:这对我有用。将本地目录中的所有内容复制到谷歌云存储中的特定存储桶名称/完整路径(递归):
import glob
from google.cloud import storage
def upload_local_directory_to_gcs(local_path, bucket, gcs_path):
assert os.path.isdir(local_path)
for local_file in glob.glob(local_path + '/**'):
if not os.path.isfile(local_file):
upload_local_directory_to_gcs(local_file, bucket, gcs_path + "/" + os.path.basename(local_file))
else:
remote_path = os.path.join(gcs_path, local_file[1 + len(local_path):])
blob = bucket.blob(remote_path)
blob.upload_from_filename(local_file)
upload_local_directory_to_gcs(local_path, bucket, BUCKET_FOLDER_DIR)
【讨论】:
这不适用于第一级的文件,但适用于更深层次的所有文件。第一级文件将截断文件名中的第一个字符 你可以使用glob.glob(local_path + "/**", recursive=True)
,然后if os.path.isfile(local_file): upload_file
来简化它【参考方案4】:
参考 - https://hackersandslackers.com/manage-files-in-google-cloud-storage-with-python/
from os import listdir
from os.path import isfile, join
...
def upload_files(bucketName):
"""Upload files to GCP bucket."""
files = [f for f in listdir(localFolder) if isfile(join(localFolder, f))]
for file in files:
localFile = localFolder + file
blob = bucket.blob(bucketFolder + file)
blob.upload_from_filename(localFile)
return f'Uploaded files to "bucketName" bucket.'
【讨论】:
【参考方案5】:文件夹是包含对文件和目录的引用的编目结构。该库将不接受文件夹作为参数。
据我了解,您的用例是上传到 GCS 并保留本地文件夹结构。为此,您可以使用 os python 模块并创建一个将路径作为参数的递归函数(例如 process_folder)。该逻辑可用于函数:
-
使用 os.listdir() 方法获取源路径中的对象列表(将返回文件和文件夹)。
遍历步骤 1 中的列表,通过 os.path.isdir() 方法将文件与文件夹分开。
迭代文件并使用调整后的路径上传它们(例如路径+“/”+文件名)。
遍历文件夹进行递归调用(例如 process_folder(path+folder_name))。
有必要使用两条路径:
-
与 os 模块一起使用的真实系统路径(例如“/Users/User/.../upload_folder/folder_name”)。
GCS 文件上传的虚拟路径(例如,“upload”+”/“ + folder_name + ”/“ + file_name)。
不要忘记实现 [1] 中引用的指数退避来处理 500 个错误。您可以使用 [2] 中的 Drive SDK 示例作为参考。
[1] - https://developers.google.com/storage/docs/json_api/v1/how-tos/upload#exp-backoff [2] - https://developers.google.com/drive/web/handle-errors
【讨论】:
【参考方案6】:我认为纯粹的filename = "D:\foldername"
没有足够的源代码信息。我也不确定这是否可能......通过网络界面,您也可以上传文件或创建文件夹,然后上传文件。
您可以保存文件夹名称,然后创建它(我从未使用过 google-app-engine,但我想应该可以),然后将内容上传到新文件夹
【讨论】:
以上是关于如何使用 Python API 在 Google Cloud Storage 上上传文件夹的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 python 发送 REST API(Google Vision 的 API)请求?
如何使用 Python API 在 Google Cloud Storage 上上传文件夹
如何使用 Google Sheets API python 将下拉列表添加到 google sheet
在 Python 项目中设置 GOOGLE_APPLICATION_CREDENTIALS 以使用 Google API
如何使用Appengine和来自API的Python脚本流数据将数据流式传输到Google Cloud BigQuery?