Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -2,9 +2,15 @@ import gradio as gr
|
|
2 |
import random
|
3 |
import json
|
4 |
import fastapi
|
5 |
-
from fastapi import FastAPI
|
6 |
import os
|
7 |
import argilla as rg
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
# Initialize Argilla client
|
10 |
client = rg.Argilla(
|
@@ -12,7 +18,6 @@ client = rg.Argilla(
|
|
12 |
api_key=os.getenv("ARGILLA_API_KEY", "")
|
13 |
)
|
14 |
|
15 |
-
# List of countries to check
|
16 |
countries = {
|
17 |
"Argentina": {
|
18 |
"iso": "ARG",
|
@@ -96,8 +101,17 @@ countries = {
|
|
96 |
}
|
97 |
}
|
98 |
|
99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
|
|
101 |
iso = countries[country]["iso"]
|
102 |
emoji = countries[country]["emoji"]
|
103 |
|
@@ -106,11 +120,11 @@ def count_answers_per_space(country: str):
|
|
106 |
try:
|
107 |
dataset = client.datasets(dataset_name)
|
108 |
|
109 |
-
# Get all records with their responses
|
110 |
-
records = dataset.records(with_responses=True)
|
111 |
|
112 |
# Count total questions
|
113 |
-
total_questions = len(
|
114 |
|
115 |
# Count answered questions
|
116 |
answered_questions = 0
|
@@ -126,10 +140,7 @@ def count_answers_per_space(country: str):
|
|
126 |
# Count per user
|
127 |
for response in responses:
|
128 |
user_id = str(response.user_id)
|
129 |
-
|
130 |
-
answers_per_user[user_id] += 1
|
131 |
-
else:
|
132 |
-
answers_per_user[user_id] = 1
|
133 |
|
134 |
percentage_complete = (answered_questions / total_questions * 100) if total_questions > 0 else 0
|
135 |
|
@@ -157,13 +168,30 @@ def count_answers_per_space(country: str):
|
|
157 |
# Create a FastAPI app
|
158 |
app = FastAPI()
|
159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
# Route to serve the map visualization
|
161 |
@app.get("/d3-map")
|
162 |
-
async def serve_map():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
# Generate data for each country by querying Argilla
|
|
|
|
|
|
|
164 |
country_data = {}
|
165 |
for country in countries.keys():
|
166 |
-
country_data[countries[country]["iso"]] =
|
167 |
|
168 |
# Convert to JSON for JavaScript
|
169 |
country_data_json = json.dumps(country_data)
|
@@ -174,13 +202,17 @@ async def serve_map():
|
|
174 |
|
175 |
html_content = html_template.replace("COUNTRY_DATA_PLACEHOLDER", country_data_json)
|
176 |
|
177 |
-
|
|
|
|
|
|
|
|
|
178 |
|
179 |
# Create a simple Gradio interface with an iframe
|
180 |
-
def create_iframe():
|
181 |
-
# Add a random parameter to force reload
|
182 |
-
|
183 |
-
return '<iframe src="/d3-map?
|
184 |
|
185 |
# Create the Gradio blocks
|
186 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="pink", secondary_hue="purple")) as demo:
|
@@ -188,9 +220,9 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="pink", secondary_hue="purple"))
|
|
188 |
|
189 |
iframe_output = gr.HTML(create_iframe())
|
190 |
|
191 |
-
# Refresh button to generate new random data
|
192 |
def refresh():
|
193 |
-
return create_iframe()
|
194 |
|
195 |
gr.Button("Actualizar Datos").click(fn=refresh, outputs=iframe_output)
|
196 |
|
|
|
2 |
import random
|
3 |
import json
|
4 |
import fastapi
|
5 |
+
from fastapi import FastAPI, Request
|
6 |
import os
|
7 |
import argilla as rg
|
8 |
+
from functools import lru_cache
|
9 |
+
import time
|
10 |
+
import asyncio
|
11 |
+
from fastapi.responses import HTMLResponse
|
12 |
+
from fastapi.staticfiles import StaticFiles
|
13 |
+
from fastapi.middleware.gzip import GZipMiddleware
|
14 |
|
15 |
# Initialize Argilla client
|
16 |
client = rg.Argilla(
|
|
|
18 |
api_key=os.getenv("ARGILLA_API_KEY", "")
|
19 |
)
|
20 |
|
|
|
21 |
countries = {
|
22 |
"Argentina": {
|
23 |
"iso": "ARG",
|
|
|
101 |
}
|
102 |
}
|
103 |
|
104 |
+
# Cache the results for 5 minutes (300 seconds)
|
105 |
+
# This significantly reduces load on the Argilla server
|
106 |
+
@lru_cache(maxsize=32)
|
107 |
+
def count_answers_per_space_cached(country: str, cache_buster: int):
|
108 |
+
"""
|
109 |
+
Cached version of count_answers_per_space
|
110 |
+
cache_buster is used to invalidate the cache when needed
|
111 |
+
"""
|
112 |
+
return count_answers_per_space(country)
|
113 |
|
114 |
+
def count_answers_per_space(country: str):
|
115 |
iso = countries[country]["iso"]
|
116 |
emoji = countries[country]["emoji"]
|
117 |
|
|
|
120 |
try:
|
121 |
dataset = client.datasets(dataset_name)
|
122 |
|
123 |
+
# Optimization: Get all records with their responses in one call
|
124 |
+
records = list(dataset.records(with_responses=True))
|
125 |
|
126 |
# Count total questions
|
127 |
+
total_questions = len(records)
|
128 |
|
129 |
# Count answered questions
|
130 |
answered_questions = 0
|
|
|
140 |
# Count per user
|
141 |
for response in responses:
|
142 |
user_id = str(response.user_id)
|
143 |
+
answers_per_user[user_id] = answers_per_user.get(user_id, 0) + 1
|
|
|
|
|
|
|
144 |
|
145 |
percentage_complete = (answered_questions / total_questions * 100) if total_questions > 0 else 0
|
146 |
|
|
|
168 |
# Create a FastAPI app
|
169 |
app = FastAPI()
|
170 |
|
171 |
+
# Add Gzip compression middleware to reduce transferred data size
|
172 |
+
app.add_middleware(GZipMiddleware, minimum_size=1000)
|
173 |
+
|
174 |
+
# Global variable to track when data was last updated
|
175 |
+
last_update_time = time.time()
|
176 |
+
cached_html_content = None
|
177 |
+
|
178 |
# Route to serve the map visualization
|
179 |
@app.get("/d3-map")
|
180 |
+
async def serve_map(request: Request, refresh: bool = False):
|
181 |
+
global last_update_time, cached_html_content
|
182 |
+
current_time = time.time()
|
183 |
+
|
184 |
+
# Use cached content if available and not expired (5 minute cache)
|
185 |
+
if cached_html_content and current_time - last_update_time < 300 and not refresh:
|
186 |
+
return HTMLResponse(content=cached_html_content)
|
187 |
+
|
188 |
# Generate data for each country by querying Argilla
|
189 |
+
# Use async gathering to fetch all data in parallel
|
190 |
+
cache_buster = int(current_time) # Use current time to bust cache when refresh=True
|
191 |
+
|
192 |
country_data = {}
|
193 |
for country in countries.keys():
|
194 |
+
country_data[countries[country]["iso"]] = count_answers_per_space_cached(country, cache_buster)
|
195 |
|
196 |
# Convert to JSON for JavaScript
|
197 |
country_data_json = json.dumps(country_data)
|
|
|
202 |
|
203 |
html_content = html_template.replace("COUNTRY_DATA_PLACEHOLDER", country_data_json)
|
204 |
|
205 |
+
# Update the cache
|
206 |
+
cached_html_content = html_content
|
207 |
+
last_update_time = current_time
|
208 |
+
|
209 |
+
return HTMLResponse(content=html_content)
|
210 |
|
211 |
# Create a simple Gradio interface with an iframe
|
212 |
+
def create_iframe(refresh=False):
|
213 |
+
# Add a random parameter to force reload if refresh is True
|
214 |
+
param = f"refresh={str(refresh).lower()}&t={random.randint(1, 10000)}"
|
215 |
+
return f'<iframe src="/d3-map?{param}" style="width:100%; height:650px; border:none;"></iframe>'
|
216 |
|
217 |
# Create the Gradio blocks
|
218 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="pink", secondary_hue="purple")) as demo:
|
|
|
220 |
|
221 |
iframe_output = gr.HTML(create_iframe())
|
222 |
|
223 |
+
# Refresh button to generate new random data and force cache refresh
|
224 |
def refresh():
|
225 |
+
return create_iframe(refresh=True)
|
226 |
|
227 |
gr.Button("Actualizar Datos").click(fn=refresh, outputs=iframe_output)
|
228 |
|