Spaces:
Sleeping
Sleeping
File size: 7,209 Bytes
2f10a39 1a4b7af b80070b 1a4b7af d374f49 e1c614d d21f1d8 de5f5f5 b80070b 029d7b6 b80070b 1a4b7af e1c614d de5f5f5 b80070b 3fc7f57 1a4b7af b80070b 1a4b7af de5f5f5 d30c20a b80070b 04e3232 d30c20a b80070b 9f05482 b80070b 4c1c6de de5f5f5 b80070b de5f5f5 b80070b e2f0610 b80070b 04e3232 5afac81 b80070b 5afac81 b80070b 1a4b7af b80070b 04e3232 de5f5f5 b80070b de5f5f5 b80070b 97db9b6 b80070b 5afac81 de5289a b80070b | 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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | import sys
import os
import time
import json
import requests
from huggingface_hub import HfApi, hf_hub_download
from datetime import datetime
REPO_ID = "ravi2814/grant-data-storage"
KERNEL_SLUG = "grant-data-updater-worker"
CODE_DIR = "kaggle_worker"
os.environ["HF_HUB_DISABLE_PROGRESS_BARS"] = "1"
def print_ui(msg):
print(msg, flush=True)
class RemoteController:
def __init__(self):
self.username = os.getenv("KAGGLE_USERNAME")
self.hf_token = os.getenv("HF_TOKEN")
self.hf_api = HfApi(token=self.hf_token)
from kaggle.api.kaggle_api_extended import KaggleApi
self.api = KaggleApi()
self.api.authenticate()
if not os.path.exists(CODE_DIR):
os.makedirs(CODE_DIR)
def reset_logs(self):
try:
self.hf_api.delete_file(
path_in_repo="live_log.txt",
repo_id=REPO_ID,
repo_type="dataset",
commit_message="Reset logs"
)
except: pass
def check_for_updates(self):
print_ui("Checking for updates...")
gov_date = None
try:
api_url = "https://open.canada.ca/data/api/3/action/package_show?id=432527ab-7aac-45b5-81d6-7597107a7013"
resp = requests.get(api_url, timeout=10)
result = resp.json()['result']
resource = next((r for r in result['resources'] if r['id'] == '1d15a62f-5656-49ad-8c88-f40ce689d831'), None)
if resource:
gov_str = resource.get('last_modified') or result.get('metadata_modified')
gov_date = datetime.fromisoformat(gov_str.replace('Z', '+00:00')).replace(tzinfo=None)
print_ui(f"Government Data Date: {gov_date}")
else:
return True, None, None
try:
hf_hub_download(repo_id=REPO_ID, filename="last_metadata.json", local_dir=".", token=self.hf_token, force_download=True, repo_type="dataset")
with open("last_metadata.json", "r") as f:
meta = json.load(f)
my_str = meta.get('resource_modified')
if not my_str: return True, gov_date, meta
my_date = datetime.fromisoformat(my_str.replace('Z', '+00:00')).replace(tzinfo=None)
print_ui(f"Your Database Date: {my_date}")
if gov_date > my_date:
print_ui("New data available.")
return True, gov_date, meta
else:
return False, gov_date, meta
except:
return True, gov_date, None
except Exception as e:
print_ui(f"Check error: {e}. Forcing run.")
return True, None, None
def update_timestamp(self, meta):
print_ui("Status: Up to date.")
if meta:
meta['checked_at'] = datetime.now().isoformat()
with open("last_metadata.json", "w") as f:
json.dump(meta, f)
self.hf_api.upload_file(
path_or_fileobj="last_metadata.json",
path_in_repo="last_metadata.json",
repo_id=REPO_ID,
repo_type="dataset",
commit_message="Timestamp update"
)
print_ui("Timestamp updated.")
def run_remote_worker(self):
print_ui("Preparing worker...")
with open("worker_script.py", "r") as f:
script_content = f.read()
if "HF_TOKEN_PLACEHOLDER" in script_content:
script_content = script_content.replace("HF_TOKEN_PLACEHOLDER", self.hf_token)
with open(os.path.join(CODE_DIR, "worker.py"), "w") as f:
f.write(script_content)
meta = {
"id": f"{self.username}/{KERNEL_SLUG}",
"title": "Grant Data Updater Worker",
"code_file": "worker.py",
"language": "python",
"kernel_type": "script",
"is_private": "true",
"enable_gpu": "true",
"enable_internet": "true",
"dataset_sources": [], "kernel_sources": [], "competition_sources": []
}
with open(os.path.join(CODE_DIR, "kernel-metadata.json"), "w") as f:
json.dump(meta, f)
print_ui("Deploying to Kaggle...")
try:
self.api.kernels_push(CODE_DIR)
print_ui("Code pushed.")
except Exception as e:
if "already queued" in str(e).lower():
print_ui("Worker already queued.")
else:
raise e
def monitor_progress(self):
print_ui("Connecting to worker...")
start_time = time.time()
last_log_content = ""
kaggle_confirmed = False
time.sleep(5) # Give API a moment
while True:
try:
stat = self.api.kernels_status(f"{self.username}/{KERNEL_SLUG}")
status = stat['status'] if isinstance(stat, dict) else getattr(stat, 'status', 'unknown')
except:
status = "unknown"
# --- KEY CHANGE: Trigger UI update immediately ---
if not kaggle_confirmed and status in ['queued', 'running', 'starting']:
kaggle_confirmed = True
print_ui("STATUS: KAGGLE_STARTED")
try:
hf_hub_download(repo_id=REPO_ID, filename="live_log.txt", local_dir=".", token=self.hf_token, force_download=True, repo_type="dataset")
if os.path.exists("live_log.txt"):
with open("live_log.txt", "r") as f:
content = f.read()
if len(content) > len(last_log_content):
new_text = content[len(last_log_content):]
print(new_text, end='', flush=True)
last_log_content = content
except:
pass
if status == 'complete':
print_ui("\nWorker finished successfully.")
return True
elif status == 'error':
print_ui("\nWorker failed.")
return False
time.sleep(5)
if time.time() - start_time > 3600:
print_ui("Timeout: 60 minutes limit.")
return False
if __name__ == "__main__":
try:
if not os.getenv("HF_TOKEN") or not os.getenv("KAGGLE_USERNAME"):
print_ui("Error: Missing credentials")
sys.exit(1)
controller = RemoteController()
needs_update, gov_date, meta = controller.check_for_updates()
if needs_update:
controller.reset_logs()
controller.run_remote_worker()
success = controller.monitor_progress()
if success:
print_ui("Sync Complete")
else:
sys.exit(1)
else:
controller.update_timestamp(meta)
except Exception as e:
print_ui(f"Error: {e}")
sys.exit(1) |