Skip to content

Commit 94c843b

Browse files
committed
Add step to cleanup finetuned models before other tests
1 parent 4110323 commit 94c843b

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

.github/workflows/pytest.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ jobs:
5656
run: >
5757
make devenv
5858
59+
- name: Cleanup old finetuned models
60+
run: >
61+
uv run python scripts/cleanup_finetuned_models.py --older-than 60
62+
continue-on-error: true
63+
5964
- name: Run tests (Linux Python 3.11)
6065
if: runner.os == 'Linux' && matrix.python-version == '3.11'
6166
env:
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to clean up finetuned models older than a specified duration.
4+
Usage: python scripts/cleanup_finetuned_models.py [--older-than MINUTES] [--dry-run]
5+
"""
6+
7+
import os
8+
import sys
9+
from argparse import ArgumentParser
10+
from datetime import datetime, timedelta, timezone
11+
12+
from nixtla.nixtla_client import NixtlaClient
13+
14+
15+
def cleanup_models(older_than_minutes: int = 30, dry_run: bool = False) -> int:
16+
"""
17+
Clean up finetuned models older than specified duration.
18+
19+
Args:
20+
older_than_minutes: Delete models older than this many minutes (default: 30).
21+
dry_run: If True, only list models without deleting them.
22+
23+
Returns:
24+
Number of models deleted.
25+
"""
26+
# Collect all credential pairs from environment
27+
credentials = [
28+
(os.environ.get("NIXTLA_API_KEY_CUSTOM"), os.environ.get("NIXTLA_BASE_URL_CUSTOM")),
29+
(os.environ.get("NIXTLA_API_KEY"), os.environ.get("NIXTLA_BASE_URL")),
30+
(os.environ.get("NIXTLA_API_KEY_FOR_SF"), os.environ.get("NIXTLA_BASE_URL")),
31+
]
32+
33+
# Filter out None/empty credentials
34+
credentials = [(key, url) for key, url in credentials if key and url]
35+
36+
if not credentials:
37+
print("⚠ No credentials found. Skipping cleanup.")
38+
return 0
39+
40+
now = datetime.now(timezone.utc)
41+
cutoff_time = now - timedelta(minutes=older_than_minutes)
42+
43+
total_deleted = 0
44+
total_failed = 0
45+
46+
for api_key, base_url in credentials:
47+
try:
48+
client = NixtlaClient(api_key=api_key, base_url=base_url)
49+
models = client.finetuned_models()
50+
except Exception:
51+
# Silently skip if unable to connect
52+
continue
53+
54+
# Filter models older than cutoff time
55+
old_models = []
56+
for model in models:
57+
model_time = model.created_at
58+
if model_time.tzinfo is None:
59+
model_time = model_time.replace(tzinfo=timezone.utc)
60+
61+
if model_time < cutoff_time:
62+
old_models.append(model)
63+
64+
if not old_models:
65+
continue
66+
67+
if dry_run:
68+
total_deleted += len(old_models)
69+
continue
70+
71+
# Delete old models
72+
for model in old_models:
73+
try:
74+
client.delete_finetuned_model(model.id)
75+
total_deleted += 1
76+
except Exception:
77+
total_failed += 1
78+
79+
if dry_run:
80+
print(f"🔍 Found {total_deleted} model(s) older than {older_than_minutes} minute(s)")
81+
print("📋 [DRY RUN] Models would be deleted without --dry-run")
82+
else:
83+
print(f"✓ Cleaned up {total_deleted} finetuned model(s)")
84+
if total_failed:
85+
print(f"⚠ {total_failed} model(s) failed to delete")
86+
87+
return total_deleted
88+
89+
90+
if __name__ == "__main__":
91+
parser = ArgumentParser(description="Clean up old finetuned models")
92+
parser.add_argument(
93+
"--older-than",
94+
type=int,
95+
default=30,
96+
help="Delete models older than this many minutes (default: 30)",
97+
)
98+
parser.add_argument("--dry-run", action="store_true", help="List models without deleting")
99+
args = parser.parse_args()
100+
101+
cleanup_models(older_than_minutes=args.older_than, dry_run=args.dry_run)
102+
sys.exit(0)

0 commit comments

Comments
 (0)