import gradio as gr import pandas as pd from fastapi import FastAPI from gradio.routes import App as GradioApp from introduck.inference import extract_contacts_from_text from introduck.utils import validate_email from introduck.utils import validate_multiple_emails from typing import Any _INTRO_SUBJECT_EXAMPLE: str = "Could you make an intro?" _INTRO_MESSAGE_EXAMPLE: str = """\ Hey, hope you are doing well! :-) Could you, please, make me an intro to one of them? - - - etc. Relevant info: - ; - Raising ; - We are backed by ; - Team: + - Traction highlights: + Best, \ """ def _analyze_message( sender: str, recipients: str, subject: str, body: str ) -> (pd.DataFrame, dict): default_outputs = None, None # validate sender email (if present) if sender: sender = validate_email(email=sender) if not sender: return default_outputs # validate recipient emails (if present) if recipients: recipients = validate_multiple_emails(emails=recipients) if not recipients: return default_outputs if not subject: return default_outputs if not body: return default_outputs payload: str = "" payload += f"From: {sender or '*'}\n" payload += f"To: {recipients or '*'}\n" payload += f"Subject: {subject or '*'}\n\n" payload += f"{body or '***'}\n" outputs: list[dict[str, Any]] = extract_contacts_from_text(payload=payload) return pd.DataFrame(outputs), {"text": payload, "entities": outputs} def _use_message_template() -> (str, str): return _INTRO_SUBJECT_EXAMPLE, _INTRO_MESSAGE_EXAMPLE def _validate_message( sender: str, recipients: str, subject: str, body: str ) -> dict: errors: list[str] = [] # validate sender email (if present) if sender: sender = validate_email(email=sender) if not sender: errors.append("- sender email is not valid;") # validate recipient emails (if present) if recipients: recipients = validate_multiple_emails(emails=recipients) if not recipients: errors.append("- one or more recipient emails are not valid;") if not subject: errors.append("- subject can't be empty;") if not body: errors.append("- message can't be empty;") new_value: str = "" if errors: errors_list: str = "\n".join(errors) new_value = f"```\nPlease, fix this errors:\n{errors_list}\n```" new_visibility: bool = len(errors) > 0 return gr.update(value=new_value, visible=new_visibility) def create_playground_route() -> FastAPI: # TODO: Fix once resolved https://github.com/gradio-app/gradio/issues/1683 # TODO: ...and remove elem_id="htxt" from HighlightedText for RF822 output css_workaround: str = """ #htxt span { font-family: monospace; white-space: pre; } """ copyright_string: str = "Introduck LLC, 2022" title: str = "Introduck Playground" base_blocks: gr.Blocks = gr.Blocks( analytics_enabled=False, title=title, css=css_workaround) with base_blocks: gr.Markdown(f"# {title}
") gr.Markdown("## New intro request") email_sender_input: gr.Textbox = gr.Textbox( label="From (optional):", lines=1, max_lines=1, placeholder="founder@acme.com") email_recipients_input: gr.Textbox = gr.Textbox( label="To (optional):", lines=1, max_lines=1, placeholder="jane@vc2.com, john@vc01.com") email_subject_input: gr.Textbox = gr.Textbox( show_label=False, lines=1, max_lines=1, placeholder="Subject...", interactive=True) email_body_input: gr.Textbox = gr.Textbox( show_label=False, lines=5, max_lines=42, placeholder="Type a message...", interactive=True) # TODO: Add support for attached files. # email_attachments_input: gr.File = gr.File( # label="Attachments:", # file_count="multiple") email_errors_output: gr.Markdown = gr.Markdown( value="", visible=False) with gr.Row(): email_template_button: gr.Button = gr.Button( value="Use template", variant="secondary") email_submit_button: gr.Button = gr.Button( value="Submit", variant="primary") gr.Markdown("""\ **NOTE:** This email form is used to extract useful information from intro requests. We assure you that no data will be shared publicly and only a small group of people will get access to this data in order to label it and create new datasets for model training. By clicking **"Submit"** you automatically agree to this terms.\ """) with gr.Tabs(selected="default"): with gr.TabItem(label="Contacts", id="default"): contacts_output: gr.Dataframe = gr.Dataframe(max_rows=16) with gr.TabItem(label="RFC822-ish"): rfc822_output: gr.HighlightedText = gr.HighlightedText( label="RFC822-ish message (for debugging purposes):", show_legend=False, elem_id="htxt") # temporary fix, see above for more info gr.Markdown("## FAQ") with gr.Group(): with gr.Accordion("Is it cool?"): gr.Markdown("Yes!") with gr.Accordion("Is it free?"): gr.Markdown("Yes!") gr.Markdown("""\ [Contact us](mailto:hello@introduck.ai) /  [Terms of Service](https://introduck.ai/terms) /  [Privacy Policy](https://introduck.ai/privacy) """) gr.Markdown(f"**©** {copyright_string}") # ui end, continue with signals and slots... email_submit_button.click( fn=_analyze_message, inputs=[ email_sender_input, email_recipients_input, email_subject_input, email_body_input], outputs=[ contacts_output, rfc822_output]) email_submit_button.click( fn=_validate_message, inputs=[ email_sender_input, email_recipients_input, email_subject_input, email_body_input], outputs=[email_errors_output]) email_template_button.click( fn=_use_message_template, inputs=[], outputs=[email_subject_input, email_body_input]) return GradioApp.create_app(blocks=base_blocks)