ntdservices commited on
Commit
2c1c4d5
Β·
verified Β·
1 Parent(s): f9eb3ae

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -58
app.py CHANGED
@@ -1,90 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from flask import Flask, jsonify
2
- import requests
3
- import threading
4
- import time
5
- import os
6
 
7
  app = Flask(__name__)
8
 
9
- # ─────── LIVE STATE ─────────────────────────
10
  DEBT_STATE = {
11
- "starting_debt": 0,
12
- "rate_per_sec": 0,
13
- "last_updated": time.time()
 
14
  }
15
 
16
- # ─────── API FETCH ─────────────────────────
17
- def get_debt_data():
18
- url = "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/debt_to_penny"
19
- url += "?fields=record_date,tot_pub_debt_out_amt"
20
- url += "&sort=-record_date&page[size]=10"
21
-
22
- resp = requests.get(url, timeout=10)
23
- records = resp.json()["data"]
24
-
 
 
25
  return [
26
- (r["record_date"], float(r["tot_pub_debt_out_amt"]))
27
- for r in records
28
  ]
29
 
30
- # ─────── BACKGROUND REFRESH ────────────────
31
- def refresh_debt_periodically():
 
 
 
 
32
  while True:
33
  try:
34
- records = get_debt_data()
35
- today, today_amt = records[0]
36
- prev_day, prev_amt = None, None
37
 
38
- for r in records[1:]:
39
- if r[1] != today_amt:
40
- prev_day, prev_amt = r
41
- break
42
 
43
- if prev_day:
44
- t1 = time.mktime(time.strptime(today, "%Y-%m-%d"))
45
- t2 = time.mktime(time.strptime(prev_day, "%Y-%m-%d"))
46
- rate = (today_amt - prev_amt) / (t1 - t2)
47
 
48
- # optional: freeze rate if negative
49
- if rate < 0:
50
- rate = 0
51
 
52
- DEBT_STATE["starting_debt"] = today_amt
53
- DEBT_STATE["rate_per_sec"] = rate
54
- DEBT_STATE["last_updated"] = time.time()
55
 
56
- print(f"βœ… Refreshed: {today_amt=:.2f}, {rate=:.2f}/sec")
 
 
 
 
 
 
 
 
 
 
57
 
58
  except Exception as e:
59
- print("❌ Error refreshing debt:", e)
60
 
61
- time.sleep(300) # 5 minutes
62
 
 
63
 
64
- # ─────── ROUTES ────────────────────────────
65
  @app.route("/")
66
- def home():
67
- return "βœ… Debt clock is running", 200
68
 
69
  @app.route("/api/debt")
70
- def get_debt_api():
71
  now = time.time()
72
- elapsed = now - DEBT_STATE["last_updated"]
73
- est = DEBT_STATE["starting_debt"] + DEBT_STATE["rate_per_sec"] * elapsed
74
- return jsonify({
75
- "startingDebt": est,
76
- "ratePerSecond": DEBT_STATE["rate_per_sec"]
77
- })
 
78
 
79
  @app.route("/api/ping")
80
- def ping():
81
- return {"status": "ok", "time": time.strftime("%Y-%m-%d %H:%M:%S")}, 200
82
-
83
 
84
- # ─────── APP START ─────────────────────────
85
  if __name__ == "__main__":
86
- print("βœ… Starting debt refresh thread...")
87
- threading.Thread(target=refresh_debt_periodically, daemon=True).start()
88
-
89
  port = int(os.environ.get("PORT", 7860))
90
  app.run(host="0.0.0.0", port=port)
 
1
+ # app.py
2
+ #
3
+ # Hugging Face Space – Live U.S. Debt Clock
4
+ # Β· Pulls the last 10 Treasury β€œDebt to the Penny” points
5
+ # Β· Derives a $/sec rate from the two most-recent *different* days
6
+ # Β· Computes the *current* debt by projecting from the timestamp
7
+ # of the latest record β†’ now
8
+ # Β· Refreshes every 5 min so the rate/value stay current
9
+ #
10
+ # Endpoints
11
+ # / – simple text β€œrunning” check
12
+ # /api/debt – JSON { startingDebt, ratePerSecond, asOf }
13
+ # /api/ping – lightweight uptime probe
14
+
15
+ import os, time, threading, requests
16
  from flask import Flask, jsonify
 
 
 
 
