84 lines
3.2 KiB
Python
84 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Fetch Claude.ai usage limits by connecting to existing Chrome session.
|
|
Requires: pip install playwright
|
|
Usage: python3 claude-usage.py [--json]
|
|
"""
|
|
|
|
import asyncio
|
|
import json
|
|
import re
|
|
import sys
|
|
from playwright.async_api import async_playwright
|
|
|
|
CDP_URL = "http://127.0.0.1:9222" # Chrome DevTools Protocol
|
|
|
|
async def get_usage():
|
|
async with async_playwright() as p:
|
|
try:
|
|
# Connect to existing Chrome instance
|
|
browser = await p.chromium.connect_over_cdp(CDP_URL)
|
|
except Exception as e:
|
|
print(f"Error: Can't connect to Chrome at {CDP_URL}", file=sys.stderr)
|
|
print("Make sure Chrome is running with: --remote-debugging-port=9222", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# Get the default context (existing session with cookies)
|
|
context = browser.contexts[0] if browser.contexts else await browser.new_context()
|
|
page = await context.new_page()
|
|
|
|
try:
|
|
await page.goto("https://claude.ai/settings/usage", wait_until="networkidle", timeout=30000)
|
|
await page.wait_for_selector("text=Plan usage limits", timeout=10000)
|
|
|
|
content = await page.content()
|
|
|
|
# Parse usage data
|
|
usage = {}
|
|
|
|
# Current session
|
|
session_match = re.search(r'Current session.*?(\d+)%\s*used', content, re.DOTALL)
|
|
if session_match:
|
|
usage['session_percent'] = int(session_match.group(1))
|
|
|
|
reset_match = re.search(r'Resets in\s*(\d+)\s*hr\s*(\d+)\s*min', content)
|
|
if reset_match:
|
|
usage['session_resets_hr'] = int(reset_match.group(1))
|
|
usage['session_resets_min'] = int(reset_match.group(2))
|
|
|
|
# Weekly limits - All models
|
|
weekly_match = re.search(r'All models.*?(\d+)%\s*used', content, re.DOTALL)
|
|
if weekly_match:
|
|
usage['weekly_percent'] = int(weekly_match.group(1))
|
|
|
|
weekly_reset_match = re.search(r'Resets\s*(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s*(\d+:\d+\s*[AP]M)', content)
|
|
if weekly_reset_match:
|
|
usage['weekly_resets'] = f"{weekly_reset_match.group(1)} {weekly_reset_match.group(2)}"
|
|
|
|
# Sonnet only
|
|
sonnet_match = re.search(r'Sonnet only.*?(\d+)%\s*used', content, re.DOTALL)
|
|
if sonnet_match:
|
|
usage['sonnet_percent'] = int(sonnet_match.group(1))
|
|
|
|
return usage
|
|
|
|
except Exception as e:
|
|
print(f"Error fetching usage: {e}", file=sys.stderr)
|
|
sys.exit(1)
|
|
finally:
|
|
await page.close()
|
|
|
|
def main():
|
|
usage = asyncio.run(get_usage())
|
|
|
|
if "--json" in sys.argv:
|
|
print(json.dumps(usage))
|
|
else:
|
|
print(f"📊 Claude.ai Usage")
|
|
print(f" Session: {usage.get('session_percent', '?')}% (resets in {usage.get('session_resets_hr', '?')}h {usage.get('session_resets_min', '?')}m)")
|
|
print(f" Weekly: {usage.get('weekly_percent', '?')}% (resets {usage.get('weekly_resets', '?')})")
|
|
print(f" Sonnet: {usage.get('sonnet_percent', '?')}%")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|