-1

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'}"
    }]
}
ankur jain
  • 89
  • 1
  • 1
  • 3
  • 1
    Why use Jinja templates to create JSON!? Just create a Python dict/list and put it through `json.dumps`. That’ll ensure the correct encoding of everything. In fact, since you’re `json.loads` the result anyway… what’s the point!? – deceze Aug 09 '23 at 16:09
  • This is just a small snippet. The actual template is a huge file. – ankur jain Aug 09 '23 at 16:10
  • That still doesn’t justify this apparent nonsense. – deceze Aug 09 '23 at 16:11
  • JSON decoder doesn't care about single quotes inside a string. Which line does the decode error come from? `return json.loads(output)` I think? It would fail if you have inserted a _double-quote_ into the rendered template via substitution of `{{DATA.address}}` – Anentropic Aug 09 '23 at 16:19
  • @Anentropic Yes, my input JSON was different. I modified it to match what I have now and the error is reproducible. Thanks – ankur jain Aug 09 '23 at 16:45
  • 1
    Part of the problem is you are inserting a dictionary as the value of `{{DATA.address}}`, Python converts that to a string for you, but that string is not JSON. Randomly removing single quotes from that string will get rid of the errors, but you will have further problems later. You need to try to understand what is actually happening. – Anentropic Aug 09 '23 at 17:44

1 Answers1

1

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.

deceze
  • 510,633
  • 85
  • 743
  • 889