sccastillo commited on
Commit
cc16e90
·
1 Parent(s): 4449ca6

Add OpenAI integration and interactive AI interface

Browse files

✨ Features added:
- OpenAI LLM integration using langchain
- Interactive web interface for asking questions
- New endpoint: POST /api/generate for AI responses
- Enhanced health check with OpenAI status
- Added required dependencies (langchain, langchain-openai, python-dotenv)

🔧 Improvements:
- Beautiful interactive UI with JavaScript
- Real-time question/answer functionality
- Error handling for missing API key
- Complete setup instructions in SETUP.md

📚 Based on router.py example with simplification for direct integration

Files changed (3) hide show
  1. SETUP.md +53 -0
  2. app.py +131 -4
  3. requirements.txt +4 -0
SETUP.md ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Configuración de SciResearch API
2
+
3
+ ## 🔑 Configurar OpenAI API Key
4
+
5
+ Para que la funcionalidad de IA funcione correctamente, necesitas configurar tu API key de OpenAI:
6
+
7
+ ### Para uso local:
8
+ 1. Crea un archivo `.env` en la raíz del proyecto
9
+ 2. Agrega tu API key de OpenAI:
10
+ ```
11
+ OPENAI_API_KEY=tu_api_key_aqui
12
+ ```
13
+
14
+ ### Para Hugging Face Spaces:
15
+ 1. Ve a tu Space: https://huggingface.co/spaces/sccastillo/sciresearch
16
+ 2. Haz clic en "Settings"
17
+ 3. Ve a la sección "Variables and secrets"
18
+ 4. Agrega una nueva variable:
19
+ - **Name**: `OPENAI_API_KEY`
20
+ - **Value**: Tu API key de OpenAI (sk-...)
21
+
22
+ ## 🚀 Características
23
+
24
+ - **Interfaz web interactiva**: Pregunta directamente en la página principal
25
+ - **API REST**: Endpoint `/api/generate` para integración
26
+ - **Respuestas inteligentes**: Usa OpenAI para responder preguntas
27
+ - **Documentación automática**: Disponible en `/docs`
28
+
29
+ ## 📝 Endpoints disponibles:
30
+
31
+ - `GET /` - Página principal con interfaz interactiva
32
+ - `POST /api/generate` - Generar respuestas con IA
33
+ - `GET /api/health` - Estado de la aplicación
34
+ - `GET /docs` - Documentación Swagger UI
35
+
36
+ ## 🧪 Ejemplo de uso con curl:
37
+
38
+ ```bash
39
+ curl -X POST "https://sccastillo-sciresearch.hf.space/api/generate" \
40
+ -H "Content-Type: application/json" \
41
+ -d '{"question": "¿Qué es la inteligencia artificial?"}'
42
+ ```
43
+
44
+ ## 📁 Estructura del proyecto:
45
+
46
+ ```
47
+ sciresearch/
48
+ ├── app.py # Aplicación principal con OpenAI
49
+ ├── requirements.txt # Dependencias
50
+ ├── Dockerfile # Configuración Docker
51
+ ├── README.md # Metadatos de HF Spaces
52
+ └── SETUP.md # Este archivo
53
+ ```
app.py CHANGED
@@ -1,13 +1,70 @@
1
- from fastapi import FastAPI
 
2
  from fastapi.responses import HTMLResponse
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  # Crear la aplicación FastAPI
5
  app = FastAPI(
6
  title="SciResearch API",
7
- description="Scientific Research FastAPI application on Hugging Face Spaces",
8
  version="1.0.0"
9
  )
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  @app.get("/", response_class=HTMLResponse)
12
  def read_root():
13
  """
@@ -22,19 +79,75 @@ def read_root():
22
  body { font-family: Arial, sans-serif; margin: 40px; }
23
  h1 { color: #333; }
24
  .container { max-width: 600px; margin: 0 auto; }
 
 
 
 
 
25
  </style>
26
  </head>
27
  <body>
28
  <div class="container">
29
  <h1>🦀 SciResearch API</h1>
30
- <p>¡Bienvenido a la aplicación de investigación científica!</p>
 
 
 
 
 
 
 
 
 
 
 
 
31
  <h2>Endpoints disponibles:</h2>
32
  <ul>
33
  <li><a href="/docs">/docs</a> - Documentación interactiva de la API</li>
34
  <li><a href="/api/hello">/api/hello</a> - Saludo JSON</li>
35
  <li><a href="/api/health">/api/health</a> - Estado de la aplicación</li>
 
36
  </ul>
37
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  </body>
39
  </html>
40
  """
@@ -52,4 +165,18 @@ def health_check():
52
  """
53
  Endpoint para verificar el estado de la aplicación
54
  """
