justadri23 commited on
Commit
54cf7c2
·
verified ·
1 Parent(s): 38a9b9a

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -48
app.py CHANGED
@@ -24,18 +24,33 @@ active_keys = []
24
  revoked_keys = []
25
 
26
  def verify_api_key(api_key):
27
- """Verifica si una clave API de Gemini es válida."""
28
  try:
29
  # Configurar temporalmente con esta clave
30
  genai.configure(api_key=api_key)
31
 
32
- # Intentar una solicitud simple
 
33
  model = genai.GenerativeModel("gemini-pro")
34
- response = model.generate_content("Hello, this is a test.")
 
 
 
 
35
 
36
  # Si llegamos aquí, la clave es válida
 
 
37
  return True
38
  except Exception as e:
 
 
 
 
 
 
 
 
39
  logger.warning(f"Clave API inválida: {str(e)}")
40
  return False
41
 
@@ -52,14 +67,19 @@ def initialize_api_keys():
52
 
53
  logger.info(f"Verificando {len(api_keys)} claves API...")
54
 
55
- # Verificar cada clave API
56
- for key in api_keys:
 
57
  if verify_api_key(key):
58
  active_keys.append(key)
59
- logger.info(f"Clave API verificada con éxito")
60
  else:
61
  revoked_keys.append(key)
62
- logger.warning(f"Clave API inválida o revocada")
 
 
 
 
63
 
64
  if not active_keys:
65
  logger.warning("No hay claves API válidas disponibles. El servidor se iniciará pero los endpoints no funcionarán.")
@@ -87,7 +107,7 @@ def get_current_api_key():
87
 
88
  return current_key
89
 
90
- # Plantilla HTML para la página de estado
91
  STATUS_PAGE_TEMPLATE = """
92
  <!DOCTYPE html>
93
  <html>
@@ -95,62 +115,117 @@ STATUS_PAGE_TEMPLATE = """
95
  <title>Gemini Proxy Status</title>
96
  <style>
97
  body {
98
- font-family: Arial, sans-serif;
99
- max-width: 800px;
100
- margin: 0 auto;
101
  padding: 20px;
 
 
 
102
  }
103
- h1 {
104
- color: #333;
 
105
  }
106
- .status-card {
107
- background-color: #f5f5f5;
108
- border-radius: 8px;
109
- padding: 20px;
110
- margin-top: 20px;
111
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  }
113
- .status-info {
114
- font-family: monospace;
115
- font-size: 16px;
116
- white-space: pre;
117
- padding: 15px;
118
- background-color: #fff;
119
- border-radius: 4px;
120
- border: 1px solid #ddd;
121
  }
122
- .status-warning {
123
- margin-top: 15px;
124
- padding: 15px;
125
- background-color: #fff3cd;
126
- border-radius: 4px;
127
- border: 1px solid #ffeeba;
128
- color: #856404;
129
  }
130
- .footer {
131
- margin-top: 30px;
132
- color: #666;
133
- font-size: 14px;
 
 
 
134
  }
135
  </style>
136
  </head>
137
  <body>
138
- <h1>Gemini Proxy Status</h1>
139
- <div class="status-card">
140
- <div class="status-info">Gemini Status: {
 
 
 
 
 
141
  activeKeys: {{ active_keys }},
142
  revokedKeys: {{ revoked_keys }}
143
  }</div>
144
  {% if active_keys == 0 %}
145
- <div class="status-warning">
146
- <strong>⚠️ Advertencia:</strong> No hay claves API activas disponibles.
147
- Los endpoints no funcionarán hasta que configures al menos una clave API válida de Gemini.
148
- Edita el archivo .env y añade tus claves API.
149
- </div>
150
  {% endif %}
151
  </div>
152
- <div class="footer">
153
- <p>Proxy funcionando en {{ host }}:{{ port }}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  </div>
155
  </body>
156
  </html>
 
24
  revoked_keys = []
25
 
26
  def verify_api_key(api_key):
27
+ """Verifica si una clave API de Gemini es válida de manera moderada para evitar rate limits."""
28
  try:
29
  # Configurar temporalmente con esta clave
30
  genai.configure(api_key=api_key)
31
 
32
+ # Intentar una solicitud simple y ligera
33
+ # Usamos una solicitud mínima para evitar consumir cuota innecesariamente
34
  model = genai.GenerativeModel("gemini-pro")
35
+ response = model.generate_content("test",
36
+ generation_config={
37
+ "max_output_tokens": 5,
38
+ "temperature": 0
39
+ })
40
 
41
  # Si llegamos aquí, la clave es válida
42
+ # Esperamos un breve momento para evitar rate limits
43
+ time.sleep(1)
44
  return True
45
  except Exception as e:
46
+ error_str = str(e).lower()
47
+ # Detectar específicamente errores de rate limit
48
+ if "rate limit" in error_str or "quota" in error_str:
49
+ logger.warning(f"Rate limit detectado durante verificación: {str(e)}")
50
+ # Asumimos que la clave es válida pero está limitada temporalmente
51
+ time.sleep(2) # Esperamos más tiempo en caso de rate limit
52
+ return True
53
+
54
  logger.warning(f"Clave API inválida: {str(e)}")
55
  return False
56
 
 
67
 
68
  logger.info(f"Verificando {len(api_keys)} claves API...")
69
 
70
+ # Verificar cada clave API con una pausa entre verificaciones
71
+ for i, key in enumerate(api_keys):
72
+ logger.info(f"Verificando clave API {i+1} de {len(api_keys)}...")
73
  if verify_api_key(key):
