-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiagnostics.py
More file actions
executable file
·89 lines (75 loc) · 2.9 KB
/
diagnostics.py
File metadata and controls
executable file
·89 lines (75 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import os, time, requests
from dotenv import load_dotenv
from signers import binance_headers, binance_sign
load_dotenv() # loads .env into environment
def ms() -> int:
return int(time.time() * 1000)
def base_url() -> str:
# Allow override (e.g. testnet); default: production
return os.getenv("BINANCE_BASE_URL", "https://api.binance.com")
TOL = int(os.getenv("TIME_SKEW_MS_TOLERANCE", "5000"))
API_KEY = os.getenv("BINANCE_API_KEY")
API_SECRET = os.getenv("BINANCE_API_SECRET")
def binance_server_time():
t0 = ms()
r = requests.get(f"{base_url()}/api/v3/time", timeout=10)
r.raise_for_status()
t1 = ms()
data = r.json()
return {"serverTime": data.get("serverTime"), "rtt_ms": t1 - t0}
def binance_account(api_key, api_secret):
"""
Minimal signed call to prove credentials + permissions
GET /api/v3/account?timestamp=...&signature=...
"""
ts = ms()
params = {"timestamp": ts}
signed_qs = binance_sign(api_secret, params)
url = f"{base_url()}/api/v3/account?" + signed_qs
r = requests.get(url, headers=binance_headers(api_key), timeout=10)
return r
def to_markdown(results: list) -> str:
lines = ["# API Auth Diagnostics (Binance)\n"]
for r in results:
status = "✅ OK" if r.get("ok") else "❌ Check"
lines.append(f"## Binance — {status}")
for n in r["notes"]:
lines.append(f"- {n}")
lines.append("")
return "\n".join(lines)
def diagnose_binance():
out = {"exchange": "binance", "ok": False, "notes": []}
try:
st = binance_server_time()
out["notes"].append(f"RTT: {st['rtt_ms']} ms")
if st.get("serverTime"):
skew = abs(st["serverTime"] - ms())
out["notes"].append(f"Time skew: {skew} ms (tolerance {TOL} ms)")
out["time_skew_ok"] = skew <= TOL
else:
out["notes"].append("Server time not found")
if not API_KEY or not API_SECRET:
out["notes"].append("BINANCE_API_KEY/SECRET missing (.env)")
out["ok"] = False
return out
r = binance_account(API_KEY, API_SECRET)
if r.status_code == 200:
out["auth_ok"] = True
out["notes"].append("Signed /account OK (credentials & permissions look valid)")
elif r.status_code in (401, 403):
out["auth_ok"] = False
out["notes"].append(f"Auth failed: {r.status_code} {r.text[:120]}")
else:
out["auth_ok"] = False
out["notes"].append(f"Signed call error: {r.status_code} {r.text[:120]}")
out["ok"] = bool(out.get("auth_ok")) and bool(out.get("time_skew_ok", True))
return out
except Exception as e:
out["notes"].append(f"Exception: {e}")
return out
if __name__ == "__main__":
res = [diagnose_binance()]
md = to_markdown(res)
print(md)
with open("report.md", "w", encoding="utf-8") as f:
f.write(md)