Skip to content

Commit 9ef679a

Browse files
add linting checks using ruff and make lint related refactors
1 parent 33aa48f commit 9ef679a

7 files changed

Lines changed: 144 additions & 122 deletions

File tree

.github/workflows/test.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,27 @@ on:
77
branches: [main, develop]
88

99
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- uses: actions/setup-python@v5
16+
with:
17+
python-version: "3.12"
18+
19+
- name: Install ruff
20+
run: pip install ruff
21+
22+
- name: Lint (ruff check)
23+
run: ruff check hooks/ tests/ --output-format github
24+
25+
- name: Format (ruff format)
26+
run: ruff format hooks/ tests/ --check
27+
1028
test:
1129
runs-on: ubuntu-latest
30+
needs: lint
1231
strategy:
1332
matrix:
1433
python-version: ["3.10", "3.11", "3.12"]

hooks/enforce_quota.py

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@
1515
"""
1616

1717
import json
18-
import sys
1918
import os
19+
import sys
2020
from datetime import date, timedelta
21-
from pathlib import Path
2221

23-
sys.path.insert(0, str(Path(__file__).parent))
2422
from quota_store import QuotaStore
2523

2624
WARN_CRITICAL = int(os.environ.get("TOKEN_QUOTA_WARN_CRITICAL", 95))
@@ -42,14 +40,7 @@ def main():
4240
pct_daily = (used_daily / effective_daily) * 100 if effective_daily > 0 else 0
4341

4442
if used_daily >= effective_daily:
45-
result = {
46-
"decision": "block",
47-
"reason": (
48-
f"Daily token quota exceeded.\n"
49-
f"Used: {used_daily:,} / {effective_daily:,} tokens ({pct_daily:.1f}%)\n"
50-
f"Quota resets at midnight. Edit TOKEN_QUOTA_DAILY to change the limit."
51-
)
52-
}
43+
result = {"decision": "block", "reason": (f"Daily token quota exceeded.\nUsed: {used_daily:,} / {effective_daily:,} tokens ({pct_daily:.1f}%)\nQuota resets at midnight. Edit TOKEN_QUOTA_DAILY to change the limit.")}
5344
print(json.dumps(result))
5445
sys.exit(0)
5546

@@ -59,14 +50,7 @@ def main():
5950
effective_weekly = store.weekly_limit + snooze
6051
if used_weekly >= effective_weekly:
6152
pct = (used_weekly / effective_weekly) * 100
62-
result = {
63-
"decision": "block",
64-
"reason": (
65-
f"Weekly token quota exceeded (rolling 7-day window).\n"
66-
f"Used: {used_weekly:,} / {effective_weekly:,} tokens ({pct:.1f}%)\n"
67-
f"Edit TOKEN_QUOTA_WEEKLY to change the limit."
68-
)
69-
}
53+
result = {"decision": "block", "reason": (f"Weekly token quota exceeded (rolling 7-day window).\nUsed: {used_weekly:,} / {effective_weekly:,} tokens ({pct:.1f}%)\nEdit TOKEN_QUOTA_WEEKLY to change the limit.")}
7054
print(json.dumps(result))
7155
sys.exit(0)
7256

@@ -76,14 +60,7 @@ def main():
7660
effective_monthly = store.monthly_limit + snooze
7761
if used_monthly >= effective_monthly:
7862
pct = (used_monthly / effective_monthly) * 100
79-
result = {
80-
"decision": "block",
81-
"reason": (
82-
f"Monthly token quota exceeded.\n"
83-
f"Used: {used_monthly:,} / {effective_monthly:,} tokens ({pct:.1f}%)\n"
84-
f"Quota resets on the 1st. Edit TOKEN_QUOTA_MONTHLY to change the limit."
85-
)
86-
}
63+
result = {"decision": "block", "reason": (f"Monthly token quota exceeded.\nUsed: {used_monthly:,} / {effective_monthly:,} tokens ({pct:.1f}%)\nQuota resets on the 1st. Edit TOKEN_QUOTA_MONTHLY to change the limit.")}
8764
print(json.dumps(result))
8865
sys.exit(0)
8966

hooks/quota_status.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
import json
1212
import os
1313
from datetime import date, timedelta
14-
from pathlib import Path
15-
import sys
1614

17-
sys.path.insert(0, str(Path(__file__).parent))
1815
from quota_store import QuotaStore
1916

2017
_cost_raw = os.environ.get("TOKEN_QUOTA_COST_PER_M")
@@ -41,12 +38,12 @@ def main():
4138

4239
if store.monthly_limit is not None and store.retain_days < 31:
4340
print(f" ⚠️ WARNING: TOKEN_QUOTA_RETAIN_DAYS={store.retain_days} is below 31.")
44-
print(f" Monthly totals may be incomplete for 31-day months.")
45-
print(f" Set TOKEN_QUOTA_RETAIN_DAYS=31 or higher to fix this.")
41+
print(" Monthly totals may be incomplete for 31-day months.")
42+
print(" Set TOKEN_QUOTA_RETAIN_DAYS=31 or higher to fix this.")
4643

47-
print(f"\n{'─'*50}")
44+
print(f"\n{'─' * 50}")
4845
print(f" Claude Code Token Quota — {today.isoformat()}")
49-
print(f"{'─'*50}")
46+
print(f"{'─' * 50}")
5047

5148
snooze = store.get_snooze()
5249

@@ -106,7 +103,7 @@ def main():
106103
print(f" Snooze: {snooze:>12,} tokens (expires midnight)")
107104
print(f" Status: {status}")
108105

109-
print(f"\n{'─'*50}\n")
106+
print(f"\n{'─' * 50}\n")
110107

111108

112109
if __name__ == "__main__":

hooks/quota_store.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
quota_store.py — shared data access layer for all token-quota hooks.
33
44
Encapsulates config parsing, ledger reads/writes, snooze state, and cleanup.
5-
Import via:
6-
import sys
7-
from pathlib import Path
8-
sys.path.insert(0, str(Path(__file__).parent))
9-
from quota_store import QuotaStore
105
"""
116

