How to pass a list as an environment variable?

PythonPython 2.7

Python Problem Overview


I use a list as part of a Python program, and wanted to convert that to an environment variable.

So, it's like this:

list1 = ['a.1','b.2','c.3']
for items in list1:
    alpha,number = items.split('.')
    print(alpha,number)

which gives me, as expected:

a 1
b 2
c 3

But when I try to set it as an environment variable, as:

export LIST_ITEMS = 'a.1', 'b.2', 'c.3'

and do:

list1 = [os.environ.get("LIST_ITEMS")]
for items in list1:
    alpha,number = items.split('.')
    print(alpha,number)

I get an error: ValueError: too many values to unpack

How do I modify the way I pass the list, or get it so that I have the same output as without using env variables?

Python Solutions


Solution 1 - Python

The rationale

I recommend using JSON if you want to have data structured in an environment variable. JSON is simple to write / read, can be written in a single line, parsers exist, developers know it.

The solution

To test, execute this in your shell:

$ export ENV_LIST_EXAMPLE='["Foo", "bar"]'

Python code to execute in the same shell:

import os
import json

env_list = json.loads(os.environ['ENV_LIST_EXAMPLE'])
print(env_list)
print(type(env_list))

gives

['Foo', 'bar']
<class 'list'>

Package

Chances are high that you are interested in cfg_load

Debugging

If you see

JSONDecodeError: Expecting value: line 1 column 2 (char 1)

You might have used single-quotes instead of double-quotes. While some JSON libraries accept that, the JSON standard clearly states that you need to use double-quotes:

Wrong: "['foo', 'bar']"
Right: '["foo", "bar"]'

Solution 2 - Python

I'm not sure why you'd do it through the environment variables, but you can do this:

export LIST_ITEMS ="a.1 b.2 c.3"

And in Python:

list1 = [i.split(".") for i in os.environ.get("LIST_ITEMS").split(" ")] 

for k, v in list1:
    print(k, v)

Solution 3 - Python

The environs PyPI package handles my use case well: load a single setting from env var and coerce it to a list, int, etc:

from environs import Env

env = Env()
env.read_env()  # read .env file, if it exists

# required variables
#  env: GITHUB_USER=sloria
gh_user = env("GITHUB_USER")  # => 'sloria'
#  env: <unset>
secret = env("SECRET")  # => raises error if not set

# casting
#  env: MAX_CONNECTIONS=100
max_connections = env.int("MAX_CONNECTIONS")  # => 100
#  env: SHIP_DATE='1984-06-25'
ship_date = env.date("SHIP_DATE")  # => datetime.date(1984, 6, 25)
#  env: TTL=42
ttl = env.timedelta("TTL")  # => datetime.timedelta(0, 42)

# providing a default value
#  env: ENABLE_LOGIN=true
enable_login = env.bool("ENABLE_LOGIN", False)  # => True
#  env: <unset>
enable_feature_x = env.bool("ENABLE_FEATURE_X", False)  # => False

# parsing lists
#  env: GITHUB_REPOS=webargs,konch,ped
gh_repos = env.list("GITHUB_REPOS")  # => ['webargs', 'konch', 'ped']
#  env: COORDINATES=23.3,50.0
coords = env.list("COORDINATES", subcast=float)  # => [23.3, 50.0]

Solution 4 - Python

If you want to set the environment variable using that format — ['a.1','b.2','c.3'] — this would work:

from ast import literal_eval

list1 = [literal_eval(e.strip()) for e in os.environ["LIST_ITEMS"].split(',')]
for item in list1:
    alpha,number = item.split('.')
    print alpha, number

Output:

a 1
b 2
c 3

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCodingInCirclesView Question on Stackoverflow
Solution 1 - PythonMartin ThomaView Answer on Stackoverflow
Solution 2 - PythonReut SharabaniView Answer on Stackoverflow
Solution 3 - PythontheY4KmanView Answer on Stackoverflow
Solution 4 - PythonmartineauView Answer on Stackoverflow