Build a Python exchange-rate alert with USD/IDR
Build a Python standard-library monitor that alerts once when USD/IDR crosses a percentage threshold, persists state safely, and respects rate freshness and API limits.
A useful alert compares each newly effective USD/IDR observation with the last one, not each HTTP poll with the last poll. The example suppresses the first observation, ignores stale data and errors, and prints a console alert when the move crosses the configured threshold.
sources["IDR"] and effective_at["IDR"] to judge the currency being monitored.Model the per-currency observation
The envelope source and data_updated_at fields summarize all requested currencies. An alert for IDR should use sources["IDR"] and effective_at["IDR"] instead, so another currency cannot make the monitored observation look fresher or older than it is.
Define a crossing policy
The first valid observation is only a baseline. When a new effective observation moves at least the threshold from the previous one, emit one alert and disarm. Do not emit another alert until a later valid observation returns below the threshold; then re-arm. This deduplicates repeated polls of the same crossing.
Persist state safely
Write a complete JSON object to a temporary file in the same directory, set its mode to 0600, then replace the state path with os.replace. A process interruption cannot leave a half-written baseline. Store the last rate, effective timestamp, source, market session, and whether the threshold is armed.
Bound the network and quota
Use a ten-second request timeout and never follow redirects while an Authorization header is present. Keep the key in EXCHANGERATE_API_KEY; it does not belong in a URL or log line. The script defaults to one request every five minutes (about 8,640 calls in 30 days). A 60-second interval stays under the 12 requests-per-minute burst limit but uses about 43,200 monthly calls, so it can exceed a shared monthly quota. On 429, wait for Retry-After when present and preserve the last state.
Run the complete monitor
Download the complete Python alert script, make it executable, and set the threshold, maximum age, and state path outside source control. The default freshness window is one hour; configure a longer FX_ALERT_MAX_AGE_SECONDS if a closed-market or daily-reference observation is intentional. It prints console notifications only; adding email, Slack, or another external destination requires a separate integration and secret policy.
Test the policy without waiting for the market
Unit-test the state transition with Decimal values: first observation, a move below threshold, a crossing, a repeated effective timestamp, a stale response, a return below threshold, and a second crossing. Mock the network boundary rather than fabricating market data in the script. KeyboardInterrupt stops the loop cleanly and does not delete the baseline.