Photo by Lysander Yuen on Unsplash
Complex Stuff as Environment Variables
Do not limit yourself with strings
There might be a time where you want to pass something more complex than a string as an enviroment variable to your VM or Docker container or simply you want to set it on your local system. It could be a JSON object or it could be a string with non ASCII characters.
I recently needed to pass a pem certificate as an environment variable, along with many other variables. It was a bit trickier than I thought...
One could argue passing certificate as an env variable may be not the best approach but in my case I had simply no other option.
The solution I settled was to serialize it to base64 string. Function below serializes a python dict as ASCII string so that we can pass as env variable.
import json
import base64
def serialize_dict(d: dict) -> str:
"""
Encode a dictionary into a base64 string
:param d: dictionary
:return: base56 ascii string
>>> my_dict = {'a': 3, 'b': 4}
>>> encode_dict_to_b64(my_dict)
'eyJhIjogMywgImIiOiA0fQ=='
"""
ascii_byte = json.dumps(d).encode('ascii')
return base64.b64encode(ascii_byte).decode('ascii')
You can decode base64 encoded string back to python dict again.
def deserialize_dict(base64string) -> dict:
"""
Deserialize a base64 string back to python dict
:param base64string: base64 ascii encoded string
:return: Python dict
>>> my_str = 'eyJhIjogMywgImIiOiA0fQ=='
>>> decode_b64str_to_dict(my_str)
{'a': 3, 'b': 4}
"""
try:
decoded_json = base64.b64decode(base64string.encode('ascii')).decode('ascii')
return json.loads(decoded_json)
except Exception as e:
raise ValueError(f"Failed to decode {base64string} to a python dict: {e}")
Disclaimer: It's been a while since I solved this issue and initially I read about this idea somewhere but cannot remember where it was now. So credits/kudos to that person. Mine is just a quick implementation of that idea.