Skip to content

Instantly share code, notes, and snippets.

@xuru
Last active August 3, 2023 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xuru/154e913d8b7fdf07507072e45cea667e to your computer and use it in GitHub Desktop.
Save xuru/154e913d8b7fdf07507072e45cea667e to your computer and use it in GitHub Desktop.
before = {
"id": "sub_sched_KppC1fgG2c95PyN47xCK2Fdv",
"object": "subscription_schedule",
"application": None,
"canceled_at": None,
"completed_at": None,
"created": 1690985828.495943,
"current_phase": None,
"customer": "cust_D2las0ShUdDNJh5GeudIakfm",
"default_settings": {
"application_fee_percent": None,
"automatic_tax": {"enabled": False},
"billing_cycle_anchor": "automatic",
"billing_thresholds": None,
"collection_method": "charge_automatically",
"default_payment_method": None,
"description": None,
"invoice_settings": None,
"on_behalf_of": None,
"transfer_data": None,
},
"end_behavior": "release",
"livemode": False,
"metadata": {},
"phases": [
{
"add_invoice_items": [],
"application_fee_percent": None,
"billing_cycle_anchor": None,
"billing_thresholds": None,
"collection_method": None,
"coupon": None,
"currency": "usd",
"default_payment_method": None,
"default_tax_rates": [],
"description": None,
"end_date": 1722626228.495858,
"invoice_settings": None,
"items": [
{
"billing_thresholds": None,
"metadata": {},
"price": "price_1M3OSoIxQImiSx1FgPckhikZ",
"quantity": 1,
"tax_rates": [],
}
],
"metadata": {},
"on_behalf_of": None,
"proration_behavior": "create_prorations",
"start_date": 1691003828.495858,
"transfer_data": None,
"trial_end": None,
}
],
"released_at": None,
"released_subscription": None,
"status": "active",
"subscription": "sub_DRctGmkR4CJIyE8G7rSX8tQR",
"test_clock": None,
}
after = {
"id": "sub_sched_KppC1fgG2c95PyN47xCK2Fdv",
"object": "subscription_schedule",
"application": None,
"canceled_at": None,
"completed_at": None,
"created": 1690985828.495943,
"current_phase": None,
"customer": "cust_D2las0ShUdDNJh5GeudIakfm",
"default_settings": {
"application_fee_percent": None,
"automatic_tax": {"enabled": False},
"billing_cycle_anchor": "automatic",
"billing_thresholds": None,
"collection_method": "charge_automatically",
"default_payment_method": None,
"description": None,
"invoice_settings": None,
"on_behalf_of": None,
"transfer_data": None,
},
"end_behavior": "release",
"livemode": False,
"metadata": {},
"phases": [
{
"add_invoice_items": [],
"application_fee_percent": None,
"billing_cycle_anchor": None,
"billing_thresholds": None,
"collection_method": None,
"coupon": None,
"currency": "usd",
"default_payment_method": None,
"default_tax_rates": [],
"description": None,
"end_date": 1722626228.495858,
"invoice_settings": None,
"items": [
{
"billing_thresholds": None,
"metadata": {},
"price": "price_1M3OSoIxQImiSx1FgPckhikZ",
"quantity": 1,
"tax_rates": [],
}
],
"metadata": {},
"on_behalf_of": None,
"proration_behavior": "create_prorations",
"start_date": 1691003828.495858,
"transfer_data": None,
"trial_end": None,
}
],
"released_at": None,
"released_subscription": None,
"status": "active",
"subscription": "sub_DRctGmkR4CJIyE8G7rSX8tQR",
"test_clock": None,
}
params = {
"phases[0]": {"end_date": "1693253412", "start_date": "1690575012"},
"phases[0][items][0]": {"price": "price_1M3OSoIxQImiSx1FgPckhikZ"},
"phases[1]": {"start_date": "1693253412"},
"phases[1][items][0]": {"price": "price_1M3OSoIxQImiSx1FgPckhikZ"},
}
def recursive_update_dict(data: dict, data_to_update: dict):
for k, v in data_to_update.items():
if "[" in k:
d = data
for part in [x if not x.isnumeric() else int(x) for x in k.replace(']', '').split('[')]:
d = d[part]
d.update(**v)
elif "__" in k:
name, sub = k.split("__", maxsplit=1)
recursive_update_dict(data[name], {sub: v})
else:
data[k] = v
recursive_update_dict(d, params)
@estabroo
Copy link

estabroo commented Aug 2, 2023

def recursive_update_dict(data: dict, data_to_update: dict):
    for k, v in data_to_update.items():
        if "[" in k:
            d = data
            try:
                for part in [x if not x.isnumeric() else int(x) for x in k.replace(']', '').split('[')]:
                    d = d[part]
            except (IndexError, KeyError):  # trying to update something that doesn't exist
                continue
            d.update(**v)

        elif "__" in k:
            name, sub = k.split("__", maxsplit=1)
            recursive_update_dict(data[name], {sub: v})
        else:
            data[k] = v

@estabroo
Copy link

estabroo commented Aug 2, 2023

if you want to include the missing parts instead of skipping

def recursive_update_dict(data: dict, data_to_update: dict):
    for k, v in data_to_update.items():
        if "[" in k:
            d = data
            for part in [x if not x.isnumeric() else int(x) for x in k.replace(']', '').split('[')]:
                try:
                    d = d[part]
                except IndexError:
                    d.append({})
                    d = d[part]
                except KeyError:
                    d[part] = []
                    d = d[part]
            d.update(**v)

        elif "__" in k:
            name, sub = k.split("__", maxsplit=1)
            recursive_update_dict(data[name], {sub: v})
        else:
            data[k] = v

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment