6

I'm trying to read a dictionary in my python script from an environment variable.

This is the code of my python script:

  desired_cap_default = [
        {'platform': 'Windows 7', 'browserName': 'firefox', 'version': '24.0'},
        {'platform': 'OS X 10.10', 'browserName': 'chrome', 'version': '45.0'},
        {'platform': 'Windows XP', 'browserName': 'chrome', 'version': '40.0'},
        {'platform': 'OS X 10.10', 'browserName': 'safari', 'version': '8.0'},
        # {'platform': 'Windows XP', 'browserName': 'firefox', 'version': '10.0', 'screenResolution': '1600x1200',
        # 'videoUploadOnPass': False, 'commandTimeout': 120}
    ]

browser = os.getenv('TESTING_BROWSERS', desired_cap_default)

And this is how I'm specifying the environment variable (but is not recognising it as a dictionary)

TESTING_BROWSERS="[{'platform': 'Windows 7', 'browserName': 'firefox', 'version': '24.0'}, \
    {'platform': 'OS X 10.10', 'browserName': 'chrome', 'version': '45.0'}, \
    {'platform': 'Windows XP', 'browserName': 'chrome', 'version': '40.0'}, \
    {'platform': 'OS X 10.10', 'browserName': 'safari', 'version': '8.0'},  ]"

Can anyone help me figuring out what am I missing? Thanks in advance guys

idjaw
  • 25,487
  • 7
  • 64
  • 83
Gino G
  • 83
  • 1
  • 7
  • 1
    The backslashes in `TESTING_BROWSERS` are unnecessary; newlines are embedded in quoted strings without them. – chepner Oct 20 '15 at 18:44

3 Answers3

6

You can you use the ast module for this.

TESTING_BROWSERS = "[{'platform': 'Windows 7', 'browserName': 'firefox', 'version': '24.0'}, \
{'platform': 'OS X 10.10', 'browserName': 'chrome', 'version': '45.0'}, \
{'platform': 'Windows XP', 'browserName': 'chrome', 'version': '40.0'}, \
{'platform': 'OS X 10.10', 'browserName': 'safari', 'version': '8.0'},  ]"

import ast
my_dict = ast.literal_eval(TESTING_BROWSERS)
Wondercricket
  • 7,651
  • 2
  • 39
  • 58
  • 1
    Simple, useful and to the point. It worked perfectly, thanks. My only concern is... :( would be awesome if you just told me the problem was that's being treated as a string instead of dict! Thank you a lot! – Gino G Oct 21 '15 at 08:12
4

Your json object here is being represented as a string. You need to now use the json module to make it a proper Python dictionary.

You also have an error in your json with that trailing comma you have at the end.

Furthermore, is that in order to use the json module for this, you should be using double quotes and then enclose by single quotes.

I also don't see the "\" as necessary if you are setting them in to an environment variable. However, if they are there, they will also be in your string as this:

\\\n

The json module will have a hard time with that. What you can do in that case is if you really want those slashes in there, make sure you remove them before performing your json.loads command using the replace method on the string. So, you can in fact, do this:

browser = json.loads(os.getenv('TESTING_BROWSERS', v).replace("\\\n", ""))

Below are two examples. One with the modifications I made to the json removing the slashes, and another without removing:

import json
a = '[{"platform": "Windows 7", "browserName": "firefox", "version": "24.0"}, {"platform": "OS X 10.10", "browserName": "chrome", "version": "45.0"}, {"platform": "Windows XP", "browserName": "chrome", "version": "40.0"}, {"platform": "OS X 10.10", "browserName": "safari", "version": "8.0"}]'
print(json.loads(a))

Output:

[{u'platform': u'Windows 7', u'browserName': u'firefox', u'version': u'24.0'}, {u'platform': u'OS X 10.10', u'browserName': u'chrome', u'version': u'45.0'}, {u'platform': u'Windows XP', u'browserName': u'chrome', u'version': u'40.0'}, {u'platform': u'OS X 10.10', u'browserName': u'safari', u'version': u'8.0'}]

Now, with the slashes in place.

Remember, you have to at least fix your quotes and remove that comma first, as I mentioned.

>>> import json
>>> browser = json.loads(os.getenv('TESTING_BROWSERS', v).replace("\\\n", ""))
>>> print(browser)
[{u'platform': u'Windows 7', u'browserName': u'firefox', u'version': u'24.0'}, {u'platform': u'OS X 10.10', u'browserName': u'chrome', u'version': u'45.0'}, {u'platform': u'Windows XP', u'browserName': u'chrome', u'version': u'40.0'}, {u'platform': u'OS X 10.10', u'browserName': u'safari', u'version': u'8.0'}]

Here is information on the json module:

Python 2

https://docs.python.org/2/library/json.html

Python 3

https://docs.python.org/3/library/json.html

idjaw
  • 25,487
  • 7
  • 64
  • 83
  • 1
    Rather, the JSON object *is* a string; you need to use `json.loads` to turn that string into a proper Python `dict`. – chepner Oct 20 '15 at 18:31
  • Thanks @chepner . I corrected my wording and fixed a few other references that were misleading. Cheers. If you happen to take another look, let me know if you see anything else off. – idjaw Oct 20 '15 at 18:34
  • Thanks for the extensive answer and explanation! I'll try it right now! – Gino G Oct 21 '15 at 08:01
1

It is being recognised as a string. You need to evaluate it as python code in order to create a dictionary from it.

import ast
brower_dict = ast.literal_eval(brower)

ast.literal_eval is more limited than built-in eval, but it is safe to use from untrusted sources, as it cannot execute arbitrary code.

Alvaro Gutierrez Perez
  • 3,669
  • 1
  • 16
  • 24