Chris Addis commited on
Commit ·
4c4fdd7
1
Parent(s): 2f9cb8d
add authentication
Browse files
app.py
CHANGED
|
@@ -20,6 +20,16 @@ from library.utils_prompt import *
|
|
| 20 |
authorized_users_str = os.environ.get("AUTHORIZED_USER_IDS", "")
|
| 21 |
AUTHORIZED_USER_IDS = set(authorized_users_str.split(',') if authorized_users_str and authorized_users_str.strip() else [])
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
#Api sdk
|
| 24 |
OR = OpenRouterAPI()
|
| 25 |
|
|
@@ -39,7 +49,8 @@ MODEL_PRICING = {
|
|
| 39 |
"google/gemini-2.5-flash-preview:thinking": "$0.35",
|
| 40 |
"gpt-4.1-nano": "$0.02",
|
| 41 |
"openai/chatgpt-4o-latest": "$0.75",
|
| 42 |
-
"meta-llama/llama-4-maverick": "$0.04"
|
|
|
|
| 43 |
}
|
| 44 |
|
| 45 |
def get_sys_prompt(length="medium", photograph=False):
|
|
@@ -120,6 +131,23 @@ def create_demo():
|
|
| 120 |
"""
|
| 121 |
# --- Pass css to gr.Blocks ---
|
| 122 |
with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css) as demo:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
with gr.Row():
|
| 124 |
with gr.Column(scale=3):
|
| 125 |
gr.Markdown("# MATCHA: Museum Alt-Text for Cultural Heritage with AI 🍵 🌿")
|
|
@@ -139,7 +167,11 @@ def create_demo():
|
|
| 139 |
# Store model choices and state
|
| 140 |
show_all_models_state = gr.State(False)
|
| 141 |
|
| 142 |
-
# Define
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
preferred_models = [
|
| 144 |
("Gemini 2.0 Flash (cheap)", "google/gemini-2.0-flash-001"),
|
| 145 |
("GPT-4.1 Mini", "gpt-4.1-mini"),
|
|
@@ -155,11 +187,15 @@ def create_demo():
|
|
| 155 |
("Llama 4 Maverick", "meta-llama/llama-4-maverick")
|
| 156 |
]
|
| 157 |
|
| 158 |
-
# Calculate all models
|
| 159 |
all_models_list = preferred_models + additional_models
|
| 160 |
|
| 161 |
-
#
|
| 162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
|
| 164 |
with gr.Row():
|
| 165 |
# Left column: Controls and uploads
|
|
@@ -170,11 +206,25 @@ def create_demo():
|
|
| 170 |
file_count="multiple"
|
| 171 |
)
|
| 172 |
|
| 173 |
-
# Model dropdown
|
| 174 |
model_choice = gr.Dropdown(
|
| 175 |
-
choices=
|
| 176 |
label="Select Model",
|
| 177 |
-
value=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
)
|
| 179 |
|
| 180 |
length_choice = gr.Radio(
|
|
@@ -192,22 +242,37 @@ def create_demo():
|
|
| 192 |
info="Display additional model options in the dropdown above"
|
| 193 |
)
|
| 194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
content_type = gr.Radio(
|
| 196 |
choices=["Museum Object", "Photography"],
|
| 197 |
label="Content Type",
|
| 198 |
value="Museum Object"
|
| 199 |
)
|
| 200 |
|
| 201 |
-
#
|
| 202 |
-
default_model_name = "Unknown Model"
|
| 203 |
-
for name, value in preferred_models:
|
| 204 |
-
if value == default_model:
|
| 205 |
-
default_model_name = name
|
| 206 |
-
break
|
| 207 |
-
|
| 208 |
model_info = gr.Markdown(
|
| 209 |
-
|
| 210 |
-
**Estimated cost per 100 Images**: {MODEL_PRICING[default_model]}""",
|
| 211 |
elem_id="model-info-display"
|
| 212 |
)
|
| 213 |
|
|
@@ -248,31 +313,34 @@ def create_demo():
|
|
| 248 |
all_images = gr.State([])
|
| 249 |
all_results = gr.State([])
|
| 250 |
|
| 251 |
-
# Handle checkbox change to update model dropdown
|
| 252 |
-
def toggle_models(show_all, current_model):
|
| 253 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
preferred_choices = list(preferred_models)
|
| 255 |
all_choices = list(all_models_list)
|
| 256 |
|
| 257 |
if show_all:
|
| 258 |
-
# When showing all models, use the fresh copy of all models
|
| 259 |
return gr.Dropdown(choices=all_choices, value=current_model)
|
| 260 |
else:
|
| 261 |
-
# Check if current model is in preferred models list
|
| 262 |
preferred_values = [value for _, value in preferred_choices]
|
| 263 |
|
| 264 |
if current_model in preferred_values:
|
| 265 |
-
# Keep the current model if it's in preferred models
|
| 266 |
return gr.Dropdown(choices=preferred_choices, value=current_model)
|
| 267 |
else:
|
| 268 |
-
|
| 269 |
-
return gr.Dropdown(choices=preferred_choices, value=default_model)
|
| 270 |
|
| 271 |
# Update model info when model selection changes
|
| 272 |
def update_model_info(model_value):
|
|
|
|
|
|
|
|
|
|
| 273 |
# Find display name
|
| 274 |
model_name = "Unknown Model"
|
| 275 |
-
for name, value in
|
| 276 |
if value == model_value:
|
| 277 |
model_name = name
|
| 278 |
break
|
|
@@ -287,7 +355,7 @@ def create_demo():
|
|
| 287 |
# Connect checkbox to toggle model choices
|
| 288 |
show_all_models.change(
|
| 289 |
fn=toggle_models,
|
| 290 |
-
inputs=[show_all_models, model_choice],
|
| 291 |
outputs=[model_choice]
|
| 292 |
)
|
| 293 |
|
|
@@ -410,37 +478,8 @@ def create_demo():
|
|
| 410 |
""")
|
| 411 |
|
| 412 |
return demo
|
| 413 |
-
|
| 414 |
-
# New function to check if current user is authorized
|
| 415 |
-
def check_authorization(profile: gr.OAuthProfile | None):
|
| 416 |
-
if profile is None:
|
| 417 |
-
return False #"Not logged in. Please Login for full access."
|
| 418 |
-
|
| 419 |
-
if profile.username in AUTHORIZED_USER_IDS:
|
| 420 |
-
return True
|
| 421 |
-
else:
|
| 422 |
-
return False
|
| 423 |
-
|
| 424 |
-
def hello(profile: gr.OAuthProfile | None) -> str:
|
| 425 |
-
if profile is None:
|
| 426 |
-
return "I don't know you."
|
| 427 |
-
return f"Hello {profile.name}"
|
| 428 |
-
|
| 429 |
-
def create_demo_free():
|
| 430 |
-
with gr.Blocks() as demo:
|
| 431 |
-
gr.LoginButton()
|
| 432 |
-
gr.Markdown("Please Login")
|
| 433 |
-
m2 = gr.Markdown()
|
| 434 |
-
m3 = gr.Markdown(f"Authorized User IDs: {', '.join(AUTHORIZED_USER_IDS)}")
|
| 435 |
-
demo.load(hello, inputs=None, outputs=m2)
|
| 436 |
-
m2 = gr.Markdown(str(check_authorization(None)))
|
| 437 |
-
return demo
|
| 438 |
|
| 439 |
# Launch the app
|
| 440 |
if __name__ == "__main__":
|
| 441 |
-
|
| 442 |
-
if check_authorization(profile):
|
| 443 |
-
app = create_demo()
|
| 444 |
-
else:
|
| 445 |
-
app = create_demo_free()
|
| 446 |
app.launch()
|
|
|
|
| 20 |
authorized_users_str = os.environ.get("AUTHORIZED_USER_IDS", "")
|
| 21 |
AUTHORIZED_USER_IDS = set(authorized_users_str.split(',') if authorized_users_str and authorized_users_str.strip() else [])
|
| 22 |
|
| 23 |
+
# Check if current user is authorized
|
| 24 |
+
def check_authorization(profile: gr.OAuthProfile | None):
|
| 25 |
+
if profile is None:
|
| 26 |
+
return False #"Not logged in. Please Login for full access."
|
| 27 |
+
|
| 28 |
+
if profile.username in AUTHORIZED_USER_IDS:
|
| 29 |
+
return True
|
| 30 |
+
else:
|
| 31 |
+
return False
|
| 32 |
+
|
| 33 |
#Api sdk
|
| 34 |
OR = OpenRouterAPI()
|
| 35 |
|
|
|
|
| 49 |
"google/gemini-2.5-flash-preview:thinking": "$0.35",
|
| 50 |
"gpt-4.1-nano": "$0.02",
|
| 51 |
"openai/chatgpt-4o-latest": "$0.75",
|
| 52 |
+
"meta-llama/llama-4-maverick": "$0.04",
|
| 53 |
+
"meta-llama/llama-4-maverick:free": "Free"
|
| 54 |
}
|
| 55 |
|
| 56 |
def get_sys_prompt(length="medium", photograph=False):
|
|
|
|
| 131 |
"""
|
| 132 |
# --- Pass css to gr.Blocks ---
|
| 133 |
with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css) as demo:
|
| 134 |
+
# Store authentication state
|
| 135 |
+
is_authenticated = gr.State(False)
|
| 136 |
+
|
| 137 |
+
# Initialize authentication on app load
|
| 138 |
+
def app_load():
|
| 139 |
+
# Get the OAuth profile (will be None if not logged in)
|
| 140 |
+
profile = getattr(gr.context.get('user', None), 'profile', None)
|
| 141 |
+
# Use the check_authorization function
|
| 142 |
+
return check_authorization(profile)
|
| 143 |
+
|
| 144 |
+
# Update authentication state on load
|
| 145 |
+
demo.load(
|
| 146 |
+
fn=app_load,
|
| 147 |
+
inputs=None,
|
| 148 |
+
outputs=[is_authenticated]
|
| 149 |
+
)
|
| 150 |
+
|
| 151 |
with gr.Row():
|
| 152 |
with gr.Column(scale=3):
|
| 153 |
gr.Markdown("# MATCHA: Museum Alt-Text for Cultural Heritage with AI 🍵 🌿")
|
|
|
|
| 167 |
# Store model choices and state
|
| 168 |
show_all_models_state = gr.State(False)
|
| 169 |
|
| 170 |
+
# Define model lists
|
| 171 |
+
free_model = [
|
| 172 |
+
("Llama 4 Maverick (Free)", "meta-llama/llama-4-maverick:free")
|
| 173 |
+
]
|
| 174 |
+
|
| 175 |
preferred_models = [
|
| 176 |
("Gemini 2.0 Flash (cheap)", "google/gemini-2.0-flash-001"),
|
| 177 |
("GPT-4.1 Mini", "gpt-4.1-mini"),
|
|
|
|
| 187 |
("Llama 4 Maverick", "meta-llama/llama-4-maverick")
|
| 188 |
]
|
| 189 |
|
| 190 |
+
# Calculate all models
|
| 191 |
all_models_list = preferred_models + additional_models
|
| 192 |
|
| 193 |
+
# Function to update model dropdown based on auth status
|
| 194 |
+
def update_model_dropdown(is_auth):
|
| 195 |
+
if is_auth:
|
| 196 |
+
return gr.Dropdown(choices=preferred_models, value="google/gemini-2.0-flash-001")
|
| 197 |
+
else:
|
| 198 |
+
return gr.Dropdown(choices=free_model, value="meta-llama/llama-4-maverick:free")
|
| 199 |
|
| 200 |
with gr.Row():
|
| 201 |
# Left column: Controls and uploads
|
|
|
|
| 206 |
file_count="multiple"
|
| 207 |
)
|
| 208 |
|
| 209 |
+
# Model dropdown - initially empty, will be populated based on auth status
|
| 210 |
model_choice = gr.Dropdown(
|
| 211 |
+
choices=[],
|
| 212 |
label="Select Model",
|
| 213 |
+
value=None
|
| 214 |
+
)
|
| 215 |
+
|
| 216 |
+
# Update the model dropdown when authentication state changes
|
| 217 |
+
is_authenticated.change(
|
| 218 |
+
fn=update_model_dropdown,
|
| 219 |
+
inputs=[is_authenticated],
|
| 220 |
+
outputs=[model_choice]
|
| 221 |
+
)
|
| 222 |
+
|
| 223 |
+
# Also update model dropdown on initial load
|
| 224 |
+
demo.load(
|
| 225 |
+
fn=update_model_dropdown,
|
| 226 |
+
inputs=[is_authenticated],
|
| 227 |
+
outputs=[model_choice]
|
| 228 |
)
|
| 229 |
|
| 230 |
length_choice = gr.Radio(
|
|
|
|
| 242 |
info="Display additional model options in the dropdown above"
|
| 243 |
)
|
| 244 |
|
| 245 |
+
# Update checkbox interactivity based on auth status
|
| 246 |
+
def update_checkbox_interactive(is_auth):
|
| 247 |
+
return gr.Checkbox(
|
| 248 |
+
label="Show Additional Models",
|
| 249 |
+
value=False,
|
| 250 |
+
info="Display additional model options in the dropdown above",
|
| 251 |
+
interactive=is_auth
|
| 252 |
+
)
|
| 253 |
+
|
| 254 |
+
is_authenticated.change(
|
| 255 |
+
fn=update_checkbox_interactive,
|
| 256 |
+
inputs=[is_authenticated],
|
| 257 |
+
outputs=[show_all_models]
|
| 258 |
+
)
|
| 259 |
+
|
| 260 |
+
# Also update checkbox interactivity on initial load
|
| 261 |
+
demo.load(
|
| 262 |
+
fn=update_checkbox_interactive,
|
| 263 |
+
inputs=[is_authenticated],
|
| 264 |
+
outputs=[show_all_models]
|
| 265 |
+
)
|
| 266 |
+
|
| 267 |
content_type = gr.Radio(
|
| 268 |
choices=["Museum Object", "Photography"],
|
| 269 |
label="Content Type",
|
| 270 |
value="Museum Object"
|
| 271 |
)
|
| 272 |
|
| 273 |
+
# Model info display
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 274 |
model_info = gr.Markdown(
|
| 275 |
+
"**Select a model to see information**",
|
|
|
|
| 276 |
elem_id="model-info-display"
|
| 277 |
)
|
| 278 |
|
|
|
|
| 313 |
all_images = gr.State([])
|
| 314 |
all_results = gr.State([])
|
| 315 |
|
| 316 |
+
# Handle checkbox change to update model dropdown
|
| 317 |
+
def toggle_models(show_all, current_model, is_auth):
|
| 318 |
+
if not is_auth:
|
| 319 |
+
# Non-authenticated users only get free model
|
| 320 |
+
return gr.Dropdown(choices=free_model, value="meta-llama/llama-4-maverick:free")
|
| 321 |
+
|
| 322 |
+
# For authenticated users, existing logic
|
| 323 |
preferred_choices = list(preferred_models)
|
| 324 |
all_choices = list(all_models_list)
|
| 325 |
|
| 326 |
if show_all:
|
|
|
|
| 327 |
return gr.Dropdown(choices=all_choices, value=current_model)
|
| 328 |
else:
|
|
|
|
| 329 |
preferred_values = [value for _, value in preferred_choices]
|
| 330 |
|
| 331 |
if current_model in preferred_values:
|
|
|
|
| 332 |
return gr.Dropdown(choices=preferred_choices, value=current_model)
|
| 333 |
else:
|
| 334 |
+
return gr.Dropdown(choices=preferred_choices, value="google/gemini-2.0-flash-001")
|
|
|
|
| 335 |
|
| 336 |
# Update model info when model selection changes
|
| 337 |
def update_model_info(model_value):
|
| 338 |
+
# Combine all model lists for lookup
|
| 339 |
+
combined_models = preferred_models + additional_models + free_model
|
| 340 |
+
|
| 341 |
# Find display name
|
| 342 |
model_name = "Unknown Model"
|
| 343 |
+
for name, value in combined_models:
|
| 344 |
if value == model_value:
|
| 345 |
model_name = name
|
| 346 |
break
|
|
|
|
| 355 |
# Connect checkbox to toggle model choices
|
| 356 |
show_all_models.change(
|
| 357 |
fn=toggle_models,
|
| 358 |
+
inputs=[show_all_models, model_choice, is_authenticated],
|
| 359 |
outputs=[model_choice]
|
| 360 |
)
|
| 361 |
|
|
|
|
| 478 |
""")
|
| 479 |
|
| 480 |
return demo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 481 |
|
| 482 |
# Launch the app
|
| 483 |
if __name__ == "__main__":
|
| 484 |
+
app = create_demo()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 485 |
app.launch()
|