python - 尝试使用谷歌云文本到语音 API 时无效的 JWT

标签 python google-cloud-platform

我遵循了这个非常简单的指南:https://cloud.google.com/text-to-speech/docs/quickstart-client-libraries?hl=en

按照python的步骤我没有发现问题,但是当我执行示例代码时出现这个错误:

/usr/bin/env /usr/bin/python /home/edoelas/.vscode/extensions/ms-python.python-2021.1.502429796/pythonFiles/lib/python/debugpy/launcher 41413 -- /home/edoelas/git/gsdeck/scripts/generateaudio.py 
Traceback (most recent call last):
  File "/home/edoelas/.local/lib/python3.9/site-packages/google/api_core/grpc_helpers.py", line 73, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/home/edoelas/.local/lib/python3.9/site-packages/grpc/_channel.py", line 923, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/home/edoelas/.local/lib/python3.9/site-packages/grpc/_channel.py", line 826, in _end_unary_response_blocking
    raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
        status = StatusCode.UNAVAILABLE
        details = "Getting metadata from plugin failed with error: ('invalid_grant: Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim.', '{"error":"invalid_grant","error_description":"Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim."}')"
        debug_error_string = "{"created":"@1612972534.048677552","description":"Getting metadata from plugin failed with error: ('invalid_grant: Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim.', '{"error":"invalid_grant","error_description":"Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim."}')","file":"src/core/lib/security/credentials/plugin/plugin_credentials.cc","file_line":90,"grpc_status":14}"
>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/edoelas/git/gsdeck/scripts/generateaudio.py", line 27, in <module>
    response = client.synthesize_speech(
  File "/home/edoelas/.local/lib/python3.9/site-packages/google/cloud/texttospeech_v1/services/text_to_speech/client.py", line 374, in synthesize_speech
    response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
  File "/home/edoelas/.local/lib/python3.9/site-packages/google/api_core/gapic_v1/method.py", line 145, in __call__
    return wrapped_func(*args, **kwargs)
  File "/home/edoelas/.local/lib/python3.9/site-packages/google/api_core/grpc_helpers.py", line 75, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.ServiceUnavailable: 503 Getting metadata from plugin failed with error: ('invalid_grant: Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim.', '{"error":"invalid_grant","error_description":"Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim."}')

我没有任何使用谷歌云 API 的经验。不知道JWT是什么时候生成的,有没有问题。我还检查了我的系统时间,它看起来很好,除非我必须设置一个不同的时间来匹配谷歌云控制台或类似的时间。

编辑: 我没有在任何地方使用服务帐户手动进行身份验证,我只是按照指南中的说明设置了环境变量 GOOGLE_APPLICATION_CREDENTIALS。

我认为我可能会做一些奇怪的事情的步骤是在初始化 Cloud SDK 时。我只需转到终端,编写 gcloud init 创建一个新配置,选择我从中创建此服务帐户的 google 帐户,选择服务帐户所在的项目,仅此而已。

我没有设置 venv,因为据我所知,这对隔离 python 库很有用。

代码与指南中使用的相同:

"""Synthesizes speech from the input string of text or ssml.

Note: ssml must be well-formed according to:
    https://www.w3.org/TR/speech-synthesis/
"""
from google.cloud import texttospeech

# Instantiates a client
client = texttospeech.TextToSpeechClient()

# Set the text input to be synthesized
synthesis_input = texttospeech.SynthesisInput(text="Hello, World!")

# Build the voice request, select the language code ("en-US") and the ssml
# voice gender ("neutral")
voice = texttospeech.VoiceSelectionParams(
    language_code="en-US", ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL
)

# Select the type of audio file you want returned
audio_config = texttospeech.AudioConfig(
    audio_encoding=texttospeech.AudioEncoding.MP3
)

# Perform the text-to-speech request on the text input with the selected
# voice parameters and audio file type
response = client.synthesize_speech(
    input=synthesis_input, voice=voice, audio_config=audio_config
)

# The response's audio_content is binary.
with open("output.mp3", "wb") as out:
    # Write the response to the output file.
    out.write(response.audio_content)
    print('Audio content written to file "output.mp3"')

编辑 2:

按照 CLI 快速入门指南运行命令时:

curl -X POST \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
https://texttospeech.googleapis.com/v1/text:synthesize

我得到:

ERROR: (gcloud.auth.application-default.print-access-token) There was a problem refreshing your current auth tokens: ('invalid_grant: Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim.', '{"error":"invalid_grant","error_description":"Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim."}')
Please run:

  $ gcloud auth application-default login

to obtain new credentials.
{
  "error": {
    "code": 403,
    "message": "The request is missing a valid API key.",
    "status": "PERMISSION_DENIED"
  }
}

当运行 gcloud auth application-default login 时,显示如下:

The environment variable [GOOGLE_APPLICATION_CREDENTIALS] is set to:
  [/home/edoelas/git/gsdeck/credentials/service_account.json]
Credentials will still be generated to the default location:
  [/home/edoelas/.config/gcloud/application_default_credentials.json]
To use these credentials, unset this environment variable before
running your application.

Do you want to continue (Y/n)?  Y    

Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&state=jAxmGRv50BQxjUy1acQvcs6Pyp2jNM&access_type=offline&code_challenge=gjZ5y5t3T7b2M0lhvL5Eqwhfag6i7c91oEjcc2Tw5CA&code_challenge_method=S256

Opening in existing browser session.

Credentials saved to file: [/home/edoelas/.config/gcloud/application_default_credentials.json]

These credentials will be used by any library that requests Application Default Credentials (ADC).
/opt/google-cloud-sdk/lib/third_party/google/auth/_default.py:69: UserWarning: Your application has authenticated using end user credentials from Google Cloud SDK without a quota project. You might receive a "quota exceeded" or "API not enabled" error. We recommend you rerun `gcloud auth application-default login` and make sure a quota project is added. Or you can use service accounts instead. For more information about service accounts, see https://cloud.google.com/docs/authentication/
  warnings.warn(_CLOUD_SDK_CREDENTIALS_WARNING)

Quota project "gsdeck" was added to ADC which can be used by Google client libraries for billing and quota. Note that some services may still bill the project owning the resource.

最佳答案

我在 JWT token 中看到的主要原因之一是生成 token 的服务器与它试图与之通信的客户端不同步。

能否请您确保您的系统时间同步并且配置为保持自身更新to a NTP server

关于python - 尝试使用谷歌云文本到语音 API 时无效的 JWT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66139719/

相关文章:

python - 每当 ip 监视器写入 stdout 时调用脚本

Python Web 浏览器引擎

python - Python Wave音频采样率

kubernetes - 在 Google Kubernetes Engine 中的多个集群之间调用内部服务

python - 如何在 Appengine 中检查开发与产品?

python - 有没有办法使用 ReadFromText 转换(Python)在 Apache Beam 中读取多行 csv 文件?

python - 尝试使用 for 循环比较文本

python浮点性质并转换为较小的类型

kubernetes - 删除GCP Kubernetes上的默认CPU请求和限制

google-cloud-platform - 具有云负载均衡器的不同区域的 Google 容器引擎集群