How to assign a variable string with single quotes to Jinja2

239 views Asked by At

I receive a json payload like below:

{
    "address": {
            "summary": "my home's address"
        }
}

I have a JSON with jinja template:

{
    "parent_elem": [{
        "address": "{{DATA.address}}"
    }]
}

Then, I try to copy the value from payload's address to template json via jinja.

    with open('payload.json') as payload_file:
        data = json.load(payload_file)
        
        # Load the Jinja2 environment
        env = Environment(loader=FileSystemLoader('.'))
        template = env.get_template('jinja_template.json')
       
        # Render the template with the variables
        output = template.render(
           DATA = data
        )
        return json.loads(output)

However, the code breaks on single quotes (home's keyword) and I end up getting this error: json.decoder.JSONDecodeError: Expecting ',' delimiter:

How do I escape this single quote and get a perfect json from the template?

This is the json I receive from jinja: Clearly this is not a valid JSON

{
    "parent_elem": [{
        "address": "{'summary': "my home's address"}"
    }]
}

If I remove the single quote from "home's" keyword in input json, this is what I get at output (which is a valid json)

{
    "parent_elem": [{
        "address": "{'summary': 'my homes address'}"
    }]
}
1

There are 1 answers

0
deceze On

What you're doing is:

  1. Load JSON data into a Python dict.
  2. Put the data of this dict into a template which is supposed to produce valid JSON data.
  3. Load that JSON data into a Python dict.

You turn JSON into a dict into JSON into a dict. That's just fundamentally madness. Your concrete problem is that you're doing the second step badly: when manually cobbling together a text format, you need to ensure you correctly encode each value according to the text format, to be sure you produce syntactically correct data. There are solutions to this problem, but again, since your entire approach is nonsensical, we'll skip right to the sane solution:

with open('payload.json') as payload_file:
    data = json.load(payload_file)
    
return {
    "parent_elem": [{
        "address": data['address']
    }]
}

This produces the same result as your JSON-dict-JSON-dict process, just more directly and without formatting issues. You'll notice that you can pretty much copy-paste your JSON template into Python code with just minimal changes.