127
import json
@@ -99,7 +94,12 @@ def get_snooze(self) -> int:
9994
def write_snooze(self, extra_tokens: int):
10095
self.ledger_dir.mkdir(parents=True, exist_ok=True)
10196
snooze_file = self.ledger_dir / "snooze.json"
102-
snooze_file.write_text(json.dumps({
103-
"extra_tokens": extra_tokens,
104-
"expires": date.today().isoformat(),
105-
}, indent=2))
97+
snooze_file.write_text(
98+
json.dumps(
99+
{
100+
"extra_tokens": extra_tokens,
101+
"expires": date.today().isoformat(),
102+
},
103+
indent=2,
104+
)
105+
)

hooks/snooze.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,14 @@
66
Set TOKEN_QUOTA_SNOOZE_TOKENS to change the snooze amount (default: 1,000,000).
77
"""
88

9-
import sys
10-
from pathlib import Path
11-
12-
sys.path.insert(0, str(Path(__file__).parent))
139
from quota_store import QuotaStore
1410

1511

1612
def main():
1713
store = QuotaStore()
1814
store.write_snooze(store.snooze_tokens)
1915
print(f"Quota snoozed: +{store.snooze_tokens:,} tokens added to all limits for today.")
20-
print(f"Expires at midnight. Set TOKEN_QUOTA_SNOOZE_TOKENS to change the amount.")
16+
print("Expires at midnight. Set TOKEN_QUOTA_SNOOZE_TOKENS to change the amount.")
2117

2218

2319
if __name__ == "__main__":

hooks/track_tokens.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from datetime import datetime
1010
from pathlib import Path
1111

12-
sys.path.insert(0, str(Path(__file__).parent))
1312
from quota_store import QuotaStore
1413

1514

@@ -49,10 +48,10 @@ def main():
4948
if not usage:
5049
sys.exit(0)
5150

52-
input_tokens = usage.get("input_tokens", 0)
51+
input_tokens = usage.get("input_tokens", 0)
5352
output_tokens = usage.get("output_tokens", 0)
54-
cache_write = usage.get("cache_creation_input_tokens", 0)
55-
cache_read = usage.get("cache_read_input_tokens", 0)
53+
cache_write = usage.get("cache_creation_input_tokens", 0)
54+
cache_read = usage.get("cache_read_input_tokens", 0)
5655
total = input_tokens + output_tokens + cache_write + cache_read
5756

5857
if total == 0:
@@ -61,13 +60,15 @@ def main():
6160
store = QuotaStore()
6261
ledger = store.load_ledger()
6362
ledger["total_tokens"] += total
64-
ledger["sessions"].append({
65-
"timestamp": datetime.now().isoformat(timespec="seconds"),
66-
"input_tokens": input_tokens,
67-
"output_tokens": output_tokens,
68-
"cache_write_tokens": cache_write,
69-
"cache_read_tokens": cache_read,
70-
})
63+
ledger["sessions"].append(
64+
{
65+
"timestamp": datetime.now().isoformat(timespec="seconds"),
66+
"input_tokens": input_tokens,
67+
"output_tokens": output_tokens,
68+
"cache_write_tokens": cache_write,
69+
"cache_read_tokens": cache_read,
70+
}
71+
)
7172
store.save_ledger(ledger)
7273

7374
print(f"[token-quota] +{total:,} tokens this turn | today total: {ledger['total_tokens']:,}", file=sys.stderr)

0 commit comments

Comments
 (0)