More details on our Python examples can be found in our GitHub repository.

You will need to download the simple goal seek example from us, upload it to your GRID account and replace REPLACE_WITH_YOUR_SPREADSHEET_ID with its workbook id. See our quick start guide for more details.

# /// script
# requires-python = ">=3.9"
# dependencies = [
#     "fastapi[standard]",
#     "grid-api",
#     "uvicorn",
# ]
# ///
import uvicorn

from fastapi import FastAPI
from grid_api import AsyncGrid, APIConnectionError, APIStatusError, RateLimitError

app = FastAPI()

@app.get("/seek_interests")
async def seek_interests(target_amount: float):
    client = AsyncGrid()

    try:
        response = await client.workbooks.query(
            id="REPLACE_WITH_YOUR_SPREADSHEET_ID",
            goal_seek={
                "targetCell": "Sheet1!C7",
                "targetValue": target_amount,
                "controlCell": "Sheet1!C5",
            },
            read=[]
        )
    except APIConnectionError as e:
        return {"error": "The server could not be reached."}
    except RateLimitError as e:
        return {"error": "A 429 status code was received; we should back off a bit."}
    except APIStatusError as e:
        return {"error": e.message}

    solution = response.goalSeek["solution"]

    return {"interest_rate": solution}


@app.get("/seek_years")
async def seek_years(target_amount: float):
    client = AsyncGrid()

    try:
        response = await client.workbooks.query(
            id="REPLACE_WITH_YOUR_SPREADSHEET_ID",
            goal_seek={
                "targetCell": "Sheet1!C7",
                "targetValue": target_amount,
                "controlCell": "Sheet1!C4",
            },
            read=[]
        )
    except APIConnectionError as e:
        return {"error": "The server could not be reached."}
    except RateLimitError as e:
        return {"error": "A 429 status code was received; we should back off a bit."}
    except APIStatusError as e:
        return {"error": e.message}

    solution = response.goalSeek["solution"]

    return {"years": solution}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

Make sure your API key is set in the environment variable GRID_API_TOKEN, or passed as an argument to the Grid class.

client = Grid(api_key="REPLACE_WITH_YOUR_API_KEY")

To start the goal seek server, run the following:

uv run goal_seek.py

Open the URL below to see how high the interest rate would need to be to reach $150,000:

http://localhost:8000/seek_interests?target_amount=150000

You should get a response like:

{"interest_rate":0.08713616268663185}

To see how many years it would take to save up $200,000:

http://localhost:8000/seek_years?target_amount=200000

You should get a response like:

{"years":12.93949339333381}