1

I'm calling an API that will require dynamic variables as parameters. However, I do not know how to format the string to include variables when it is surrounded by triple quotes and a backslash escape character at the beginning of the string literal.

I've tried varying the amount of quotes and using the ".format()" function.

Here is code formatted in a way that gets a successful result:

payload = "{\n\t\"firm\": \"myfirm\",\n\t\"id\": \"f87987562\",\n\t\"data\": {\n\t\t\"tracking_preference\": 2\n\t} \n}\n"

Here is my attempt at trying to format the string in a cleaner way while also including variables:

payload = \
    """{
    "firm": {0},
    "id": {1},
    "data": {
        "tracking_preference": {2}
    } 
}
""".format('myfirm', "f87987562", 2)

This is the error that I am receiving:

     19     } 
     20 }
---> 21 """.format('myfirm', "f87987562", 2)
     22 
     23 apikey = "secret_key"

KeyError: '\n    "firm"'

I suspect it has something to do with the backslash, but its implementation seems necessary. Any help and insight on the intuition behind this string formatting is greatly appreciated.

I am trying to pass the string literal into the request function:

response = requests.request("POST", url, data=payload, headers=headers)
  • 1
    Possible duplicate of [How can I print literal curly-brace characters in python string and also use .format on it?](https://stackoverflow.com/questions/5466451/how-can-i-print-literal-curly-brace-characters-in-python-string-and-also-use-fo). Try `payload = \ """{{ "firm": {0}, "id": {1}, "data": {{ "tracking_preference": {2} }} }} """.format('myfirm', "f87987562", 2)` – Ruzihm Oct 23 '19 at 20:06
  • The problem isn't the backslash, the problem is that `format` is looking at everything inside of curly brackets, which is everything in your string. Why not use a normal `dict` and convert it later? – Ofer Sadan Oct 23 '19 at 20:06

2 Answers2

3

In a format string, { and } are special. To embed a literal parenthesis, use {{ or }}.

payload = """{{
    "firm": "{0}",
    "id": "{1}",
    "data": {{
        "tracking_preference": {2}
    }}
}}
""".format('myfirm', "f87987562", 2)

print(payload)

Output:

{
    "firm": "myfirm",
    "id": "f87987562",
    "data": {
        "tracking_preference": 2
    }
}

In Python 3.6+, f-strings can make this simpler:

firm = 'myfirm'
id = 'f87987562'
tracking = 2

payload = f'''{{
    "firm": "{firm}",
    "id": "{id}",
    "data": {{
        "tracking_preference": {tracking}
    }}
}}'''

Finally, the json module is ideal for this specific scenario:

import json

firm = 'myfirm'
id = 'f87987562'
tracking = 2

data = {'firm':firm,'id':id,'data':{'tracking_preference':tracking}}
payload = json.dumps(data,indent=2) # indent is optional for easy reading
print(payload)

Output:

{
  "firm": "myfirm",
  "id": "f87987562",
  "data": {
    "tracking_preference": 2
  }
}
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
0

If you're using python 3.6+, you could use an f-string:

payload = \
    f"""{
    "firm": {"myfirm"},
    "id": {"f87987562"},
    "data": {
        "tracking_preference": {2}
    } 
}
"""

If not, you might be better off with a string template:

from string import Template

payload_t = Template(
    """{
    "firm": ${firm},
    "id": ${id},
    "data": {
        "tracking_preference": ${tracking}
    } 
}
""")

payload = payload_t.substitute(firm="myfirm", id="f87987562", tracking=2)
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241