【问题标题】:google.api_core.exceptions.PermissionDenied: 403 Error opening filegoogle.api_core.exceptions.PermissionDenied:403 打开文件时出错
【发布时间】:2019-08-01 03:08:59
【问题描述】:

我正在使用它的 Python 示例为Detect text in files (PDF/TIFF) 试用 Google Cloud Vision API,并遇到了这个错误:

google.api_core.exceptions.PermissionDenied:403 打开文件时出错:gs://input_folder/input.pdf

我正在使用

通过 json 键实例化客户端

client = vision.ImageAnnotatorClient(credentials=vision_credentials)

我创建了具有以下权限的服务帐户:所有者、存储管理员、存储对象管理员、存储传输管理员。请注意,我正在使用 Google 存储桶。

Traceback (most recent call last):
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\google\api_core\grpc_helpers.py", line 57, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\grpc\_channel.py", line 565, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\grpc\_channel.py", line 467, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
grpc._channel._Rendezvous: <_Rendezvous of RPC that terminated with:
        status = StatusCode.PERMISSION_DENIED
        details = "Error opening file: gs://input_folder/input.pdf."
        debug_error_string = "{"created":"@1564912541.032000000","description":"Error received from peer ipv4:172.217.194.95:443","file":"src/core/lib/surface/call.cc","file_line":1052,"grpc_message":"Error opening file: gs://input_folder/input.pdf.","grpc_status":7}"

The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "notepad.py", line 105, in <module>
    async_detect_document("gs://input_folder/input.pdf", "gs://output_folder_results/")
  File "notepad.py", line 62, in async_detect_document
    requests=[async_request])
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\google\cloud\vision_v1\gapic\image_annotator_client.py", line 484, in async_batch_annotate_files
    request, retry=retry, timeout=timeout, metadata=metadata
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\google\api_core\gapic_v1\method.py", line 143, in __call__
    return wrapped_func(*args, **kwargs)
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\google\api_core\retry.py", line 273, in retry_wrapped_func
    on_error=on_error,
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\google\api_core\retry.py", line 182, in retry_target
    return target()
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\google\api_core\timeout.py", line 214, in func_with_timeout
    return func(*args, **kwargs)
  File "C:\Users\Eva\AppData\Local\Programs\Python\Python37\lib\site-packages\google\api_core\grpc_helpers.py", line 59, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.PermissionDenied: 403 Error opening file: gs://input_folder/input.pdf.

我的代码:

from google.oauth2 import service_account
from google.cloud import vision
from google.cloud import storage
from google.protobuf import json_format
# Supported mime_types are: 'application/pdf' and 'image/tiff'
mime_type = 'application/pdf'

batch_size = 2

# Google credentials
VISION_SCOPES = ['https://www.googleapis.com/auth/cloud-vision']
SERVICE_ACCOUNT_FILE = 'C:\\Users\\Eva\\Desktop\\GoogleOCR\\cred.json'
vision_credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=VISION_SCOPES)

# Instantiates a client
client = vision.ImageAnnotatorClient(credentials=vision_credentials)

# Sample code
def async_detect_document(gcs_source_uri, gcs_destination_uri):
    feature = vision.types.Feature(
        type=vision.enums.Feature.Type.DOCUMENT_TEXT_DETECTION)

    gcs_source = vision.types.GcsSource(uri=gcs_source_uri)
    print(gcs_source)
    input_config = vision.types.InputConfig(
        gcs_source=gcs_source, mime_type=mime_type)

    gcs_destination = vision.types.GcsDestination(uri=gcs_destination_uri)
    print(gcs_destination)
    output_config = vision.types.OutputConfig(
        gcs_destination=gcs_destination, batch_size=batch_size)

    async_request = vision.types.AsyncAnnotateFileRequest(
        features=[feature], input_config=input_config,
        output_config=output_config)
    print(async_request)
    operation = client.async_batch_annotate_files(
        requests=[async_request])

    print('Waiting for the operation to finish.')
    operation.result(timeout=180)

    storage_client = storage.Client()

    match = re.match(r'gs://([^/]+)/(.+)', gcs_destination_uri)
    bucket_name = match.group(1)
    prefix = match.group(2)

    bucket = storage_client.get_bucket(bucket_name)

    blob_list = list(bucket.list_blobs(prefix=prefix))
    print('Output files:')
    for blob in blob_list:
        print(blob.name)
.
    output = blob_list[1]

    json_string = output.download_as_string()
    response = json_format.Parse(
        json_string, vision.types.AnnotateFileResponse())

    first_page_response = response.responses[0]
    annotation = first_page_response.full_text_annotation

    print(u'Full text:\n{}'.format(
        annotation.text))

async_detect_document("gs://input_folder/input.pdf", "gs://output_folder_results/")

更新:我尝试将存储桶对象公共访问权限设置为 AllUsers,但仍然收到相同的错误行

更新 2:发布完整的回溯错误

更新 3:发布了我的代码

【问题讨论】:

  • 您从哪个环境运行脚本?您的存储桶与服务帐号在同一个项目中还是在另一个项目中?
  • @Christopher 我正在通过 anaconda 运行脚本。是的,我的存储桶和服务帐户在同一个项目下。
  • 考虑到 SA 已经是项目的所有者,我想不出任何失败的原因,除非脚本正在获取一个无权访问您的 GCS 存储桶的凭证。您可能需要检查存储桶的继承所有者/权限,以查看服务帐户是否存在
  • 您是否使用服务帐户凭据的路由路径设置GOOGLE_APPLICATION_CREDENTIALS 环境变量?
  • @Christopher 我已经检查并正确分配了

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


【解决方案1】:

我不认为credentials 参数做你认为它做的事。如果您在 JSON 文件中有凭据,则需要使用 JSON 文件的路径设置环境变量 GOOGLE_APPLICATION_CREDENTIALS。或者,如果您将 JSON 文件 contents 加载到变量中,例如info,你可以这样做:

from google.oauth2.service_account import Credentials

vision_credentials = Credentials.from_service_account_info(info)
client = vision.ImageAnnotatorClient(credentials=vision_credentials)

【讨论】:

  • 我已经设置了环境变量,或者有代码将 JSON 文件内容加载到 vision_credentials 变量中,类似于您的建议。
  • @vvac 好的,抱歉,它对您不起作用,但它确实起作用。简单地将 JSON 文件内容加载到 vision_credentials 变量中是行不通的,它需要用于创建 Credentials 对象。那没有很好的记录(如果有的话?)并花了我一些工作来弄清楚。但也许你还有其他错误。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多