"""General helper utilities for authentication, policy loading, and file operations.""" import os import gradio as gr from dotenv import load_dotenv def get_personal_token(oauth_token: gr.OAuthToken | None) -> tuple[str | None, str]: """ Get personal Hugging Face token from OAuth or .env fallback. Used for personal/user operations like saving to private datasets. Args: oauth_token: Gradio OAuth token from user login, or None Returns: Tuple of (hf_token, status_message) - hf_token: Token string if available, None otherwise - status_message: Warning message if using local .env, empty string otherwise """ print(f"DEBUG: get_personal_token called with oauth_token type: {type(oauth_token)}") if oauth_token is None or (isinstance(oauth_token, str) and oauth_token == "Log in to Hugging Face"): # Try loading from .env file print("DEBUG: oauth_token is None, loading from .env") load_dotenv() hf_token = os.getenv("HF_TOKEN_MLSOC") if hf_token is None: print("DEBUG: HF_TOKEN_MLSOC not found in .env") return None, "" else: print(f"DEBUG: Loaded token from .env, length: {len(hf_token)}, first 4 chars: {hf_token[:4] if len(hf_token) >= 4 else hf_token}") return hf_token, "\n⚠️ Using local .env file for token (not online)" else: # OAuthToken object print(f"DEBUG: oauth_token is OAuthToken object") token = oauth_token.token print(f"DEBUG: Extracted token from OAuthToken, length: {len(token) if token else 0}, first 4 chars: {token[:4] if token and len(token) >= 4 else (token if token else 'None')}") if not token or not token.strip(): print("DEBUG: OAuthToken.token is empty, falling back to .env") load_dotenv() hf_token = os.getenv("HF_TOKEN_MLSOC") if hf_token: print(f"DEBUG: Loaded token from .env (empty OAuth case), length: {len(hf_token)}, first 4 chars: {hf_token[:4] if len(hf_token) >= 4 else hf_token}") return hf_token, "\n⚠️ Using local .env file for token (not online)" return None, "" return token, "" def get_org_token() -> str | None: """ Get organization token from Space secret or .env fallback. Used for ROOST org dataset operations and inference (preferred). Returns: Token string if available, None otherwise """ # Check Space secret HACKATHON_INFERENCE_TOKEN org_token = os.getenv("HACKATHON_INFERENCE_TOKEN") if org_token: return org_token # Fall back to .env file load_dotenv() org_token = os.getenv("ROOST_TOKEN_FALLBACK") if org_token: return org_token return None def get_inference_token(oauth_token: gr.OAuthToken | None) -> tuple[str | None, str]: """ Get token for inference (org token preferred, falls back to personal). Returns: Tuple of (token, status_message) """ # Try org token first org_token = get_org_token() if org_token: return org_token, "" # Fall back to personal token personal_token, status_msg = get_personal_token(oauth_token) return personal_token, status_msg def check_token_availability(oauth_token: gr.OAuthToken | None) -> tuple[bool, bool]: """ Check which tokens are available. Returns: Tuple of (has_personal: bool, has_org: bool) """ has_personal = get_personal_token(oauth_token)[0] is not None has_org = get_org_token() is not None return has_personal, has_org def format_token_status(oauth_token: gr.OAuthToken | None) -> str: """ Format markdown showing token status and usage. Returns: Markdown string explaining which tokens are set and their uses """ has_personal, has_org = check_token_availability(oauth_token) lines = [ "You can log in to yout Hugging Face account to save your work in a private dataset and use the app for inference after the end of the hackathon.", "### Token Status", ] # Personal token status if has_personal: personal_token, status_msg = get_personal_token(oauth_token) if oauth_token and oauth_token.token: source = "OAuth login" else: source = ".env file" lines.append(f"- **Personal Token**: ✅ Available ({source})") lines.append(" - Enables: Inference (fallback), Private dataset saves/loads") else: lines.append("- **Personal Token**: ❌ Not available") lines.append(" - Required for: Private dataset operations") # Org token status if has_org: org_token = get_org_token() # Check if it's from Space secret or .env if os.getenv("HACKATHON_INFERENCE_TOKEN"): source = "Space secret" else: source = ".env file" lines.append(f"- **Org Token**: ✅ Available ({source})") lines.append(" - Enables: Inference (preferred), ROOST dataset saves/loads") else: lines.append("- **Org Token**: ❌ Not available") lines.append(" - Required for: ROOST dataset saves") lines.append(" - Note: ROOST dataset can be loaded if public") return "\n".join(lines) def load_preset_policy(preset_name: str, base_dir: str) -> tuple[str, str]: """Load preset policy from markdown file.""" preset_files = { "Hate Speech Policy": "hate_speech.md", "Violence Policy": "violence.md", "Toxicity Policy": "toxicity.md", } if preset_name in preset_files: policy_path = os.path.join(base_dir, "example_policies", preset_files[preset_name]) try: with open(policy_path, "r") as f: policy_text = f.read() return policy_text, policy_text except FileNotFoundError: return f"*Error: Policy file {preset_files[preset_name]} not found*", "" return "", "" def load_policy_from_file(file_path: str) -> tuple[str, str]: """Load policy from uploaded file.""" with open(file_path, "r") as f: content = f.read() return content, content