How can we store a JSON credential to ENV variable in python?
Question:
{
"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"
}
I tried encoding and decoding the JSON but it didn’t work
I even tried using /// in place of " "
So I am using sheets-api. What I want to achieve is loading the path-for-json-file from .env variable
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)
Answers:
Assuming your JSON file is creds.json
creds.json
{
"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"
}
main.py
import json
data = json.load(open('creds.json'))
f = open(".env", "x")
for key, value in data.items():
f.write(f"{key.upper()}={value}n")
creds.env will be generated
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()
basically returns a dict called 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)
A simpler way using a single env
variable
- First encode your JSON in base-64 as follows:
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-----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"
}
# 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'
- In your
.env
file, add an environment variable SERVICE_ACCOUNT_KEY
with the value of encoded_service_key
:
SERVICE_ACCOUNT_KEY = b'a_long_string'
- Now to convert the encoded string back to 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)
{
"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"
}
I tried encoding and decoding the JSON but it didn’t work
I even tried using /// in place of " "
So I am using sheets-api. What I want to achieve is loading the path-for-json-file from .env variable
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)
Assuming your JSON file is creds.json
creds.json
{
"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"
}
main.py
import json
data = json.load(open('creds.json'))
f = open(".env", "x")
for key, value in data.items():
f.write(f"{key.upper()}={value}n")
creds.env will be generated
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()
basically returns a dict called 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)
A simpler way using a single env
variable
- First encode your JSON in base-64 as follows:
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-----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"
}
# 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'
- In your
.env
file, add an environment variableSERVICE_ACCOUNT_KEY
with the value ofencoded_service_key
:
SERVICE_ACCOUNT_KEY = b'a_long_string'
- Now to convert the encoded string back to 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)