vectorplasticity commited on
Commit
ae784de
·
verified ·
1 Parent(s): e1e24cf

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +103 -31
app.py CHANGED
@@ -1,52 +1,124 @@
1
- from flask import Flask, render_template, jsonify, Response
 
 
 
 
 
2
  import requests
3
- from datetime import datetime
4
- import json
5
  from cachetools import TTLCache
 
 
6
 
7
  app = Flask(__name__)
8
- cache = TTLCache(maxsize=10, ttl=10800)
9
 
10
- def get_cached_models():
11
- if 'models' in cache:
12
- return cache['models']
 
 
 
 
 
13
  try:
14
- resp = requests.get('https://openrouter.ai/api/v1/models', timeout=30)
15
- resp.raise_for_status()
16
- data = resp.json().get('data', [])
17
- for m in data:
18
- try:
19
- p = m.get('pricing', {})
20
- m['prompt_cost'] = float(p.get('prompt', 0) or 0)
21
- m['completion_cost'] = float(p.get('completion', 0) or 0)
22
- m['total_cost'] = round(m['prompt_cost'] + m['completion_cost'], 6)
23
- except:
24
- m['prompt_cost'] = m['completion_cost'] = m['total_cost'] = 0
25
- cache['models'] = data
26
- return data
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  except Exception as e:
28
- return cache.get('models', [])
 
29
 
30
  @app.route('/')
31
  def index():
32
- models = get_cached_models()
33
- return render_template('index.html', models=models, count=len(models), updated=datetime.utcnow().strftime('%Y-%m-%d %H:%M UTC'))
 
 
 
 
 
 
 
34
 
35
  @app.route('/api/raw')
36
- def raw_json():
 
 
37
  return Response(
38
- json.dumps(get_cached_models(), indent=4),
39
- mimetype='application/json',
40
- headers={'Content-Disposition': 'inline'}
41
  )
42
 
43
  @app.route('/api/download')
44
- def download_json():
 
 
 
45
  return Response(
46
- json.dumps(get_cached_models(), indent=4),
47
  mimetype='application/json',
48
- headers={'Content-Disposition': 'attachment; filename=openrouter-models.json'}
 
 
49
  )
50
 
 
 
 
 
 
 
 
 
 
 
 
51
  if __name__ == '__main__':
52
- app.run(debug=True)
 
1
+ """
2
+ OpenRouter Models Display SaaS
3
+ A Flask application that fetches and displays all OpenRouter AI models with sorting capabilities.
4
+ """
5
+
6
+ from flask import Flask, jsonify, request, Response, render_template
7
  import requests
 
 
8
  from cachetools import TTLCache
9
+ import json
10
+ from pathlib import Path
11
 
12
  app = Flask(__name__)
 
13
 
14
+ # Cache for 3 hours (10800 seconds)
15
+ models_cache = TTLCache(maxsize=1, ttl=10800)
16
+
17
+ def fetch_models():
18
+ """Fetch models from OpenRouter API with caching."""
19
+ if 'models' in models_cache:
20
+ return models_cache['models']
21
+
22
  try:
23
+ response = requests.get(
24
+ 'https://openrouter.ai/api/v1/models',
25
+ timeout=30
26
+ )
27
+ response.raise_for_status()
28
+ data = response.json()
29
+
30
+ models = []
31
+ for model in data.get('data', []):
32
+ # Parse architecture from model features
33
+ architecture = []
34
+ if model.get('architecture'):
35
+ if model['architecture'].get('modality'):
36
+ arch_str = model['architecture']['modality']
37
+ if 'text->text' in arch_str:
38
+ architecture.append('text')
39
+ if 'image' in arch_str:
40
+ architecture.append('image')
41
+ if 'audio' in arch_str:
42
+ architecture.append('audio')
43
+ if 'video' in arch_str:
44
+ architecture.append('video')
45
+
46
+ if not architecture:
47
+ architecture = ['text']
48
+
49
+ # Get provider from model id
50
+ model_id = model.get('id', '')
51
+ provider = model_id.split('/')[0] if '/' in model_id else 'Unknown'
52
+
53
+ # Get pricing
54
+ pricing = model.get('pricing', {})
55
+ prompt_price = float(pricing.get('prompt', 0)) * 1000000 # Per 1M tokens
56
+ completion_price = float(pricing.get('completion', 0)) * 1000000
57
+
58
+ models.append({
59
+ 'id': model_id,
60
+ 'name': model.get('name', model_id),
61
+ 'provider': provider,
62
+ 'architecture': architecture,
63
+ 'context': model.get('context_length', 0),
64
+ 'prompt_price': prompt_price,
65
+ 'completion_price': completion_price,
66
+ 'description': model.get('description', ''),
67
+ })
68
+
69
+ # Sort by provider, then name
70
+ models.sort(key=lambda x: (x['provider'].lower(), x['name'].lower()))
71
+
72
+ models_cache['models'] = models
73
+ return models
74
  except Exception as e:
75
+ print(f"Error fetching models: {e}")
76
+ return []
77
 
78
  @app.route('/')
79
  def index():
80
+ """Main page with sortable HTML table."""
81
+ models = fetch_models()
82
+ providers = set(m['provider'] for m in models)
83
+
84
+ return render_template(
85
+ 'index.html',
86
+ models=models,
87
+ unique_providers=len(providers)
88
+ )
89
 
90
  @app.route('/api/raw')
91
+ def api_raw():
92
+ """Return raw JSON with indent=4."""
93
+ models = fetch_models()
94
  return Response(
95
+ json.dumps(models, indent=4),
96
+ mimetype='application/json'
 
97
  )
98
 
99
  @app.route('/api/download')
100
+ def api_download():
101
+ """Download JSON file."""
102
+ models = fetch_models()
103
+ json_data = json.dumps(models, indent=4)
104
  return Response(
105
+ json_data,
106
  mimetype='application/json',
107
+ headers={
108
+ 'Content-Disposition': 'attachment; filename=openrouter_models.json'
109
+ }
110
  )
111
 
112
+ @app.route('/api/models')
113
+ def api_models():
114
+ """Standard JSON API endpoint."""
115
+ models = fetch_models()
116
+ return jsonify(models)
117
+
118
+ @app.route('/health')
119
+ def health():
120
+ """Health check endpoint."""
121
+ return jsonify({'status': 'healthy', 'cached': 'models' in models_cache})
122
+
123
  if __name__ == '__main__':
124
+ app.run(host='0.0.0.0', port=7860)