You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用django-storages+App Engine+Python3.x时get_serving_url无提示失败

问题描述

开发Django项目时使用django-storages对接Google Cloud Storage存储媒体文件,尝试通过get_serving_url提供文件服务时无提示失败,异常无日志文本。BlobKey生成正常,但调用images.get_serving_url(blobkey, secure_url=True)时抛出无错误文本的异常。

实现代码

storage_backends.py

class GoogleCloudMediaStorage(GoogleCloudStorage):
    """GoogleCloudStorage suitable for Django's Media files."""

    def __init__(self, *args, **kwargs):
        if not settings.MEDIA_URL:
            raise Exception('MEDIA_URL has not been configured')
        kwargs['bucket_name'] = setting('GS_MEDIA_BUCKET_NAME')
        super(GoogleCloudMediaStorage, self).__init__(*args, **kwargs)

    # 此方法工作正常
    def url(self, name):
        """.url that doesn't call Google."""
        return urljoin(settings.MEDIA_URL, name)

    # 此方法暂不工作
    def serving_url(self, name):
        logging.info('serving url called')
        if settings.DEBUG:
            return urljoin(settings.MEDIA_URL, name)
        else:    
            # 应用的GCS存储桶及使用的文件夹结构
            try:
                logging.info('trying to get serving_url')
                filename = settings.GS_MEDIA_BUCKET_NAME + '/' + name
                logging.info(filename)
                blobkey = blobstore.create_gs_key('/gs/' + filename) 
                logging.info('This is a blobkey')
                logging.info(blobkey)
                image = images.get_serving_url(blobkey, secure_url=True)
                return image
            except Exception as e:
                logging.warn('didnt work')
                logging.warn(e)
                return urljoin(settings.MEDIA_URL, name)

main.py

from antiques_project.wsgi import application
from google.appengine.api import wrap_wsgi_app

app = wrap_wsgi_app(application)

app.yaml配置

app_engine_apis: true

已安装appengine-python-standard,尝试过多种BlobKey生成方式(带/不带桶名),secure_url设为False/True均无效。

补充错误追踪日志

Traceback (most recent call last):
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/api/images/__init__.py", line 2013, in get_serving_url_hook
rpc.check_success()
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/api/apiproxy_stub_map.py", line 614, in check_success
self.__rpc.CheckSuccess()
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/api/apiproxy_rpc.py", line 149, in CheckSuccess
raise self.exception
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/runtime/default_api_stub.py", line 276, in _CaptureTrace
f(**kwargs)
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/runtime/default_api_stub.py", line 269, in _SendRequest
raise self._TranslateToError(parsed_response)
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/runtime/default_api_stub.py", line 138, in _TranslateToError
raise apiproxy_errors.ApplicationError(response.application_error.code,
google.appengine.runtime.apiproxy_errors.ApplicationError: ApplicationError: 1

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/srv/config/storage_backends.py", line 50, in serving_url
image = images.get_serving_url(blobkey, secure_url=True)
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/api/images/__init__.py", line 1911, in get_serving_url
return rpc.get_result()
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/api/apiproxy_stub_map.py", line 648, in get_result
return self.__get_result_hook(self)
File "/layers/google.python.pip/pip/lib/python3.10/site-packages/google/appengine/api/images/__init__.py", line 2015, in get_serving_url_hook
raise _ToImagesError(e, readable_blob_key)
google.appengine.api.images.TransformationError
解决方案

1. 检查服务账号权限

get_serving_url要求App Engine默认服务账号拥有Storage Object Viewer权限,确保该账号能正常访问GCS存储桶内的文件。

2. 验证BlobKey格式

生成BlobKey时必须严格遵循格式:/gs/[bucket-name]/[object-path],注意开头的斜杠不能省略,桶名和对象路径之间也不能多加分隔符。

3. 确认文件类型兼容性

images.get_serving_url仅支持图片格式(JPEG、PNG、GIF、BMP、TIFF、WebP等),如果尝试处理非图片文件会直接抛出TransformationError,先检查目标文件是否为有效图片。

4. 改用GCS签名URL替代

如果get_serving_url问题无法解决,可切换到GCS原生的签名URL方案,无需依赖App Engine Images API:

from google.cloud import storage
from datetime import timedelta

def serving_url(self, name):
    if settings.DEBUG:
        return urljoin(settings.MEDIA_URL, name)
    else:
        try:
            storage_client = storage.Client()
            bucket = storage_client.bucket(settings.GS_MEDIA_BUCKET_NAME)
            blob = bucket.blob(name)
            # 生成有效期1小时的签名URL
            url = blob.generate_signed_url(
                version="v4",
                expiration=timedelta(hours=1),
                method="GET",
            )
            return url
        except Exception as e:
            logging.warn(f"生成签名URL失败: {e}")
            return urljoin(settings.MEDIA_URL, name)

使用该方案需确保服务账号拥有Storage Object Signer角色,或已配置正确的密钥文件。

5. 确认环境配置

检查app.yaml中app_engine_apis: true配置是否生效,且部署环境为App Engine标准环境(弹性环境对部分App Engine API支持有限)。

内容的提问来源于stack exchange,提问作者Gabriel Ficht

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:00:55