2

I have 2 scripts a.py and b.py.

I have an ansible playbook which runs a.py and b.py. Here is the script Output of a.py is given to b.py. The problem is the Ouput of a.py is a list which can be indexed but whenever I pass the yaml's stdout to b.py as command line argument it takes as str object and it can be indexed as before i.e like a.py's.

script a.py

a = [{
        "name": "jack",
        "date": "Jan-06-2021",
        "age": "24",
    },
    {
        "name": "jack1",
        "date": "Jan-07-2021",
        "age": "25",
    },
]
print(a)

b.py script

import sys
import json
random_variable = sys.argv[1] 
print(json.loads(random_variable)) # tried this no use

I want to parse the values of a just like random_variab.e[0] and random_variable[1].
random_variable[0] could be like:

{'name': 'jack', 'date': 'Jan-06-2021', 'age': '24'}
- name: testing
  gather_facts: True
  hosts: localhost
  tasks:

    - name: run python script
      command: python3 /test-repo/test_python/a.py
      register: result
    - set_fact:
        var1: "{{result.stdout}}"
    - debug: 
        msg: "{{var1}}"
    
    - name: run python script2
      command: python3 /test-repo/test_python/b.py {{var1}}
      register: result
    - debug: 
        msg: "{{result}}"

Error I am getting now

["Traceback (most recent call last):", "  File \"/test-repo/test_python/b.py\", line 4, in <module>", "    print(json.loads(a))", "  File \"/usr/lib64/python3.6/json/__init__.py\", line 354, in loads", "    return _default_decoder.decode(s)", " 
 File \"/usr/lib64/python3.6/json/decoder.py\", line 339, in decode", "    obj, end = self.raw_decode(s, idx=_w(s, 0).end())", "  File 
\"/usr/lib64/python3.6/json/decoder.py\", line 355, in raw_decode", "    obj, end = self.scan_once(s, idx)", "json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 3 (char 2)"]

Expected output when I print

random_variable = sys.argv[1]
print(random_variable[0])

Output I need

{'name': 'jack', 'date': 'Jan-06-2021', 'age': '24'}
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83

1 Answers1

1

Your issue is not coming from b.py, like you seem to think it is.

It is actually coming from the fact that a.py is not printing a JSON, but a python dictionary, and so, you cannot load it back in b.py as a JSON.

Debugging the result of a.py in the playbook will give you:

[{'name': 'jack', 'date': 'Jan-06-2021', 'age': '24'}, {'name': 'jack1', 'date': 'Jan-07-2021', 'age': '25'}]

But this is not a valid JSON array because, as the error message prompts it to you, string and properties, in JSON, have to be enclosed in double quotes not simple ones.

So there is at least two things you should do:

  1. Adapt a.py and make it read
    import json
    a = [{
            "name": "jack",
            "date": "Jan-06-2021",
            "age": "24",
        },
        {
            "name": "jack1",
            "date": "Jan-07-2021",
            "age": "25",
        },
    ]
    print(json.dumps(a))
    
  2. Adapt your playbook and enclose your JSON string in simple quotes, to not break the shell:
    - command: python3 /test-repo/test_python/b.py '{{ var1 }}'
    

This said, I would also make this adaptation: using the proper shebang in your Python scripts, so you don't have to specify the interpreter on the command task anymore.

So a.py become:

#!/usr/bin/env python3
import json
a = [{
        "name": "jack",
        "date": "Jan-06-2021",
        "age": "24",
    },
    {
        "name": "jack1",
        "date": "Jan-07-2021",
        "age": "25",
    },
]
print(json.dumps(a))

b.py become:

#!/usr/bin/env python3
import sys
import json
print(json.loads(sys.argv[1])[0])

Your playbook becomes:

- hosts: all
  gather_facts: yes

  tasks:
    - command: /test-repo/test_python/a.py
      register: result

    - debug: 
        var: result.stdout
    
    - command: /test-repo/test_python/b.py '{{ result.stdout }}'
      register: result

    - debug: 
        var: result.stdout

And all this yields the recap:

PLAY [all] **********************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [localhost]

TASK [command] ******************************************************************************************************
changed: [localhost]

TASK [debug] ********************************************************************************************************
ok: [localhost] => {
    "result.stdout": [
        {
            "age": "24",
            "date": "Jan-06-2021",
            "name": "jack"
        },
        {
            "age": "25",
            "date": "Jan-07-2021",
            "name": "jack1"
        }
    ]
}

TASK [command] ******************************************************************************************************
changed: [localhost]

TASK [debug] ********************************************************************************************************
ok: [localhost] => {
    "result.stdout": {
        "age": "24",
        "date": "Jan-06-2021",
        "name": "jack"
    }
}

PLAY RECAP **********************************************************************************************************
localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
  • yeah you are correct, but I have function generation that kind of list, whereas here the list i am passing in a.py takes a string but my the function that generating this kind of list is not passing through json.dump(variable_having_list). ``` ``` –  Feb 27 '21 at 23:12
  • File \"/usr/lib64/python3.6/json/decoder.py\", line 339, in decode", " obj, end = self.raw_decode(s, idx=_w(s, 0).end())", " File \"/usr/lib64/python3.6/json/decoder.py\", line 357, in raw_decode", " raise JSONDecodeError(\"Expecting value\", s, err.value) from None", "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)"], "stdout": "", "stdout_lines": []} ``` ****I am getting the following error**** –  Feb 27 '21 at 23:17
  • `json.dumps`! Mind the **s**, `json.dump` is not the same function. – β.εηοιτ.βε Feb 27 '21 at 23:22