我是一名Ruby开发人员,尝试使用Python编写的Google Cloud Functions,并且将远程文件从给定的URL传输到Google Cloud Storage(GCS)遇到了麻烦。
在等效的RoR应用程序中,我下载到该应用程序的临时存储,然后上传到GSC。
我希望可以通过Cloud Function将远程文件简单地“下载”到我的GCS存储桶中。
这是我正在处理一些注释的简化示例,真正的代码从私有API提取URL,但这工作正常,并且不是问题所在。
from google.cloud import storage
project_id = 'my-project'
bucket_name = 'my-bucket'
destination_blob_name = 'upload.test'
storage_client = storage.Client.from_service_account_json('my_creds.json')
# This works fine
#source_file_name = 'localfile.txt'
# When using a remote URL I get 'IOError: [Errno 2] No such file or directory'
source_file_name = 'http://www.hospiceofmontezuma.org/wp-content/uploads/2017/10/confused-man.jpg'
def upload_blob(bucket_name, source_file_name, destination_blob_name):
bucket = storage_client.get_bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(source_file_name)
upload_blob(bucket_name, source_file_name, destination_blob_name)
谢谢。
答案 0 :(得分:2)
无法直接从URL将文件上传到Google Cloud Storage。由于您是在本地环境中运行脚本,因此要上载的文件内容必须在同一环境中。这意味着url的内容需要存储在内存中或文件中。
根据您的代码显示如何执行此操作的示例:
选项1 :您可以使用wget
模块,该模块将获取url并将其内容下载到本地文件中(类似于wget
CLI命令)。请注意,这意味着文件将存储在本地,然后从文件上传。上传完成后,我添加了os.remove
行以删除文件。
from google.cloud import storage
import wget
import io, os
project_id = 'my-project'
bucket_name = 'my-bucket'
destination_blob_name = 'upload.test'
storage_client = storage.Client.from_service_account_json('my_creds.json')
source_file_name = 'http://www.hospiceofmontezuma.org/wp-content/uploads/2017/10/confused-man.jpg'
def upload_blob(bucket_name, source_file_name, destination_blob_name):
filename = wget.download(source_file_name)
bucket = storage_client.get_bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_filename(filename, content_type='image/jpg')
os.remove(filename)
upload_blob(bucket_name, source_file_name, destination_blob_name)
选项2 :使用urllib
模块,其工作方式与wget
模块类似,但是它不是写入文件,而是写入变量。请注意,如果您打算在Python 2.X中运行脚本,我将在Python3 there are some differences中进行此示例。
from google.cloud import storage
import urllib.request
project_id = 'my-project'
bucket_name = 'my-bucket'
destination_blob_name = 'upload.test'
storage_client = storage.Client.from_service_account_json('my_creds.json')
source_file_name = 'http://www.hospiceofmontezuma.org/wp-content/uploads/2017/10/confused-man.jpg'
def upload_blob(bucket_name, source_file_name, destination_blob_name):
file = urllib.request.urlopen(source_file_name)
bucket = storage_client.get_bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_string(link.read(), content_type='image/jpg')
upload_blob(bucket_name, source_file_name, destination_blob_name)
答案 1 :(得分:0)
可以通过Cloud Transfer服务将URL直接传输到GCS中,但是为单个URL设置云传输作业会产生很多开销。这类解决方案针对的情况是需要成为GCS对象的数百万个URL。
相反,我建议编写一份作业,将读取URL的传入流泵送到GCS的写入流中,并在Google Cloud中靠近存储桶的某个位置运行它。