I am writing some code for technical users to pass in JSON with placeholders for variables, accompanied by a dict to define each of those variables. I want to replace those variables with the values and ultimately need to get it into a Python dict. Imagine I start with this:
>>> json_in = """
{
"sidebar": {
"type": "sidebar",
"title": "<h1>Vulnerability Data</h1>",
"description": {md_html}
},
"widgets": [
{
"name": "Map",
"itemId": {item_id},
"showNavigation": false
}
]
}"""
>>> args = {'md_html': '<super_long_html_string>', 'item_id': 'abcdef12345'}
If I try to do a format like json_in.format(**args)
, I just get a KeyError when it hits the first opening curly brace (before "sidebar"), which format tries to read. Doubling the curly braces escapes them in format()
, but this JSON can be thousands of lines long, so it's really not something I want to make people do a ton of reformatting on. I guess I can try to edit the JSON with Python before the format()
. I'd have to avoid mangling the curly braces from the formatting strings, so this seems like it's getting needlessly complex. Python usually has simple solutions, so what am I missing?
Another path I went down is just to create it as a Python dict in the first place. It's easy to search for JSONisms and replace with the Python equivalents (e.g.: false
to False
, true
to True
). Instead of formatting strings ({item_id}
), I just use variables (item_id
) to end up with something like this:
>>> md_html = '<super_long_html_string>'
>>> item_id = 'abcdef12345'
>>> dict_in = {
"sidebar": {
"type": "sidebar",
"title": "<h1>Vulnerability Data</h1>",
"description": md_html
},
"widgets": [
{
"name": "Map",
"itemId": item_id,
"showNavigation": False
}
]
}
The problem is that the variables md_html
and item_id
are hard-coded in this example, and I want to accept whatever the user passes in (see the args
dict above). If I could create a dict with placeholders and replace them with inputs supplied, that would solve my problem.
CodePudding user response:
I would use the jq
library to define such a JSON template.
import jq
json_in = """
{
"sidebar": {
"type": "sidebar",
"title": "<h1>Vulnerability Data</h1>",
"description": $md_html
},
"widgets": [
{
"name": "Map",
"itemId": $item_id,
"showNavigation": false
}
]
}"""
args = {'md_html': '<super_long_html_string>', 'item_id': 'abcdef12345'}
result = jq.compile(json_in, args=args).input("")
CodePudding user response:
Check out Template Strings if you have control over json_in
.
from string import Template
json_in = """
{
"sidebar": {
"type": "sidebar",
"title": "<h1>Vulnerability Data</h1>",
"description": $md_html
},
"widgets": [
{
"name": "Map",
"itemId": $item_id,
"showNavigation": false
}
]
}"""
args = {'md_html': '<super_long_html_string>', 'item_id': 'abcdef12345'}
Template(json_in).substitute(args)
Output
{
"sidebar": {
"type": "sidebar",
"title": "<h1>Vulnerability Data</h1>",
"description": <super_long_html_string>
},
"widgets": [
{
"name": "Map",
"itemId": abcdef12345,
"showNavigation": false
}
]
}
I suppose you'll want quotes around the strings, I just left the json as close to your question as possible.