使用Google App Engine Python将外部链接中的图像上传到Google云存储

7
我正在寻找一种解决方案,以便使用Appengine Python将来自外部URL(例如http://example.com/image.jpg)的图片上传到Google Cloud Storage。
我现在正在使用:
blobstore.create_upload_url('/uploadSuccess', gs_bucket_name=bucketPath)

对于想要从他们的电脑上传图片的用户,调用
images.get_serving_url(gsk,size=180,crop=True)

在上传成功后,将其存储为用户的个人资料图片。我正在尝试允许用户在使用OAuth2登录后使用他们的Facebook或Google个人资料图片。我可以访问他们的个人资料图片链接,并希望复制它以保持一致性。请帮忙 :)
3个回答

13

上传外部图像需要获取并保存它。获取图像,您可以使用此代码

from google.appengine.api import urlfetch

file_name = 'image.jpg'
url = 'http://example.com/%s' % file_name
result = urlfetch.fetch(url)
if result.status_code == 200:
    doSomethingWithResult(result.content)

要保存该图像,您可以使用在此处显示的应用引擎GCS客户端代码。

import cloudstorage as gcs
import mimetypes

doSomethingWithResult(content):

    gcs_file_name = '/%s/%s' % ('bucket_name', file_name)
    content_type = mimetypes.guess_type(file_name)[0]
    with gcs.open(gcs_file_name, 'w', content_type=content_type,
                  options={b'x-goog-acl': b'public-read'}) as f:
        f.write(content)

    return images.get_serving_url(blobstore.create_gs_key('/gs' + gcs_file_name))

非常感谢!你的回答太棒了。运行得很好,而且非常全面。@voscausa 太棒了!我想给你的回答点赞,但我没有足够的声望 :) - Rob

2
这是我使用`google-cloud-storage`库和`upload_from_string()`函数的新解决方案(2019年)(请参见此处): 最初的回答
from google.cloud import storage
import urllib.request

BUCKET_NAME = "[project_name].appspot.com" # change project_name placeholder to your preferences
BUCKET_FILE_PATH = "path/to/your/images" # change this path

def upload_image_from_url_to_google_storage(img_url, img_name):
    """
    Uploads an image from a URL source to google storage.
    - img_url: string URL of the image, e.g. https://picsum.photos/200/200
    - img_name: string name of the image file to be stored
    """
    storage_client = storage.Client()
    bucket = storage_client.get_bucket(BUCKET_NAME)
    blob = bucket.blob(BUCKET_FILE_PATH + "/" + img_name + ".jpg")

    # try to read the image URL
    try:
        with urllib.request.urlopen(img_url) as response:
            # check if URL contains an image
            info = response.info()
            if(info.get_content_type().startswith("image")):
                blob.upload_from_string(response.read(), content_type=info.get_content_type())
                print("Uploaded image from: " + img_url)
            else:
                print("Could not upload image. No image data type in URL")
    except Exception:
        print('Could not upload image. Generic exception: ' + traceback.format_exc())

0

如果你正在寻找一种使用 storages 包的更新方式来完成这个操作,我编写了以下这两个函数:

import requests
from storages.backends.gcloud import GoogleCloudStorage


def download_file(file_url, file_name):
    response = requests.get(file_url)
    if response.status_code == 200:
        upload_to_gc(response.content, file_name)


def upload_to_gc(content, file_name):
    gc_file_name = "{}/{}".format("some_container_name_here", file_name)
    with GoogleCloudStorage().open(name=gc_file_name, mode='w') as f:
        f.write(content)

通常情况下,您可以从系统中任何位置调用download_file()函数,并传递urlprefered_file_name参数。

GoogleCloudStorage类来自于django-storages包。

pip install django-storages

Django Storages


嘿!这个 GoogleCloudStorage 模块是从哪里来的?它不是通过通常的 google-cloud-storage 包获得的吗? - Timo Wagner
@TimoWagner 这个来自于 storages 包,可以通过 pip install django-storages 安装。 - Ramy M. Mousa
感谢Ramy的澄清...我发布了另一个解决方案,使用google-cloud-storage库。如果您不想/不需要Django(请参见此处 - Timo Wagner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接