将文件从URL传输到Cloud Storage

时间:2019-01-17 12:14:49

标签: python google-cloud-platform google-cloud-storage google-cloud-functions

我是一名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)

谢谢。

2 个答案:

答案 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中靠近存储桶的某个位置运行它。