introduck / introduck /routes.py
speqtr's picture
remote inference api
aa1a424 verified
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?
- <person1@example.com>
- <person2@acme.corp>
- etc.
Relevant info:
- <add your one sentence summary here>;
- Raising <add your fundraising amount here>;
- We are backed by <add your existing investor names here>;
- Team:
+ <add team members>
- Traction highlights:
+ <highlights list>
Best,
<your name>\
"""
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}<br/>")
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)&nbsp;/&nbsp;
[Terms of Service](https://introduck.ai/terms)&nbsp;/&nbsp;
[Privacy Policy](https://introduck.ai/privacy)
""")
gr.Markdown(f"**&copy;** {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)