74
  active_keys.append(key)
75
+ logger.info(f"Clave API {i+1} verificada con éxito")
76
  else:
77
  revoked_keys.append(key)
78
+ logger.warning(f"Clave API {i+1} inválida o revocada")
79
+
80
+ # Pausa entre verificaciones para evitar rate limits
81
+ if i < len(api_keys) - 1:
82
+ time.sleep(2)
83
 
84
  if not active_keys:
85
  logger.warning("No hay claves API válidas disponibles. El servidor se iniciará pero los endpoints no funcionarán.")
 
107
 
108
  return current_key
109
 
110
+ # Plantilla HTML para la página de estado con estilo de terminal
111
  STATUS_PAGE_TEMPLATE = """
112
  <!DOCTYPE html>
113
  <html>
 
115
  <title>Gemini Proxy Status</title>
116
  <style>
117
  body {
118
+ background-color: #111;
119
+ color: #0f0;
120
+ font-family: 'Courier New', monospace;
121
  padding: 20px;
122
+ max-width: 900px;
123
+ margin: 0 auto;
124
+ line-height: 1.4;
125
  }
126
+ a {
127
+ color: #0f0;
128
+ text-decoration: underline;
129
  }
130
+ .terminal-header {
131
+ margin-bottom: 20px;
132
+ border-bottom: 1px dashed #0f0;
133
+ padding-bottom: 10px;
134
+ }
135
+ .terminal-prompt::before {
136
+ content: "$ ";
137
+ }
138
+ .terminal-prompt {
139
+ white-space: nowrap;
140
+ overflow: hidden;
141
+ border-right: 5px solid #0f0;
142
+ animation: terminal-cursor 1s step-end infinite;
143
+ }
144
+ @keyframes terminal-cursor {
145
+ 0%, 100% { border-color: #0f0; }
146
+ 50% { border-color: transparent; }
147
+ }
148
+ .terminal-output {
149
+ margin: 15px 0;
150
+ padding-left: 15px;
151
+ border-left: 2px solid #0a0;
152
+ white-space: pre-wrap;
153
+ }
154
+ .terminal-section {
155
+ margin-bottom: 25px;
156
+ }
157
+ .warning {
158
+ color: #ff0;
159
  }
160
+ .error {
161
+ color: #f00;
 
 
 
 
 
 
162
  }
163
+ .url {
164
+ text-decoration: underline;
165
+ color: #0ff;
 
 
 
 
166
  }
167
+ .method {
168
+ font-weight: bold;
169
+ color: #f0f;
170
+ }
171
+ .comment {
172
+ color: #777;
173
+ font-style: italic;
174
  }
175
  </style>
176
  </head>
177
  <body>
178
+ <div class="terminal-header">
179
+ <h1 style="margin-top:0;">GEMINI PROXY</h1>
180
+ </div>
181
+
182
+ <div class="terminal-section">
183
+ <div class="terminal-prompt">status</div>
184
+ <div class="terminal-output">{
185
+ host: "{{ host }}:{{ port }}",
186
  activeKeys: {{ active_keys }},
187
  revokedKeys: {{ revoked_keys }}
188
  }</div>
189
  {% if active_keys == 0 %}
190
+ <div class="terminal-output error">[ERROR] No hay claves API activas. Los endpoints no funcionarán.</div>
 
 
 
 
191
  {% endif %}
192
  </div>
193
+
194
+ <div class="terminal-section">
195
+ <div class="terminal-prompt">endpoints --list</div>
196
+ <div class="terminal-output"><span class="comment"># Compatible con OpenAI</span>
197
+ <span class="method">POST</span> http://{{ host }}:{{ port }}/v1/chat/completions
198
+ <span class="method">POST</span> http://{{ host }}:{{ port }}/v1/embeddings
199
+ <span class="method">GET</span> http://{{ host }}:{{ port }}/v1/models
200
+
201
+ <span class="comment"># API Nativa de Gemini</span>
202
+ <span class="method">POST</span> http://{{ host }}:{{ port }}/gemini/v1/models/{model_id}:generateContent
203
+ <span class="method">POST</span> http://{{ host }}:{{ port }}/gemini/v1/models/{model_id}:embedContent
204
+ <span class="method">GET</span> http://{{ host }}:{{ port }}/gemini/v1/models</div>
205
+ </div>
206
+
207
+ <div class="terminal-section">
208
+ <div class="terminal-prompt">models --list</div>
209
+ <div class="terminal-output">gemini-pro
210
+ gemini-pro-vision
211
+ gemini-2.5-pro-exp-03-25
212
+ gemini-2.0-flash
213
+ gemini-2.0-flash-lite
214
+ gemini-1.5-flash
215
+ gemini-1.5-flash-8b
216
+ gemini-1.5-pro
217
+ gemini-embedding-exp</div>
218
+ </div>
219
+
220
+ <div class="terminal-section">
221
+ <div class="terminal-prompt">help</div>
222
+ <div class="terminal-output"><span class="comment"># Este es un proxy de API para Gemini que proporciona compatibilidad con OpenAI
223
+ # Los endpoints están listados arriba
224
+ # Para más información, consulta el README.md</span></div>
225
+ </div>
226
+
227
+ <div style="margin-top: 40px; opacity: 0.6">
228
+ Gemini Proxy v1.0.0 [Running on {{ host }}:{{ port }}] (c) 2024
229
  </div>
230
  </body>
231
  </html>