kwest.dev / app.py
chainyo's picture
add warning disclaimer
2412e4c
"""kwest.dev is a saas tool to craft stories for your ideas."""
import os
from typing import Union
import requests
import streamlit as st
API_URL = os.getenv("API_URL", None)
AUTH_TOKEN = os.getenv("AUTH_TOKEN", None)
RECIPES = ["sell", "motivate", "convince", "connect", "explain", "lead", "impress"]
VALID_EMOJIS = {"yes": "βœ…", "no": "❌"}
if not API_URL or not AUTH_TOKEN:
raise ValueError("API_URL and AUTH_TOKEN secrets must be set in the environment variables.")
def check_if_input_is_valid(input_str: str) -> Union[dict[str, str], None]:
"""Check if the input string is valid for the API."""
response = requests.post(
f"{API_URL}input-check",
headers={"Authorization": f"{AUTH_TOKEN}", "Accept": "application/json"},
json={"input": input_str},
)
if response.status_code == 200:
return response.json()["output"]
else:
return None
def get_recipe_choices(input_str: str) -> Union[dict[str, str], None]:
"""Get the recipe choices for the input string."""
response = requests.post(
f"{API_URL}recipe-choice",
headers={"Authorization": f"{AUTH_TOKEN}", "Accept": "application/json"},
json={"input": input_str},
)
if response.status_code == 200:
return response.json()["output"]
else:
return None
def craft_story_from_recipe(input_str: str, recipe: str) -> None:
"""Craft a story from the input string and recipe."""
response = requests.post(
f"{API_URL}craft-from-recipe",
headers={"Authorization": f"{AUTH_TOKEN}", "Accept": "application/json"},
json={"input": input_str, "recipe": recipe},
)
if response.status_code == 200:
st.session_state.story = response.json()["output"]["story"]
else:
raise ValueError("An error occurred while crafting the story.")
st.markdown(
"""
<style>
button {
height: 100px !important;
}
</style>
""",
unsafe_allow_html=True,
)
_recipe_choice_explanations = """
Once you have shared these details, you will have the opportunity to choose a recipe to craft your story.
The different recipes available are: `sell`, `motivate`, `convince`, `connect`, `explain`, `lead`, `impress`
You can choose the recipe that best fits your idea, but to help you decide we will mark the 1st and 2nd best recipes with πŸ₯‡ and πŸ₯ˆ respectively.
"""
_explanations = f"""
- 🎯 Explain the **main objective** of your idea. What is the **main goal** you are trying to achieve?
- πŸ“ Give as much **context** as possible. For example, what is the problem you are trying to solve? If you have a good name for your idea, share it.
- πŸ‘€ What is the **audience** for your idea? Who are the people that should be interested in it?
---
__Examples of good and bad inputs:__
βœ… `I need a pitch for a new app that helps people find the best restaurants in town based on their previous feedback. I will present it to angel investors. The name of the app is "Foodie".`
βœ… `I want to present to my friends the idea of a collaborative group of people that help each other to achieve their goals. I want to motivate them to join the group to allow people to share knowledge together and grow skills using peer-to-peer learning.`
βœ… `I'm going to present a new way to manage projects to my team. I want to convince them that this new method will help us be more efficient, reduce stress, and deliver better results.`
❌ `I need a pitch for a new app. It's cool.`
"""
st.title("kwest.dev")
st.subheader("Leverage the power of storytelling for any idea. πŸ’‘")
with st.expander(label="How to present your idea to get the best story πŸ‘‡", expanded=True):
st.markdown(_explanations)
st.warning("If you get an error while generating a story while the input is valid, please try again, we might have a temporary rate limit.")
input_col, btn_col = st.columns([3, 1], vertical_alignment="bottom")
with input_col:
input_str = st.text_area("Your idea that needs a story", "", placeholder="I need a pitch for ...")
with btn_col:
check_input = st.button(label="▢️", key="check_input", help="Check if the input is valid")
if check_input and input_str != "":
input_is_valid = check_if_input_is_valid(input_str)
if input_is_valid is None:
st.error("An error occurred while checking the input. Please try again.")
st.stop()
else:
st.write(
f"Objective: {VALID_EMOJIS[input_is_valid['objective']]} | "
f"Context: {VALID_EMOJIS[input_is_valid['context']]} | "
f"Audience: {VALID_EMOJIS[input_is_valid['audience']]}"
)
if input_is_valid["objective"] == "yes" and input_is_valid["context"] == "yes" and input_is_valid["audience"] == "yes":
# NOTE: Only sell recipe is available for now.
craft_story_from_recipe(input_str, "sell")
# recipe_choices = get_recipe_choices(input_str)
# st.write("Choose the recipe you want to use for your story.")
# recipe_choices_col = st.columns(7, vertical_alignment="bottom")
# for idx, recipe in enumerate(RECIPES):
# with recipe_choices_col[idx]:
# if recipe == recipe_choices["recipe"]:
# _recipe = f"πŸ₯‡{recipe}"
# elif recipe == recipe_choices["second_recipe"]:
# _recipe = f"πŸ₯ˆ{recipe}"
# else:
# _recipe = recipe
# st.button(
# _recipe,
# on_click=craft_story_from_recipe,
# kwargs={"input_str": input_str, "recipe": recipe},
# use_container_width=True,
# )
if "story" in st.session_state:
st.markdown(st.session_state.story)
del st.session_state.story