Reputation: 8801
I'm trying to use .format() to concatenate some variables in a json string
subscription_info = '{"endpoint":"xxx","keys":{"p256dh":"xxx","auth":"xxx"}}'
send_data = '{"message":"message_test", "subscription_info": {$subscription_info} }'.format(subscription_info=subscription_info)
But I'm getting
KeyError: '"message"'
How can I fix this?
Upvotes: 0
Views: 403
Reputation: 56547
You are breaking format rules. Normally when you use format Python looks for the following
"{" [field_name] ["!" conversion] [":" format_spec] "}"
So in your case "message"
becomes a field_name, since {
is before it and :
after it. This obviously doesn't work. The .format()
method is not meant to be used with complex, nested text structures.
One way is to use string.Template
together with .substitute
instead:
>>> tmpl = string.Template('{"message":"message_test", "subscription_info": {$subscription_info} }')
>>> tmpl.substitute(subscription_info=subscription_info)
'{"message":"message_test", "subscription_info": {{"endpoint":"xxx","keys":{"p256dh":"xxx","auth":"xxx"}}} }'
However it also isn't meant to be used with nested text structures.
Since you are using JSON then perhaps you should parse and serialize the JSON instead. This is the proper way to handle the problem:
>>> import json
>>> subscription_info = {"endpoint":"xxx","keys":{"p256dh":"xxx","auth":"xxx"}}
>>> send_data = {"message":"message_test", "subscription_info": subscription_info }
>>> json.dumps(send_data)
'{"subscription_info": {"endpoint": "xxx", "keys": {"auth": "xxx", "p256dh": "xxx"}}, "message": "message_test"}'
It is the cleanest and safest method.
Upvotes: 1
Reputation: 78564
Double up the outer curly braces to avoid interpreting message
as a format field:
send_data = '{{"message":"message_test", "subscription_info": {subscription_info} }}'.format(subscription_info=subscription_info)
print(send_data)
# {"message":"message_test", "subscription_info": {"endpoint":"xxx","keys":{"p256dh":"xxx","auth":"xxx"}} }
And you don't need the $
in your format string; a valid python indentifier is required if you must use a named field.
Upvotes: 1