Python os.environ throws key error?

Question:

I’m accessing an environment variable in a script with os.environ.get and it’s throwing a KeyError. It doesn’t throw the error from the Python prompt. This is running on OS X 10.11.6, and is Python 2.7.10.

What is going on?

$ python score.py
Traceback (most recent call last):
  File "score.py", line 4, in <module>
    setup_logging()
  File "/score/log.py", line 29, in setup_logging
    config = get_config()
  File "/score/log.py", line 11, in get_config
    environment = os.environ.get('NODE_ENV')
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/UserDict.py", line 23, in __getitem__
    raise KeyError(key)
KeyError: 'NODE_ENV'
$ python -c "import os; os.environ.get('NODE_ENV')"
$

As requested, here’s the source code for score.py

from __future__ import print_function

from log import get_logger, setup_logging
setup_logging()
log = get_logger('score')

And here’s log.py

import json
import os
import sys

from iron_worker import IronWorker
from logbook import Logger, Processor, NestedSetup, StderrHandler, SyslogHandler

IRON_IO_TASK_ID = IronWorker.task_id()

def get_config():
  environment = os.environ.get('NODE_ENV')
  if environment == 'production':
    filename = '../config/config-production.json'
  elif environment == 'integration':
    filename = '../config/config-integration.json'
  else:
    filename = '../config/config-dev.json'

  with open(filename) as f:
    return json.load(f)

def setup_logging():
  # This defines a remote Syslog handler
  # This will include the TASK ID, if defined
  app_name = 'scoreworker'
  if IRON_IO_TASK_ID:
    app_name += '-' + IRON_IO_TASK_ID

  config = get_config()

  default_log_handler = NestedSetup([
    StderrHandler(),
    SyslogHandler(
      app_name,
      address = (config['host'], config['port']),
      level = 'ERROR',
      bubble = True
    )
  ])
  default_log_handler.push_application()

def get_logger(name):
  return Logger(name)
Asked By: Chris B.

||

Answers:

I’d recommend you start debugging os.py, for instance, on windows it’s being used this implementation:

def get(self, key, failobj=None):
    print self.data.__class__
    print key
    return self.data.get(key.upper(), failobj)

And if I test it with this:

import os


try:
    os.environ.get('NODE_ENV')
except Exception as e:
    print("-->{0}".format(e.__class__))

os.environ['NODE_ENV'] = "foobar"

try:
    os.environ.get('NODE_ENV')
except Exception as e:
    print("{0}".format(e.__class__))

The output will be:

<type 'dict'>
PYTHONUSERBASE
<type 'dict'>
APPDATA
<type 'dict'>
NODE_ENV
<type 'dict'>
NODE_ENV

So it makes sense the exception is not spawned reading dict.get docs.

In any case, if you don’t want to mess up or debugging the python modules, try cleaning up the *.pyc files, try to set up properly NODE_ENV. And if all that don’t work, restart your terminal to clear up.

Answered By: BPL

Try running:

find . -name *.pyc -delete

To delete your .pyc files.

Researching your problem I came across this question, where a user was experiencing the same thing: .get() seemingly raising a KeyError. In that case, it was caused, according to this accepted answer, by a .pyc file which contained code where a dict value was being accessed by key (i.e., mydict['potentially_nonexistent_key']), while the traceback was showing the code from the updated .py file where .get() was used. I have never heard of this happening, where the traceback references current code from a .py file, but shows an error raised by an outdated .pyc file, but it seems to have happened at least once in the history of Python…

It is a long shot, but worth a try I thought.

Answered By: elethan

Command for windows to delete the .pyc files:

del /S *.pyc
Answered By: Israel

I encountered a similar error when I set the environment variable without exporting it. So if you do this:

me@host:/# NODE_ENV=foo

You will get this:

me@host:/# python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> node_env = os.environ['NODE_ENV']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/os.py", line 675, in __getitem__
raise KeyError(key) from None
KeyError: 'NODE_ENV'
>>>

But if you do this:

me@host:/# NODE_ENV=foo
me@host:/# export NODE_ENV

It works:

me@host:/# python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> node_env = os.environ['NODE_ENV']
>>> print(node_env)
foo
>>>
Answered By: tomdaq

I had the same problem. I solved that by making some corrections on the .env file:

Before:

Key = Value

After my correction:

Key=Value 

without blank spaces and worked!

Answered By: Danilo Gazzoli

Use export a=10 instead of a=10 while setting env variable. Add the same in ~./bashrc to reload the env var wherever you login.

Doing this resolved the issue

Answered By: Sadhvik Chirunomula

I was getting this error while trying to source from a .env file.
I didn’t explicitly export the env vars so I had to change this.

ENVIRONMENT=DEV 

to this

export ENVIRONMENT=DEV 
Answered By: tlalco
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.