""" Module d'authentification pour l'application de scoring Gère l'authentification par mot de passe et l'identification des annotateurs """ import streamlit as st import os import warnings # Supprimer les warnings de secrets manquants warnings.filterwarnings('ignore', message='.*secrets.*') def check_password(): """ Vérifie que l'utilisateur a le bon mot de passe. Returns True si authentifié, False sinon. """ def password_entered(): """Vérifie si le mot de passe est correct""" # Support pour secrets (HF Spaces) ou variable d'environnement correct_password = None # Essayer d'abord st.secrets (HF Spaces) - sans message d'erreur try: correct_password = st.secrets.get("APP_PASSWORD") except: pass # Fallback sur variable d'environnement if not correct_password: correct_password = os.getenv("APP_PASSWORD") # Fallback sur mot de passe par défaut if not correct_password: correct_password = "annotator2025" if st.session_state["password"] == correct_password: st.session_state["password_correct"] = True del st.session_state["password"] # Ne pas garder le mot de passe en clair else: st.session_state["password_correct"] = False # Premier affichage ou non authentifié if "password_correct" not in st.session_state: st.markdown("## 🔐 Authentification Annotateur") st.info("Entrez le mot de passe fourni par l'équipe de recherche") st.text_input( "Mot de passe", type="password", on_change=password_entered, key="password", label_visibility="collapsed" ) return False elif not st.session_state["password_correct"]: st.markdown("## 🔐 Authentification Annotateur") st.text_input( "Mot de passe", type="password", on_change=password_entered, key="password", label_visibility="collapsed" ) st.error("❌ Mot de passe incorrect") return False else: # Authentifié return True def get_annotator_identity(): """ Récupère ou demande l'identité de l'annotateur. Returns: (annotator_id, annotator_name) ou None si non défini """ if "annotator_id" not in st.session_state: st.session_state.annotator_id = None st.session_state.annotator_name = None return st.session_state.annotator_id, st.session_state.annotator_name def set_annotator_identity(annotator_id, annotator_name): """ Définit l'identité de l'annotateur dans la session """ st.session_state.annotator_id = annotator_id st.session_state.annotator_name = annotator_name def show_annotator_selector(annotator_config): """ Affiche un sélecteur d'annotateur basé sur la configuration. Args: annotator_config: Dict avec la configuration des annotateurs Format: { "annotator_1": { "name": "Expert A", "start_idx": 0, "end_idx": 100 }, ... } Returns: (annotator_id, config) ou (None, None) si pas sélectionné """ st.markdown("## 👤 Sélection de l'annotateur") st.info("Sélectionnez votre identifiant pour charger votre portion du dataset") # Créer la liste des options options = ["-- Choisissez votre identifiant --"] annotator_mapping = {} for ann_id, ann_config in annotator_config.items(): display_name = f"{ann_config['name']} (Items {ann_config['start_idx']}-{ann_config['end_idx']})" options.append(display_name) annotator_mapping[display_name] = (ann_id, ann_config) selected = st.selectbox( "Annotateur", options, key="annotator_selector", label_visibility="collapsed" ) if selected == options[0]: return None, None annotator_id, config = annotator_mapping[selected] # Afficher un résumé st.success(f""" ✅ **{config['name']}** - Items à annoter: {config['end_idx'] - config['start_idx']} - Range: [{config['start_idx']}, {config['end_idx']}[ """) if st.button("Confirmer et continuer", type="primary", use_container_width=True): set_annotator_identity(annotator_id, config['name']) return annotator_id, config return None, None