55
- return {"status": "healthy", "service": "sciresearch", "version": "1.0.0"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from fastapi import FastAPI, HTTPException
3
  from fastapi.responses import HTMLResponse
4
+ from pydantic import BaseModel
5
+ from dotenv import load_dotenv
6
+
7
+ # Importar dependencias de LangChain y OpenAI
8
+ from langchain_openai import OpenAI
9
+ from langchain.chains import LLMChain
10
+ from langchain.prompts import PromptTemplate
11
+
12
+ # Cargar variables de entorno
13
+ load_dotenv()
14
+
15
+ # Modelos Pydantic
16
+ class QuestionRequest(BaseModel):
17
+ question: str
18
+
19
+ class GenerateResponse(BaseModel):
20
+ text: str
21
+ status: str = "success"
22
 
23
  # Crear la aplicación FastAPI
24
  app = FastAPI(
25
  title="SciResearch API",
26
+ description="Scientific Research FastAPI application with OpenAI integration on Hugging Face Spaces",
27
  version="1.0.0"
28
  )
29
 
30
+ def answer_question(question: str):
31
+ """
32
+ Función para responder preguntas usando OpenAI LLM
33
+ """
34
+ if not question or question.strip() == "":
35
+ raise HTTPException(status_code=400, detail="Please provide a question.")
36
+
37
+ # Obtener API key de OpenAI desde variables de entorno
38
+ openai_api_key = os.getenv("OPENAI_API_KEY")
39
+ if not openai_api_key or openai_api_key == "your_openai_api_key_here":
40
+ raise HTTPException(status_code=500, detail="OpenAI API key not configured")
41
+
42
+ # Template simple para responder preguntas
43
+ prompt_template = PromptTemplate(
44
+ template="Answer the following question clearly and concisely: {question}",
45
+ input_variables=["question"]
46
+ )
47
+
48
+ # Inicializar OpenAI LLM
49
+ try:
50
+ llm = OpenAI(
51
+ api_key=openai_api_key,
52
+ temperature=0.7
53
+ )
54
+
55
+ # Crear cadena LLM
56
+ llm_chain = LLMChain(
57
+ prompt=prompt_template,
58
+ llm=llm
59
+ )
60
+
61
+ # Generar respuesta
62
+ response = llm_chain.run(question=question)
63
+ return GenerateResponse(text=response.strip())
64
+
65
+ except Exception as e:
66
+ raise HTTPException(status_code=500, detail=f"Error generating response: {str(e)}")
67
+
68
  @app.get("/", response_class=HTMLResponse)
69
  def read_root():
70
  """
 
79
  body { font-family: Arial, sans-serif; margin: 40px; }
80
  h1 { color: #333; }
81
  .container { max-width: 600px; margin: 0 auto; }
82
+ .form-group { margin: 20px 0; }
83
+ input[type="text"] { width: 100%; padding: 10px; margin: 5px 0; }
84
+ button { background-color: #4CAF50; color: white; padding: 10px 20px; border: none; cursor: pointer; }
85
+ button:hover { background-color: #45a049; }
86
+ #response { background-color: #f9f9f9; padding: 15px; margin-top: 20px; border-left: 4px solid #4CAF50; }
87
  </style>
88
  </head>
89
  <body>
90
  <div class="container">
91
  <h1>🦀 SciResearch API</h1>
92
+ <p>¡Bienvenido a la aplicación de investigación científica con IA!</p>
93
+
94
+ <div class="form-group">
95
+ <h3>Pregunta a la IA:</h3>
96
+ <input type="text" id="question" placeholder="Escribe tu pregunta aquí..." />
97
+ <button onclick="askQuestion()">Preguntar</button>
98
+ </div>
99
+
100
+ <div id="response" style="display:none;">
101
+ <h4>Respuesta:</h4>
102
+ <p id="answer"></p>
103
+ </div>
104
+
105
  <h2>Endpoints disponibles:</h2>
106
  <ul>
107
  <li><a href="/docs">/docs</a> - Documentación interactiva de la API</li>
108
  <li><a href="/api/hello">/api/hello</a> - Saludo JSON</li>
109
  <li><a href="/api/health">/api/health</a> - Estado de la aplicación</li>
110
+ <li><strong>/api/generate</strong> - Generar respuestas con IA (POST)</li>
111
  </ul>
112
  </div>
113
+
114
+ <script>
115
+ async function askQuestion() {
116
+ const question = document.getElementById('question').value;
117
+ if (!question.trim()) {
118
+ alert('Por favor escribe una pregunta');
119
+ return;
120
+ }
121
+
122
+ try {
123
+ const response = await fetch('/api/generate', {
124
+ method: 'POST',
125
+ headers: {
126
+ 'Content-Type': 'application/json',
127
+ },
128
+ body: JSON.stringify({question: question})
129
+ });
130
+
131
+ const data = await response.json();
132
+
133
+ if (response.ok) {
134
+ document.getElementById('answer').textContent = data.text;
135
+ document.getElementById('response').style.display = 'block';
136
+ } else {
137
+ alert('Error: ' + data.detail);
138
+ }
139
+ } catch (error) {
140
+ alert('Error de conexión: ' + error.message);
141
+ }
142
+ }
143
+
144
+ // Permitir envío con Enter
145
+ document.getElementById('question').addEventListener('keypress', function(e) {
146
+ if (e.key === 'Enter') {
147
+ askQuestion();
148
+ }
149
+ });
150
+ </script>
151
  </body>
152
  </html>
153
  """
 
165
  """
166
  Endpoint para verificar el estado de la aplicación
167
  """
168
+ openai_configured = bool(os.getenv("OPENAI_API_KEY")) and os.getenv("OPENAI_API_KEY") != "your_openai_api_key_here"
169
+
170
+ return {
171
+ "status": "healthy",
172
+ "service": "sciresearch",
173
+ "version": "1.0.0",
174
+ "openai_configured": openai_configured
175
+ }
176
+
177
+ @app.post("/api/generate", summary="Answer user questions using OpenAI", tags=["AI Generate"], response_model=GenerateResponse)
178
+ def inference(request: QuestionRequest):
179
+ """
180
+ Endpoint para generar respuestas a preguntas usando OpenAI LLM
181
+ """
182
+ return answer_question(question=request.question)
requirements.txt CHANGED
@@ -1,2 +1,6 @@
1
  fastapi
2
  uvicorn[standard]
 
 
 
 
 
1
  fastapi
2
  uvicorn[standard]
3
+ langchain
4
+ langchain-openai
5
+ python-dotenv
6
+ pydantic