File size: 5,652 Bytes
d9c2461
 
a081a02
6c3b363
a081a02
 
d9c2461
 
 
a081a02
 
d9c2461
 
 
a081a02
 
 
 
6c3b363
a081a02
 
2b78832
 
a081a02
 
 
 
 
 
d9c2461
a081a02
6c3b363
 
 
 
 
 
 
 
07a9d48
6c3b363
 
 
 
6fb52ba
6c3b363
 
 
 
 
 
 
6fb52ba
6c3b363
6fb52ba
6c3b363
 
adb79f7
 
 
 
9099e9b
adb79f7
 
 
 
 
 
a081a02
d9c2461
 
 
 
 
 
 
 
 
 
8d5d0f2
d9c2461
 
8d5d0f2
 
 
d9c2461
 
 
8d5d0f2
 
adb79f7
8d5d0f2
 
d9c2461
 
 
 
 
 
 
 
 
a081a02
d9c2461
adb79f7
a081a02
2b78832
a081a02
 
 
 
 
 
 
 
d9c2461
a081a02
6c3b363
a081a02
d9c2461
266fe4b
0d0f707
0fdc5a5
 
8d5d0f2
0fdc5a5
8d5d0f2
0fdc5a5
 
 
0d0f707
0fdc5a5
c3cc390
266fe4b
 
6fb52ba
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""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,
)

# UI
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(
        """
        - 🎯 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?

        Once you have shared this information, 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.

        ---

        __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.`
        """
    )

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":
            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