import gradio as gr from confusables import is_confusable, confusable_characters, confusable_regex, normalize def gr_is_confusable(str1: str, str2: str) -> bool: """ Check if two strings are visually confusable (i.e., they look similar to a human, but may use different Unicode characters). Args: str1: The first string to compare. str2: The second string to compare. Returns: True if the two strings are visually confusable, False otherwise. Example: gr_is_confusable("rover", "ฦฆแป๐•3โ„›") # True """ return is_confusable(str1, str2) def gr_confusable_characters(char: str) -> list[str]: """ List all Unicode characters or character sequences that are visually confusable with the given character. Args: char: The character to analyze (must be a single character). Returns: A list of confusable characters or sequences. Example: gr_confusable_characters("c") # ['ฤ‹', 'แด„', '๐” ', ...] """ return confusable_characters(char) def gr_confusable_regex(string: str, include_character_padding: bool) -> str: """ Generate a regular expression string that matches all visually confusable variants of the input string. Args: string: The reference string. include_character_padding: If True, the regex will allow for character padding (extra confusable characters between the main ones). Returns: A regex pattern string. Example: gr_confusable_regex("bore", True) """ return confusable_regex(string, include_character_padding) def gr_normalize(string: str, prioritize_alpha: bool) -> list[str]: """ Return all possible normalized forms of a string, converting confusable Unicode characters to their closest ASCII or Latin-alphabet equivalents. Args: string: The string to normalize. prioritize_alpha: If True, prioritizes conversion to Latin alphabet characters. Returns: A list of possible normalized forms. Example: gr_normalize("ฦฆแป๐•3โ„›", True) # ['rov3r', 'rover'] """ return normalize(string, prioritize_alpha) with gr.Blocks() as demo: gr.Markdown("""# MCP Server - Confusables API\nMain features of the confusables library exposed as tools.""") with gr.Tab("is_confusable"): gr.Interface( fn=gr_is_confusable, inputs=[gr.Textbox(label="String 1"), gr.Textbox(label="String 2")], outputs=gr.Textbox(label="Confusable? (True/False)"), allow_flagging="never" ).render() with gr.Tab("confusable_characters"): gr.Interface( fn=gr_confusable_characters, inputs=gr.Textbox(label="Character"), outputs=gr.Textbox(label="Confusable characters"), allow_flagging="never" ).render() with gr.Tab("confusable_regex"): gr.Interface( fn=gr_confusable_regex, inputs=[gr.Textbox(label="String"), gr.Checkbox(label="Include character padding")], outputs=gr.Textbox(label="Regex"), allow_flagging="never" ).render() with gr.Tab("normalize"): gr.Interface( fn=gr_normalize, inputs=[gr.Textbox(label="String"), gr.Checkbox(label="Prioritize alpha")], outputs=gr.Textbox(label="Normalized forms"), allow_flagging="never" ).render() if __name__ == "__main__": demo.launch(mcp_server=True)