z90486091 commited on
Commit
581b000
·
verified ·
1 Parent(s): a94a91b

Update db_syncer.py

Browse files
Files changed (1) hide show
  1. db_syncer.py +28 -50
db_syncer.py CHANGED
@@ -1,22 +1,15 @@
1
  #!/usr/bin/env python3
2
  """
3
- db_syncer.py — watches litellm.db for changes, commits to HF Space repo every 5 mins.
4
- Run as background process inside the container.
5
-
6
- Required env vars:
7
- HF_TOKEN — HuggingFace write token
8
- HF_REPO_ID — e.g. Ins0mn1a/llm_router-v1
9
- DB_PATH — path to litellm.db (default: /app/data/litellm.db)
10
- SYNC_INTERVAL — seconds between syncs (default: 300)
11
  """
12
 
13
  import hashlib
14
  import os
 
15
  import time
16
  import logging
17
- import base64
18
-
19
- import requests
20
 
21
  logging.basicConfig(
22
  format="%(asctime)s [db_syncer] %(levelname)s %(message)s",
@@ -24,12 +17,10 @@ logging.basicConfig(
24
  )
25
  log = logging.getLogger("db_syncer")
26
 
27
- HF_TOKEN = os.environ["HF_TOKEN"]
28
- HF_REPO_ID = os.environ["HF_REPO_ID"]
29
  DB_PATH = os.environ.get("DB_PATH", "/app/data/litellm.db")
 
 
30
  SYNC_INTERVAL = int(os.environ.get("SYNC_INTERVAL", "300"))
31
- HF_API = "https://huggingface.co/api"
32
- REPO_FILE_PATH = "litellm.db"
33
 
34
 
35
  def file_hash(path: str) -> str:
@@ -40,45 +31,32 @@ def file_hash(path: str) -> str:
40
  return h.hexdigest()
41
 
42
 
43
- def get_remote_sha(headers: dict) -> str | None:
44
- """Get current file SHA from HF repo (needed for updates)."""
45
- url = f"{HF_API}/spaces/{HF_REPO_ID}/raw/{REPO_FILE_PATH}"
46
- r = requests.head(url, headers=headers)
47
- if r.status_code == 200:
48
- return r.headers.get("X-SHA")
49
- return None
50
-
51
-
52
- def upload_db(headers: dict) -> bool:
53
- """Upload litellm.db to HF Space repo via API."""
54
- with open(DB_PATH, "rb") as f:
55
- content = base64.b64encode(f.read()).decode()
56
-
57
- payload = {
58
- "content": content,
59
- "encoding": "base64",
60
- "message": f"db_syncer: auto-sync litellm.db",
61
- }
62
-
63
- url = f"{HF_API}/spaces/{HF_REPO_ID}/upload/{REPO_FILE_PATH}"
64
- r = requests.post(url, headers=headers, json=payload, timeout=60)
65
-
66
- if r.status_code in (200, 201):
67
  log.info("Synced litellm.db to HF Space repo")
68
  return True
69
- else:
70
- log.error(f"Sync failed: {r.status_code} {r.text[:200]}")
71
  return False
72
 
73
 
74
  def main():
75
  log.info(f"Starting db_syncer — watching {DB_PATH} every {SYNC_INTERVAL}s")
76
- log.info(f"Target repo: {HF_REPO_ID}")
77
-
78
- headers = {
79
- "Authorization": f"Bearer {HF_TOKEN}",
80
- "Content-Type": "application/json",
81
- }
82
 
83
  last_hash = None
84
 
@@ -93,13 +71,13 @@ def main():
93
 
94
  if current_hash != last_hash:
95
  log.info(f"Change detected (hash: {current_hash[:8]}...) — syncing")
96
- if upload_db(headers):
97
  last_hash = current_hash
98
  else:
99
- log.debug("No change detected — skipping sync")
100
 
101
  except Exception as e:
102
- log.error(f"Sync error: {e}")
103
 
104
  time.sleep(SYNC_INTERVAL)
105
 
 
1
  #!/usr/bin/env python3
2
  """
3
+ db_syncer.py — watches litellm.db for changes, git commits + pushes to HF Space repo.
4
+ Runs as background process inside the HF Space container.
5
+ Uses HF Space's built-in git repo at /app.
 
 
 
 
 
6
  """
7
 
8
  import hashlib
9
  import os
10
+ import subprocess
11
  import time
12
  import logging
 
 
 
13
 
14
  logging.basicConfig(
15
  format="%(asctime)s [db_syncer] %(levelname)s %(message)s",
 
17
  )
18
  log = logging.getLogger("db_syncer")
19
 
 
 
20
  DB_PATH = os.environ.get("DB_PATH", "/app/data/litellm.db")
21
+ REPO_PATH = os.environ.get("REPO_PATH", "/app")
22
+ REPO_DB_FILENAME = "litellm.db"
23
  SYNC_INTERVAL = int(os.environ.get("SYNC_INTERVAL", "300"))
 
 
24
 
25
 
26
  def file_hash(path: str) -> str:
 
31
  return h.hexdigest()
32
 
33
 
34
+ def sync_db() -> bool:
35
+ try:
36
+ dest = os.path.join(REPO_PATH, REPO_DB_FILENAME)
37
+ subprocess.run(["cp", DB_PATH, dest], check=True)
38
+ subprocess.run(["git", "-C", REPO_PATH, "add", REPO_DB_FILENAME], check=True)
39
+ result = subprocess.run(
40
+ ["git", "-C", REPO_PATH, "diff", "--cached", "--quiet"],
41
+ capture_output=True,
42
+ )
43
+ if result.returncode == 0:
44
+ log.info("No git diff skipping commit")
45
+ return True
46
+ subprocess.run(
47
+ ["git", "-C", REPO_PATH, "commit", "-m", "db_syncer: auto-sync litellm.db"],
48
+ check=True,
49
+ )
50
+ subprocess.run(["git", "-C", REPO_PATH, "push"], check=True)
 
 
 
 
 
 
 
51
  log.info("Synced litellm.db to HF Space repo")
52
  return True
53
+ except subprocess.CalledProcessError as e:
54
+ log.error(f"Sync failed: {e}")
55
  return False
56
 
57
 
58
  def main():
59
  log.info(f"Starting db_syncer — watching {DB_PATH} every {SYNC_INTERVAL}s")
 
 
 
 
 
 
60
 
61
  last_hash = None
62
 
 
71
 
72
  if current_hash != last_hash:
73
  log.info(f"Change detected (hash: {current_hash[:8]}...) — syncing")
74
+ if sync_db():
75
  last_hash = current_hash
76
  else:
77
+ log.debug("No change — skipping")
78
 
79
  except Exception as e:
80
+ log.error(f"Unexpected error: {e}")
81
 
82
  time.sleep(SYNC_INTERVAL)
83