""" OpenRouter Models Display SaaS A Flask application that fetches and displays all OpenRouter AI models with sorting capabilities. """ from flask import Flask, jsonify, request, Response, render_template import requests from cachetools import TTLCache import json from pathlib import Path app = Flask(__name__) # Cache for 3 hours (10800 seconds) models_cache = TTLCache(maxsize=1, ttl=10800) def fetch_models(): """Fetch models from OpenRouter API with caching.""" if 'models' in models_cache: return models_cache['models'] try: response = requests.get( 'https://openrouter.ai/api/v1/models', timeout=30 ) response.raise_for_status() data = response.json() models = [] for model in data.get('data', []): # Parse architecture from model features architecture = [] if model.get('architecture'): if model['architecture'].get('modality'): arch_str = model['architecture']['modality'] if 'text->text' in arch_str: architecture.append('text') if 'image' in arch_str: architecture.append('image') if 'audio' in arch_str: architecture.append('audio') if 'video' in arch_str: architecture.append('video') if not architecture: architecture = ['text'] # Get provider from model id model_id = model.get('id', '') provider = model_id.split('/')[0] if '/' in model_id else 'Unknown' # Get pricing pricing = model.get('pricing', {}) prompt_price = float(pricing.get('prompt', 0)) * 1000000 # Per 1M tokens completion_price = float(pricing.get('completion', 0)) * 1000000 models.append({ 'id': model_id, 'name': model.get('name', model_id), 'provider': provider, 'architecture': architecture, 'context': model.get('context_length', 0), 'prompt_price': prompt_price, 'completion_price': completion_price, 'description': model.get('description', ''), }) # Sort by provider, then name models.sort(key=lambda x: (x['provider'].lower(), x['name'].lower())) models_cache['models'] = models return models except Exception as e: print(f"Error fetching models: {e}") return [] @app.route('/') def index(): """Main page with sortable HTML table.""" models = fetch_models() providers = set(m['provider'] for m in models) return render_template( 'index.html', models=models, unique_providers=len(providers) ) @app.route('/api/raw') def api_raw(): """Return raw JSON with indent=4.""" models = fetch_models() return Response( json.dumps(models, indent=4), mimetype='application/json' ) @app.route('/api/download') def api_download(): """Download JSON file.""" models = fetch_models() json_data = json.dumps(models, indent=4) return Response( json_data, mimetype='application/json', headers={ 'Content-Disposition': 'attachment; filename=openrouter_models.json' } ) @app.route('/api/models') def api_models(): """Standard JSON API endpoint.""" models = fetch_models() return jsonify(models) @app.route('/health') def health(): """Health check endpoint.""" return jsonify({'status': 'healthy', 'cached': 'models' in models_cache}) if __name__ == '__main__': app.run(host='0.0.0.0', port=7860)