I'd like to run in a local environment a Python script which is normally run in a Docker container. The docker-compose.yml
specifies an env_file which looks (partially) like the following:
DB_ADDR=rethinkdb
DB_PORT=28015
DB_NAME=ipercron
In order to run this locally, I would like these lines to be converted to
os.environ['DB_ADDR'] = 'rethinkdb'
os.environ['DB_PORT'] = '28015'
os.environ['DB_NAME'] = 'ipercron'
I could write my parser, but I was wondering if there are any existing modules/tools to read in environment variables from configuration files?
You can use ConfigParser
. Sample example can be found here.
But this library expects your key
=value
data to be present under some [heading]
. For example, like:
[mysqld]
user = mysql # Key with values
pid-file = /var/run/mysqld/mysqld.pid
skip-external-locking
old_passwords = 1
skip-bdb # Key without value
skip-innodb
This could also work for you:
env_vars = []
with open(env_file) as f:
for line in f:
if line.startswith('#') or not line.strip():
continue
# if 'export' not in line:
# continue
# Remove leading `export `, if you have those
# then, split name / value pair
# key, value = line.replace('export ', '', 1).strip().split('=', 1)
key, value = line.strip().split('=', 1)
# os.environ[key] = value # Load to local environ
env_vars.append({'name': key, 'value': value}) # Save to a list
print(env_vars);
In the comments you'll find a few different ways to save the env vars and also a few parsing options i.e. to get rid of leading export
keyword. Another way would be to use the python-dotenv library. Cheers.
Using only python std
import re
envre = re.compile(r'''^([^\s=]+)=(?:[\s"']*)(.+?)(?:[\s"']*)$''')
result = {}
with open('/etc/os-release') as ins:
for line in ins:
match = envre.match(line)
if match is not None:
result[match.group(1)] = match.group(2)
I will use https://pypi.org/project/python-dotenv/ just type pip install python-dotenv
and then in your code you can use
from dotenv import load_dotenv
load_dotenv()
this is the way i do when i need to test code outside my docker system, and prepare it to return it into docker again.
How about this for a more compact solution:
import os
with open('.docker-compose-env', 'r') as fh:
vars_dict = dict(
tuple(line.split('='))
for line in fh.readlines() if not line.startswith('#')
)
print(vars_dict)
os.environ.update(vars_dict)