0

I am making an api call and in doing so I have to manually change the endDate in the payload every day. I can not use .format() inside a dictionary. Can anyone help out?

Current payload: where I am changing the endDate manually

payload = "{\"dimensions\":[\"AdsetId\",\"Adset\",\"CampaignId\",\"Campaign\",\"Device\",\"Day\",\"Month\",\"Year\",\"Week\",\"Os\"],\"metrics\":[\"AdvertiserCost\",\"Displays\",\"ClickThroughRate\",\"Cpc\",\"AppInstalls\",\"Clicks\"],\"timezone\":\"UTC\",\"advertiserIds\":\"69957\",\"currency\":\"USD\",\"startDate\":\"2022-01-01T00:00:00.0000000+00:00\",\"***endDate\":\"2022-01-13***T00:00:00.0000000+00:00\",\"format\":\"csv\"}"

Expected payload:

payload = "{\"dimensions\":[\"AdsetId\",\"Adset\",\"CampaignId\",\"Campaign\",\"Device\",\"Day\",\"Month\",\"Year\",\"Week\",\"Os\"],\"metrics\":[\"AdvertiserCost\",\"Displays\",\"ClickThroughRate\",\"Cpc\",\"AppInstalls\",\"Clicks\"],\"timezone\":\"UTC\",\"advertiserIds\":\"69957\",\"currency\":\"USD\",\"startDate\":\"2022-01-01T00:00:00.0000000+00:00\",\endDate\":\"{}T00:00:00.0000000+00:00\",\"format\":\"csv\"}".format(today)

Here today will be a variable with today’s date

martineau
  • 119,623
  • 25
  • 170
  • 301
Aakash
  • 35
  • 7
  • Are the `***` really present in the payload? – Serge Ballesta Jan 13 '22 at 16:10
  • No..Let me edit it – Aakash Jan 13 '22 at 16:10
  • 3
    Can you post a smaller example? We don't need every parameter to see the problem. That's a string, not a dictionary, and format works with it just fine. Is that intended to be JSON? You could write a python dict, add the date you want and serialize with the `json` module. – tdelaney Jan 13 '22 at 16:10
  • 5
    While it's possible, the correct answer will be to not use formatting there at all. It's JSON formatted string, so serialize it using [`json.loads(payload)`](https://docs.python.org/3/library/json.html#json.loads), make all necessary modifications and turn modified dictionary back into a string using [`json.dumps(dictionary, separators=(',', ':'))`](https://docs.python.org/3/library/json.html#json.dumps) *(`separators` argument required to get JSON string without extra spaces)*. – Olvin Roght Jan 13 '22 at 16:11
  • Does this answer your question? [How to use str.format inside a string of json format?](https://stackoverflow.com/questions/39948645/how-to-use-str-format-inside-a-string-of-json-format) – Olvin Roght Jan 13 '22 at 16:23
  • That was helpful. Thanks @OlvinRoght – Aakash Jan 13 '22 at 16:46

3 Answers3

2

That's a string, not a dictionary and the .format thing that you want, works. Guessing that this is in fact JSON data, the normal way to do this sort of thing is to build a python dict and serialize it later. Using a python "f-string" makes it simple to call a function in the string format specification itself. datetime.datetime.utcnow() gives the current UTC time. It can be converted to a date and its isoformat method writes the format you want. So,

import datetime as dt
import json

data = {
    "dimensions": ["AdsetId", "Adset", "CampaignId", "Campaign",
        "Device", "Day", "Month", "Year", "Week", "Os"],
    "metrics": ["AdvertiserCost", "Displays", "ClickThroughRate", 
        "Cpc", "AppInstalls", "Clicks"],
    "timezone": "UTC", 
    "advertiserIds": "69957", 
    "currency": "USD", 
    "startDate": "2022-01-01T00:00:00.0000000+00:00", 
    "endDate": f"{dt.datetime.utcnow().date().isoformat()}T00:00:00.0000000+00:00", 
    "format": "csv"}
    
    
payload = json.dumps(data)
print(payload)
tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • This solves the issue! Thanks! @tdelaney – Aakash Jan 13 '22 at 16:45
  • @tdelaney, by the way, you don't need to call [`.isoformat()`](https://docs.python.org/3/library/datetime.html#datetime.date.isoformat) explicitely *(just omit it)*. Quote from [`date.__str__`](https://docs.python.org/3/library/datetime.html#datetime.date.__str__) docs: *"For a date **d**, `str(d)` is equivalent to `d.isoformat()`".* – Olvin Roght Jan 13 '22 at 17:46
1

In my opinion, a very straightforward way to do this would be along the lines of what @Olvin Roght suggested in a comment, which was essentially this:

  1. Convert payload into a dictionary using json.loads().
  2. Modify the "endDate" in the dictionary.
  3. Convert the dictionary back into a string.

Which doesn't involve .format() at all.

from datetime import datetime, timezone
import json

payload = "{\"dimensions\":[\"AdsetId\",\"Adset\",\"CampaignId\",\"Campaign\",\"Device\",\"Day\",\"Month\",\"Year\",\"Week\",\"Os\"],\"metrics\":[\"AdvertiserCost\",\"Displays\",\"ClickThroughRate\",\"Cpc\",\"AppInstalls\",\"Clicks\"],\"timezone\":\"UTC\",\"advertiserIds\":\"69957\",\"currency\":\"USD\",\"startDate\":\"2022-01-01T00:00:00.0000000+00:00\",\"endDate\":\"2022-01-13T00:00:00.0000000+00:00\",\"format\":\"csv\"}"
payload = json.loads(payload)
dt = datetime.now(timezone.utc).replace(minute=0, hour=0, second=0, microsecond=0)
payload["endDate"] = dt.isoformat(timespec="microseconds")
print(json.dumps(payload, indent=4))

Output:

{
    "dimensions": [
        "AdsetId",
        "Adset",
        "CampaignId",
        "Campaign",
        "Device",
        "Day",
        "Month",
        "Year",
        "Week",
        "Os"
    ],
    "metrics": [
        "AdvertiserCost",
        "Displays",
        "ClickThroughRate",
        "Cpc",
        "AppInstalls",
        "Clicks"
    ],
    "timezone": "UTC",
    "advertiserIds": "69957",
    "currency": "USD",
    "startDate": "2022-01-01T00:00:00.0000000+00:00",
    "endDate": "2022-01-13T00:00:00.000000+00:00",
    "format": "csv"
}
martineau
  • 119,623
  • 25
  • 170
  • 301
  • @Olvin: This code definitely produced the output shown without errors — and the current [accepted answer](https://stackoverflow.com/a/70699866/355230) doesn't do what the OP asked about, irrespective of whether the code in it will run or not. – martineau Jan 13 '22 at 17:38
0

if your payload is a string and u just want to be able to format it with a specific variable, u can use f-strings, for example:

today = datetime.strftime(datetime.now(), "%Y-%m-%d")

payload = f"{\"dimensions\":[\"AdsetId\",\"Adset\",\"CampaignId\",\"Campaign\",\"Device\",\"Day\",\"Month\",\"Year\",\"Week\",\"Os\"],\"metrics\":[\"AdvertiserCost\",\"Displays\",\"ClickThroughRate\",\"Cpc\",\"AppInstalls\",\"Clicks\"],\"timezone\":\"UTC\",\"advertiserIds\":\"69957\",\"currency\":\"USD\",\"startDate\":\"2022-01-01T00:00:00.0000000+00:00\",\endDate\":\"{today}T00:00:00.0000000+00:00\",\"format\":\"csv\"}"
gil
  • 2,388
  • 1
  • 21
  • 29