import json import os from pathlib import Path import gradio as gr from glossary_checker import GlossaryChecker from trans_validator import TranslationValidator # Configure glossary paths GLOSSARIES = { "84000 Glossary": "data/84000_glossary.json", } def load_and_validate(file_obj, selected_glossary, api_key): if not api_key or not api_key.startswith("sk-"): return "Please provide a valid Anthropic API key (starts with 'sk-')" try: # Read content from the file content = file_obj.decode('utf-8') # Save content to temporary file temp_path = "temp_aligned.txt" with open(temp_path, "w", encoding='utf-8') as f: f.write(content) # Initialize checker and validator glossary_path = GLOSSARIES[selected_glossary] checker = GlossaryChecker(glossary_path) validator = TranslationValidator(checker, api_key) # Run validation results = validator.validate_translation(temp_path) # Create result display markdown_output = [] # Add summary total_score = sum(r['score'] for r in results) / len(results) markdown_output.append(f"# Validation Results\n") markdown_output.append(f"**Overall Score**: {total_score:.2f}%\n") markdown_output.append("*(Score based on terms counted in scoring)*\n\n") markdown_output.append(f"**Total Lines**: {len(results)}\n\n") # Add detailed results for each line for result in results: markdown_output.append(f"## Line {result['line_number']}\n") markdown_output.append(f"**Score**: {result['score']:.2f}%\n") markdown_output.append(f"**Source**: {result['source']}\n") markdown_output.append(f"**Target**: {result['target']}\n") if result['terms']: # Separate terms into counted and not counted counted_terms = [] other_terms = [] for term in result['terms']: if term['analysis']['translation_assessment']['should_be_counted']: counted_terms.append(term) else: other_terms.append(term) # Display counted terms first with clear scoring implications if counted_terms: markdown_output.append("\n### 📊 Terms Counted in Scoring\n") for term in counted_terms: analysis = term['analysis'] assessment = analysis['translation_assessment'] markdown_output.append(f"\n#### `{term['source_term']}` {'✅' if assessment['translated_correctly'] else '❌'}\n") markdown_output.append(f"- Found Translation: **{analysis['translated_as']}**\n") markdown_output.append(f"- Expected Translation: **{analysis['glossary_translation']}**\n") # Add matching categories for context for cat_name in analysis['matching_categories']: cat_data = term['categories'].get(cat_name, {}) markdown_output.append(f"\n*{cat_name}*:\n") if 'definitions' in cat_data: markdown_output.append(f"- Definition: {', '.join(cat_data['definitions'])}\n") # Display other found terms separately if other_terms: markdown_output.append("\n### Other Found Terms (Not Counted)\n") for term in other_terms: analysis = term['analysis'] markdown_output.append(f"\n#### `{term['source_term']}`\n") markdown_output.append(f"- Found Translation: {analysis['translated_as']}\n") markdown_output.append(f"- Note: Term not counted due to usage context\n") markdown_output.append("\n---\n") else: markdown_output.append("\n*No glossary terms found in this line*\n\n---\n") # Clean up temp file os.remove(temp_path) return "\n".join(markdown_output) except Exception as e: if os.path.exists(temp_path): os.remove(temp_path) return f"Error during validation: {str(e)}" # Create Gradio interface demo = gr.Interface( fn=load_and_validate, inputs=[ gr.File(label="Upload aligned translations file (tab-separated)", type="binary"), gr.Dropdown(choices=list(GLOSSARIES.keys()), label="Select Glossary"), gr.Textbox(label="Anthropic API Key", placeholder="sk-...", type="password") ], outputs=gr.Markdown(), title="Translation Validation Tool", description="""Upload a file with tab-separated Tibetan source and English translation pairs. The tool validates translations against the glossary using semantic analysis. Scoring System: - 📊 Only terms that match glossary definitions are counted in scoring - ✅ Correct translations must use glossary terms (with allowed grammatical variations) - ❌ Semantic equivalents or synonyms are marked as incorrect - Score = (correct translations) / (total counted terms) × 100 You'll need an Anthropic API key to use this tool. Get one at https://console.anthropic.com/""", examples=[ ["data/example_translations.txt", "84000 Glossary", ""] # Example with masked API key ], cache_examples=False # Don't cache examples with API keys ) if __name__ == "__main__": demo.launch()