代码之家  ›  专栏  ›  技术社区  ›  Milenko Markovic

如何使用Python读取JSON?操作系统错误:[Errno 36]文件名太长:

  •  0
  • Milenko Markovic  · 技术社区  · 5 月前

    我正在使用CircleCI,我的凭证在这一步被解码

    echo 'export SERVICE_ACCOUNT_DECODED="$(echo $SERVICE_ACCOUNT | base64 -di)"' >> $BASH_ENV
    

    后来我使用Python代码

    service_account_file = json.dumps(os.environ['SERVICE_ACCOUNT_DECODED'])
        # Authenticate using the service account for Google Drive
    credentials = service_account.Credentials.from_service_account_file(service_account_file, scopes=SCOPES)
    

    我的目标是service_account_file是JSON。

    但出现了错误

      File "final_script.py", line 28, in <module>
        credentials = service_account.Credentials.from_service_account_file(service_account_file, scopes=SCOPES)
      File "/home/circleci/.pyenv/versions/3.8.20/lib/python3.8/site-packages/google/oauth2/service_account.py", line 260, in from_service_account_file
        info, signer = _service_account_info.from_filename(
      File "/home/circleci/.pyenv/versions/3.8.20/lib/python3.8/site-packages/google/auth/_service_account_info.py", line 78, in from_filename
        with io.open(filename, "r", encoding="utf-8") as json_file:
    OSError: [Errno 36] File name too long: '"{\\n
    

    我之前尝试过json.loads,但它也不起作用。

    如何解决这个问题?

    2 回复  |  直到 5 月前
        1
  •  2
  •   mkrieger1 djuarezg    5 月前

    你正试图通过一个 JSON字符串 将凭据包含到需要 文件名 包含凭据的JSON文件。

    documentation ,我们可以在第二个例子中看到,如果还有另一个函数用于创建 Credentials 适合您情况的对象:

    或者,如果您已经加载了服务帐户文件:

    service_account_info = json.load(open('service_account.json'))
    credentials = service_account.Credentials.from_service_account_info(
        service_account_info)
    

    这个 SERVICE_ACCOUNT_DECODED 已经是JSON字符串。您不应该使用 json.dumps 再次打开它(用于将Python对象转换为JSON,因此您将得到一个包含另一个JSON字符串的JSON字符串)。

    相反,使用 json.loads 从字符串中解压缩内容,这些内容对应于 service_account_info 上面:

    service_account_info = json.loads(os.environ['SERVICE_ACCOUNT_DECODED'])
    credentials = service_account.Credentials.from_service_account_info(
        service_account_info, scopes=SCOPES
    )
    
        2
  •  2
  •   Lewis    5 月前

    假设SERVICE_ACCOUNT_DECODED包含JSON内容,那么您必须使用此内容创建一个临时文件。

    import tempfile
    
    with tempfile.NamedTemporaryFile('w+') as f:
        f.write(os.environ['SERVICE_ACCOUNT_DECODED'])
        f.flush()  # clears the internal buffer of the file
        credentials = service_account.Credentials.from_service_account_file(f.name, scopes=SCOPES)
    

    希望它能起作用,但出于安全原因,我建议您不要将服务帐户凭据等敏感信息直接存储在环境变量中。