【问题标题】:How can we store a JSON credential to ENV variable in python?我们如何在 python 中将 JSON 凭证存储到 ENV 变量?
【发布时间】:2022-11-27 10:23:15
【问题描述】:
{
    "type": "service_account",
    "project_id": "project_id",
    "private_key_id": "private_key_id",
    "private_key": "-----BEGIN PRIVATE KEY-----\n",
    "client_email": "email",
    "client_id": "id",
    "auth_uri": "uri_auth",
    "token_uri": "token_urin",
    "auth_provider_x509_cert_url": "auth_provider_x509_cert_url",
    "client_x509_cert_url": "client_x509_cert_url"
}

我尝试对 JSON 进行编码和解码,但没有成功

我什至尝试使用 /// 代替 " "

所以我正在使用 sheets-api。我想要实现的是从 .env 变量加载 path-for-json-file

scope=['https://spreadsheets.google.com/feeds',
      'https://www.googleapis.com/auth/drive',
      'https://www.googleapis.com/auth/drive.file',
      'https://www.googleapis.com/auth/spreadsheets'
      ]
credentials = ServiceAccountCredentials.from_json_keyfile_name(r"path-for-json-file", scope)
client = gspread.authorize(credentials)

【问题讨论】:

    标签: python json dotenv


    【解决方案1】:

    假设你的 JSON 文件是creds.json

    信用证.json

    {
        "type": "service_account",
        "project_id": "project_id",
        "private_key_id": "private_key_id",
        "private_key": "-----BEGIN PRIVATE KEY-----
    ",
        "client_email": "email",
        "client_id": "id",
        "auth_uri": "uri_auth",
        "token_uri": "token_urin",
        "auth_provider_x509_cert_url": "auth_provider_x509_cert_url",
        "client_x509_cert_url": "client_x509_cert_url"
    }
    

    主程序

    import json
    
    data = json.load(open('creds.json'))
    
    f = open(".env", "x")
    
    for key, value in data.items():
        f.write(f"{key.upper()}={value}
    ")
    

    将生成 creds.env

    TYPE=service_account
    PROJECT_ID=project_id
    PRIVATE_KEY_ID=private_key_id
    PRIVATE_KEY=-----BEGIN PRIVATE KEY-----
    
    CLIENT_EMAIL=email
    CLIENT_ID=id
    AUTH_URI=uri_auth
    TOKEN_URI=token_urin
    AUTH_PROVIDER_X509_CERT_URL=auth_provider_x509_cert_url
    CLIENT_X509_CERT_URL=client_x509_cert_url
    

    create_keyfile_dict() 基本上返回一个名为 variable_keys 的字典

    from dotenv import load_dotenv
    
    load_dotenv()
    
    def create_keyfile_dict():
        variables_keys = {
            "type": os.getenv("TYPE"),
            "project_id": os.getenv("PROJECT_ID"),
            "private_key_id": os.getenv("PRIVATE_KEY_ID"),
            "private_key": os.getenv("PRIVATE_KEY"),
            "client_email": os.getenv("CLIENT_EMAIL"),
            "client_id": os.getenv("CLIENT_ID"),
            "auth_uri": os.getenv("AUTH_URI"),
            "token_uri": os.getenv("TOKEN_URI"),
            "auth_provider_x509_cert_url": os.getenv("AUTH_PROVIDER_X509_CERT_URL"),
            "client_x509_cert_url": os.getenv("CLIENT_X509_CERT_URL")
        }
        return variables_keys
    
    scope=['https://spreadsheets.google.com/feeds',
          'https://www.googleapis.com/auth/drive',
          'https://www.googleapis.com/auth/drive.file',
          'https://www.googleapis.com/auth/spreadsheets'
          ]
    credentials = ServiceAccountCredentials.from_json_keyfile_name(create_keyfile_dict(), scope)
    client = gspread.authorize(credentials)
    

    【讨论】:

    • 如果我们有字典对象列表怎么办?
    • private_key 包含一个特殊字符 ,您的 main.py 代码中未考虑该字符。 (注意PRIVATE_KEYCLIENT_EMAIL 之间的额外空白)。你也应该add double quotes to the values as a safety measure
    【解决方案2】:

    使用单个 env 变量的更简单方法

    • 首先将您的 JSON 编码为 base-64,如下所示:
    import json
    import base64
    import os
    from dotenv import load_dotenv, find_dotenv
    
    
    service_key = {
        "type": "service_account",
        "project_id": "project_id",
        "private_key_id": "private_key_id",
        "private_key": "-----BEGIN PRIVATE KEY-----
    ",
        "client_email": "email",
        "client_id": "id",
        "auth_uri": "uri_auth",
        "token_uri": "token_urin",
        "auth_provider_x509_cert_url": "auth_provider_x509_cert_url",
        "client_x509_cert_url": "client_x509_cert_url"
    }
    
    # convert json to a string
    service_key = json.dumps(service_key)
    
    # encode service key
    encoded_service_key = base64.b64encode(service_key.encode('utf-8'))
    
    print(encoded_service_key)
    # b'many_characters_here'
    
    • 在你的.env文件中,添加一个环境变量SERVICE_ACCOUNT_KEY,值为encoded_service_key
    SERVICE_ACCOUNT_KEY = b'a_long_string'
    
    • 现在将编码的字符串转换回 JSON:
    # get the value of `SERVICE_ACCOUNT_KEY`environment variable
    load_dotenv(find_dotenv())
    encoded_key = os.getenv("SERVICE_ACCOUNT_KEY")
    
    # remove the first two chars and the last char in the key
    encoded_key = str(encoded_key)[2:-1]
    
    # decode
    original_service_key= json.loads(base64.b64decode(encoded_key).decode('utf-8'))
    
    print(original_service_key['private_key_id'])
    # private_key_id
    
    # credentials = ServiceAccountCredentials.from_json_keyfile_name(
    #     original_service_key, scope)
    # client = gspread.authorize(credentials)
    

    【讨论】:

      猜你喜欢
      • 2019-01-10
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      • 2021-04-04
      • 2016-09-23
      • 1970-01-01
      • 2014-05-10
      • 2018-04-04
      相关资源
      最近更新 更多