ntdservices commited on
Commit
f9eb3ae
Β·
verified Β·
1 Parent(s): 0ed064f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -94
app.py CHANGED
@@ -1,109 +1,90 @@
1
- # app.py
2
- #
3
- # Hugging Face Space for a live U.S.-debt counter
4
- # now exposes:
5
- # β€’ /api/debt – JSON with current total and per-second rate
6
- # β€’ /embed.js – tiny loader that paints any <div class="ntd-debt-clock">
7
- # inside the host page (works under HF CSP)
8
-
9
- import os, time, requests
10
- from datetime import datetime
11
- from flask import Flask, jsonify, send_from_directory
12
- from flask_cors import CORS
13
-
14
- # ---------------------------------------------------------------------
15
- # Fetch last two debt records from Treasury API and calculate rate
16
- # ---------------------------------------------------------------------
17
-
18
- API_URL = "https://api.fiscaldata.treasury.gov/services/api/fiscal_service/v2/accounting/od/debt_to_penny"
19
- FIELDS = "record_date,tot_pub_debt_out_amt"
20
- PARAMS = {
21
- "fields": FIELDS,
22
- "sort": "-record_date",
23
- "page[size]": 2
24
  }
25
 
26
- try:
27
- r = requests.get(API_URL, params=PARAMS, timeout=10)
28
- r.raise_for_status()
29
- data = r.json()["data"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
- # Parse records
32
- d1 = float(data[0]["tot_pub_debt_out_amt"].replace(",", ""))
33
- d2 = float(data[1]["tot_pub_debt_out_amt"].replace(",", ""))
34
- t1 = datetime.strptime(data[0]["record_date"], "%Y-%m-%d").timestamp()
35
- t2 = datetime.strptime(data[1]["record_date"], "%Y-%m-%d").timestamp()
36
 
37
- # Calculate rate per second
38
- RATE_PER_SECOND = (d1 - d2) / (t1 - t2)
39
- STARTING_DEBT = d1
40
- START_TIMESTAMP = t1
41
 
42
- except Exception as e:
43
- print("Error fetching Treasury data:", e)
44
- # fallback if API fails
45
- STARTING_DEBT = 34_457_892_345_678.12
46
- RATE_PER_SECOND = 10_000.23
47
- START_TIMESTAMP = time.time()
48
 
49
- # ---------------------------------------------------------------------
50
 
51
- app = Flask(__name__, static_folder="templates")
52
- CORS(app)
53
 
 
 
 
 
54
  @app.route("/")
55
- def root():
56
- return send_from_directory("static", "index.html")
57
 
58
  @app.route("/api/debt")
59
- def api_debt():
60
- elapsed = time.time() - START_TIMESTAMP
61
- current = STARTING_DEBT + RATE_PER_SECOND * elapsed
62
- return jsonify(startingDebt=current, ratePerSecond=RATE_PER_SECOND)
63
-
64
- @app.route("/embed.js")
65
- def embed():
66
- js = """
67
- (() => {
68
- const API = "https://ntdservices-debt-clock.hf.space/api/debt";
69
- const CLS = "ntd-debt-clock";
70
- function mount(el) {
71
- Object.assign(el.style, {
72
- font: "700 5.4rem/1.2 'Courier New', monospace",
73
- color: "#0f0",
74
- background: "linear-gradient(145deg, #0a0a0a, #1a1a1a)",
75
- padding: "12px 20px",
76
- borderRadius: "12px",
77
- whiteSpace: "nowrap",
78
- boxShadow: "0 0 12px rgba(0,255,0,0.5), 0 0 30px rgba(0,255,0,0.2) inset",
79
- border: "2px solid rgba(0,255,0,0.3)",
80
- letterSpacing: "1.5px",
81
- transition: "all 0.3s ease-out",
82
- textShadow: "0 0 2px #0f0, 0 0 8px #0f0",
83
- marginTop: "-35vh"
84
- });
85
- fetch(API).then(r => r.json()).then(d => {
86
- let debt = d.startingDebt;
87
- const rate = d.ratePerSecond;
88
- let last = performance.now();
89
- function tick(now) {
90
- const dt = (now - last) / 1000;
91
- last = now;
92
- debt += rate * dt;
93
- el.textContent = "$" + Math.floor(debt).toLocaleString();
94
- requestAnimationFrame(tick);
95
- }
96
- requestAnimationFrame(tick);
97
- }).catch(() => { el.textContent = "N/A"; });
98
- }
99
- document.querySelectorAll("." + CLS).forEach(mount);
100
- })();
101
- """
102
- return js, 200, {
103
- "Content-Type": "application/javascript; charset=utf-8",
104
- "Cache-Control": "public, max-age=31536000, immutable"
105
- }
106
 
 
 
107
  if __name__ == "__main__":
 
 
 
108
  port = int(os.environ.get("PORT", 7860))
109
  app.run(host="0.0.0.0", port=port)
 
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)