Scrapes LLM model deprecation and retirement dates from provider documentation, matches them against your list of active models, maintains a persistent local database, and exports results to Google Sheets with risk-based colour coding.
To run this on your own computer you need one file: credentials.json. This is the key that lets the script sign in to Google and write to our shared sheet. For security, everyone uses their own key — it is never passed around between people, and it is never committed to this project (git ignores it).
Two one-time steps:
-
Create your own
credentials.json. Follow Setup steps 3–4 below: in a Google Cloud project turn on the Google Sheets and Drive APIs, create a service account, and download its JSON key. Save that file in the main folder of this project (the same folder as this README) and name it exactlycredentials.json. The script finds it automatically. -
Get your key access to the shared sheet. Open your
credentials.jsonand copy theclient_emailvalue — it looks likesomething@your-project.iam.gserviceaccount.com. Send that address to Ben (bnguyen@studiosity.com), and he'll share the team sheet with it so your key is allowed to write. (You only do this once.)
We all write to the same Google Sheet — on purpose. The sheet is already set in the code, so everyone's results go to one shared place. Please do not change the sheet ID in src/main.py and do not create your own sheet — if we each used a different one we'd end up with scattered, out-of-date data instead of one view everyone can trust. Once your key has access, run the script whenever you like to keep the shared sheet current (see Usage).
| Provider | Source page |
|---|---|
| Google Gemini | ai.google.dev/gemini-api/docs/deprecations |
| OpenAI | developers.openai.com/api/docs/deprecations |
| Azure OpenAI | learn.microsoft.com — model retirements |
| Anthropic | platform.claude.com/docs/about-claude/model-deprecations |
| Vertex AI | docs.cloud.google.com — partner models deprecations |
| AWS Bedrock | docs.aws.amazon.com/bedrock/latest/userguide/model-lifecycle.html |
AWS Bedrock model card pages (context window, modalities, geo inference IDs, etc.) are also scraped from the provider-specific card hierarchy under model-cards.html.
- Scrapes each provider's deprecation/lifecycle page
- Scrapes AWS Bedrock individual model card pages for rich metadata
- Merges results into
data/models_db.json— records are never deleted by a scrape run (models that disappear from a provider page keep their last-known data) - Prunes records whose shutdown date expired more than 1 year ago
- Matches the full DB against
MY_MODELSinsrc/main.py - Exports three Google Sheets tabs with colour-coded risk levels
| Level | Condition | Colour |
|---|---|---|
| EXPIRED | Already past shutdown date | Muted rose |
| CRITICAL | ≤ 30 days remaining | Soft peach-orange |
| HIGH | ≤ 90 days remaining | Soft amber |
| MEDIUM | ≤ 180 days remaining | Pale yellow |
| LOW | > 180 days remaining | Soft mint |
| Unknown | Date could not be parsed | White |
| Not found | Model not in any provider page | Light grey |
Every record in the local DB, across all providers.
| Column | Notes |
|---|---|
| Provider | |
| Model | Model ID or human-readable name |
| Lifecycle Stage | Active / Legacy / EOL — AWS Bedrock only |
| Scraped Shutdown Date | Raw string from the provider page |
| Parsed Shutdown Date | Normalised to YYYY-MM-DD; N/A if unparseable |
| Days Remaining | Integer; negative = already expired |
| Risk Level | See table above; colour-coded cell |
| Source URL | Direct link to the provider page |
| First Seen | Date the record was first added to the local DB |
| Last Seen | Date the record was last confirmed by a scrape run |
Only models from MY_MODELS. Unmatched models appear at the bottom in grey with "Not found" values so nothing is silently omitted.
| Column | Notes |
|---|---|
| Last Updated | Timestamp of the run (Australia/Melbourne timezone) |
| Our Model | Exactly as written in MY_MODELS |
| Scraped Model | Matched identifier from the provider page |
| Provider | |
| Scraped Shutdown Date | |
| Parsed Shutdown Date | |
| Days Remaining | |
| Risk Level | Colour-coded cell |
AWS Bedrock models that have model card metadata. Only shown when card data is available.
| Column | Notes |
|---|---|
| Model ID | |
| Lifecycle Stage | |
| Context Window | Tokens (integer) |
| Max Output Tokens | Tokens (integer) |
| Input Modalities | Comma-separated list |
| Output Modalities | Comma-separated list |
| Knowledge Cutoff | |
| Geo Inference IDs | Comma-separated cross-region inference profile IDs |
| Model Card URL | Direct link to the AWS Bedrock model card page |
Edit src/main.py:
# Target Google Sheet
SPREADSHEET_ID = 'your-sheet-id-from-url'
# Models your application uses
MY_MODELS = [
"gpt-4o-mini",
"anthropic.claude-3-haiku-20240307-v1:0",
"us.meta.llama3-3-70b-instruct-v1:0", # Bedrock cross-region prefix stripped automatically
...
]MY_MODELS matching rules (applied in order):
- Exact match
- Scraped model has appended version info —
gpt-4omatchesgpt-4o (2024-05-13) - User model has appended version tag —
claude-3-haiku@20240307matchesclaude-3-haiku - AWS Bedrock cross-region prefix stripped —
us.meta.llama3-...matchesmeta.llama3-...Supported prefixes:us.eu.ap.apac.au.ca.jp.global.us-gov.
python src/main.pyRun from the project root. The src/ directory is automatically on the Python path.
Python 3.8 or later is required.
pip install -r requirements.txt- Go to Google Cloud Console
- Create or select a project
- Enable the Google Sheets API and Google Drive API
- Navigate to IAM & Admin > Service Accounts
- Click Create Service Account (e.g.
llm-eol-tracker) - Click the account → Keys tab → Add Key > Create New Key > JSON
- Save the downloaded file as
credentials.jsonin the project root, or setGOOGLE_CREDENTIALS_FILEto its path
credentials.jsonis listed in.gitignoreand must never be committed.
Copy the service account email from credentials.json and share your target Google Sheet with it (Editor access).
Model records are persisted to data/models_db.json. This file:
- Is safe to commit — it contains no secrets, only scraped public data
- Grows incrementally — records are merged in on each run, never bulk-replaced
- Retains records that disappear from provider pages, with
last_seenshowing when they were last confirmed - Has expired entries (shutdown date > 1 year ago) pruned automatically on each run
The Google Sheet is a human-readable view of the database, not a replacement for it. It is output-only; the JSON file is the operational source of truth.
src/
main.py ← entry point: MY_MODELS, SPREADSHEET_ID, run order
utils.py ← get_html, parse_shutdown_date, calculate_risk_info
checker.py ← check_my_models, Bedrock geo-prefix matching
sheets.py ← Google Sheets export (3 tabs)
database.py ← load/save/merge/cleanup for data/models_db.json
parsers/
__init__.py ← parse_all_deprecations (calls all parsers, deduplicates)
google_gemini.py
openai.py
azure_openai.py
anthropic.py
vertex_ai.py
bedrock.py ← lifecycle page (Active / Legacy / EOL tables)
bedrock_model_cards.py ← model card pages (context window, modalities, etc.)
data/
models_db.json ← persistent model database (auto-created on first run)