17
 
18
  app = Flask(__name__)
19
 
20
+ # ─────────────────── runtime state ────────────────────
21
  DEBT_STATE = {
22
+ "debt_at_record": 0.0, # value at latest record date
23
+ "record_time": 0.0, # epoch seconds for that record date (00:00 UTC)
24
+ "rate_per_sec": 0.0, # $/s derived from last-two-points
25
+ "last_refresh": 0.0 # when we last hit the API
26
  }
27
 
28
+ # ─────────────────── helpers ──────────────────────────
29
+ API = (
30
+ "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/"
31
+ "accounting/od/debt_to_penny"
32
+ "?fields=record_date,tot_pub_debt_out_amt"
33
+ "&sort=-record_date&page[size]=10"
34
+ )
35
+
36
+ def load_debt_records():
37
+ r = requests.get(API, timeout=15)
38
+ r.raise_for_status()
39
  return [
40
+ (item["record_date"], float(item["tot_pub_debt_out_amt"]))
41
+ for item in r.json()["data"]
42
  ]
43
 
44
+ def epoch(date_str):
45
+ # record_date is YYYY-MM-DD (assume 00:00 UTC)
46
+ return time.mktime(time.strptime(date_str, "%Y-%m-%d"))
47
+
48
+ # ─────────────────── background refresher ────────────
49
+ def refresher():
50
  while True:
51
  try:
52
+ recs = load_debt_records() # newest first
53
+ (d0_date, d0_val) = recs[0]
 
54
 
55
+ # find previous day with a *different* value
56
+ prev = next((d for d in recs[1:] if d[1] != d0_val), None)
57
+ if prev is None:
58
+ raise ValueError("Could not find two distinct points")
59
 
60
+ (d1_date, d1_val) = prev
 
 
 
61
 
62
+ t0, t1 = epoch(d0_date), epoch(d1_date)
63
+ rate = (d0_val - d1_val) / (t0 - t1) # $/sec
 
64
 
65
+ if rate < 0: # optional: freeze if negative
66
+ rate = 0
 
67
 
68
+ DEBT_STATE.update(
69
+ debt_at_record = d0_val,
70
+ record_time = t0,
71
+ rate_per_sec = rate,
72
+ last_refresh = time.time()
73
+ )
74
+
75
+ print(
76
+ f"[refresh] {d0_date=} "
77
+ f"debt={d0_val:,.2f} rate={rate:,.2f}$/s"
78
+ )
79
 
80
  except Exception as e:
81
+ print("Debt refresh error:", e)
82
 
83
+ time.sleep(300) # five-minute cycle
84
 
85
+ threading.Thread(target=refresher, daemon=True).start()
86
 
87
+ # ────────────��────── routes ──────────────────────────
88
  @app.route("/")
89
+ def root():
90
+ return "βœ… Debt clock running", 200
91
 
92
  @app.route("/api/debt")
93
+ def api_debt():
94
  now = time.time()
95
+ elapsed = now - DEBT_STATE["record_time"]
96
+ current = DEBT_STATE["debt_at_record"] + DEBT_STATE["rate_per_sec"] * elapsed
97
+ return jsonify(
98
+ startingDebt = current,
99
+ ratePerSecond = DEBT_STATE["rate_per_sec"],
100
+ asOf = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(now))
101
+ )
102
 
103
  @app.route("/api/ping")
104
+ def api_ping():
105
+ return {"status": "ok"}, 200
 
106
 
107
+ # ─────────────────── main ────────────────────────────
108
  if __name__ == "__main__":
 
 
 
109
  port = int(os.environ.get("PORT", 7860))
110
  app.run(host="0.0.0.0", port=port)