|
"""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": |
|
|
|
craft_story_from_recipe(input_str, "sell") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if "story" in st.session_state: |
|
st.markdown(st.session_state.story) |
|
del st.session_state.story |
|
|