💻Create a Web Interface for your LLM in Python

<p>

In this tutorial we will create a simple chatbot web interface and deploy it using an open-source Python library called <a href="https://github.com/Avaiga/taipy" rel="nofollow">Taipy</a>.</p>
<p align="center">
<img alt="Render of the app" src="https://cdn-uploads.huggingface.co/production/uploads/63909280d2cf01fdfe33dc51/Ca237RlHtAJ3XbpTNIzyJ.png" width="100%"/>
</p>
<p>Here we will use HuggingFace's API with google/flan-t5-xxl. This tutorial can easily
be adapted to other LLMs.</p>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-1-install-requirements" id="step-1-install-requirements" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 1: Install Requirements
	</span>
</h1>
<p>Create a <code>requirements.txt</code> file with the following content:</p>
<pre><code class="language-bash">taipy==3.0.0
</code></pre>
<p>Install the requirements using pip in a terminal:</p>
<pre><code class="language-bash">pip install -r requirements.txt
</code></pre>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-2-imports" id="step-2-imports" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 2: Imports
	</span>
</h1>
<p>Create a <code>main.py</code> file with the following imports:</p>
<pre><code class="language-python"><span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">from</span> taipy.gui <span class="hljs-keyword">import</span> Gui, State, notify
</code></pre>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-3-initialize-variables" id="step-3-initialize-variables" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 3: Initialize variables
	</span>
</h1>
<p>Initialize the following variables in the main.py file:</p>
<pre><code class="language-python">context = <span class="hljs-string">"The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly.\n\nHuman: Hello, who are you?\nAI: I am an AI created by Google. How can I help you today? "</span>
conversation = {
    <span class="hljs-string">"Conversation"</span>: [<span class="hljs-string">"Who are you?"</span>, <span class="hljs-string">"Hi! I am FLAN-T5 XXL. How can I help you today?"</span>]
}
current_user_message = <span class="hljs-string">""</span>
</code></pre>
<ul>
<li><code>context</code> is the initial context for the conversation, the LLM will use this to understand what behaviour is expected from it.</li>
<li><code>conversation</code> is a dictionary that will store the conversation history to be displayed</li>
<li><code>current_user_message</code> is the current message that the user is typing</li>
</ul>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-4-create-a-function-to-generate-responses" id="step-4-create-a-function-to-generate-responses" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 4: Create a function to generate responses
	</span>
</h1>
<p><strong>This step is the one that needs to be adapted if you want to
use a different LLM.</strong></p>
<p>Initialize the HuggingFace variables with your Access Token. You can find
your Access Token <a href="https://huggingface.co/settings/tokens">here</a>.</p>
<pre><code class="language-python">API_URL = <span class="hljs-string">"https://api-inference.huggingface.co/models/google/flan-t5-xxl"</span>
headers = {<span class="hljs-string">"Authorization"</span>: <span class="hljs-string">"Bearer [YOUR ACCESS TOKEN]"</span>}
</code></pre>
<p>Create a function that takes as input a string <code>prompt</code> which
is the user message and returns a string which is the response from the LLM.</p>
<pre><code class="language-python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">query</span>(<span class="hljs-params">payload</span>):
    response = requests.post(API_URL, headers=headers, json=payload)
    <span class="hljs-keyword">return</span> response.json()

<span class="hljs-keyword">def</span> <span class="hljs-title function_">request</span>(<span class="hljs-params">state: State, prompt: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-built_in">str</span>:
    <span class="hljs-string">"""</span>
<span class="hljs-string">    Send a prompt to the HuggingFace API and return the response.</span>
<span class="hljs-string"></span>
<span class="hljs-string">    Args:</span>
<span class="hljs-string">        - state: The current state of the app.</span>
<span class="hljs-string">        - prompt: The prompt to send to the API.</span>
<span class="hljs-string"></span>
<span class="hljs-string">    Returns:</span>
<span class="hljs-string">        The response from the API.</span>
<span class="hljs-string">    """</span>
    
    output = query(
        {
            <span class="hljs-string">"inputs"</span>: prompt,
        }
    )
    <span class="hljs-built_in">print</span>(output)
    <span class="hljs-keyword">return</span> output[<span class="hljs-number">0</span>][<span class="hljs-string">"generated_text"</span>]
</code></pre>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-5-create-a-function-to-add-the-new-messages-to-the-conversation" id="step-5-create-a-function-to-add-the-new-messages-to-the-conversation" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 5: Create a function to add the new messages to the conversation
	</span>
</h1>
<p>Create a function that gets triggered when the user sends a
message. This function will add the user's message to the context,
send it to the API, get the response, add the response to the
context and to the displayed conversation.</p>
<pre><code class="language-python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">send_message</span>(<span class="hljs-params">state: State</span>) -&gt; <span class="hljs-literal">None</span>:
    <span class="hljs-string">"""</span>
<span class="hljs-string">    Send the user's message to the API and update the conversation.</span>
<span class="hljs-string"></span>
<span class="hljs-string">    Args:</span>
<span class="hljs-string">        - state: The current state of the app.</span>
<span class="hljs-string">    """</span>
    <span class="hljs-comment"># Add the user's message to the context</span>
    state.context += <span class="hljs-string">f"Human: \n <span class="hljs-subst">{state.current_user_message}</span>\n\n AI:"</span>
    <span class="hljs-comment"># Send the user's message to the API and get the response</span>
    answer = request(state, state.context).replace(<span class="hljs-string">"\n"</span>, <span class="hljs-string">""</span>)
    <span class="hljs-comment"># Add the response to the context for future messages</span>
    state.context += answer
    <span class="hljs-comment"># Update the conversation</span>
    conv = state.conversation._<span class="hljs-built_in">dict</span>.copy()
    conv[<span class="hljs-string">"Conversation"</span>] += [state.current_user_message, answer]
    state.conversation = conv
    <span class="hljs-comment"># Clear the input field</span>
    state.current_user_message = <span class="hljs-string">""</span>
</code></pre>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-6-create-the-user-interface" id="step-6-create-the-user-interface" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 6: Create the User Interface
	</span>
</h1>
<p>In Taipy, one way to define pages is to use Markdown strings. Here we use a
<a href="https://docs.taipy.io/en/latest/manuals/gui/viselements/table/" rel="nofollow">table</a> to display the
 <code>conversation</code> dictionary and an
 <a href="https://docs.taipy.io/en/latest/manuals/gui/viselements/input/" rel="nofollow">input</a> so that the
 user can type their message. When the user presses enter,
 the <code>send_message</code> function is triggered.</p>
<pre><code class="language-python">page = <span class="hljs-string">"""</span>
<span class="hljs-string">&lt;|{conversation}|table|show_all|width=100%|&gt;</span>
<span class="hljs-string">&lt;|{current_user_message}|input|label=Write your message here...|on_action=send_message|class_name=fullwidth|&gt;</span>
<span class="hljs-string">"""</span>
</code></pre>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-7-run-the-application" id="step-7-run-the-application" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 7: Run the application
	</span>
</h1>
<p>Finally we run the application:</p>
<pre><code class="language-python"><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    Gui(page).run(dark_mode=<span class="hljs-literal">True</span>, title=<span class="hljs-string">"Taipy Chat"</span>)
</code></pre>
<p>And here is the result:</p>
<p align="center">
<img alt="Render of the app" src="https://cdn-uploads.huggingface.co/production/uploads/63909280d2cf01fdfe33dc51/hDdPAMkhzaHLr8R0CvdV6.png" width="80%"/>
</p>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-8-styling" id="step-8-styling" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 8: Styling
	</span>
</h1>
<p>The app's style is Taipy's default stylekit. We are going to
make some changes so that it looks more like a chat app.</p>
<p>First in a <code>main.css</code> file, create styles to display user and
AI messages differently:</p>
<pre><code class="language-css"><span class="hljs-selector-class">.gpt_message</span> <span class="hljs-selector-tag">td</span> {
    <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">30px</span>;
    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">position</span>: relative;
    <span class="hljs-attribute">display</span>: inline-block;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ff462b</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">max-width</span>: <span class="hljs-number">80%</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">4px</span> <span class="hljs-number">8px</span> <span class="hljs-number">0</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.2</span>), <span class="hljs-number">0</span> <span class="hljs-number">6px</span> <span class="hljs-number">20px</span> <span class="hljs-number">0</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.19</span>);
    <span class="hljs-attribute">font-size</span>: large;
}

<span class="hljs-selector-class">.user_message</span> <span class="hljs-selector-tag">td</span> {
    <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">30px</span>;
    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">position</span>: relative;
    <span class="hljs-attribute">display</span>: inline-block;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#140a1e</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">max-width</span>: <span class="hljs-number">80%</span>;
    <span class="hljs-attribute">float</span>: right;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">4px</span> <span class="hljs-number">8px</span> <span class="hljs-number">0</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.2</span>), <span class="hljs-number">0</span> <span class="hljs-number">6px</span> <span class="hljs-number">20px</span> <span class="hljs-number">0</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.19</span>);
    <span class="hljs-attribute">font-size</span>: large;
}
</code></pre>
<p>We now need to tell Taipy to apply these styles to the rows in
the table. We'll first create a function that will return the
correct class name for each row:</p>
<pre><code class="language-python"><span class="hljs-keyword">def</span> <span class="hljs-title function_">style_conv</span>(<span class="hljs-params">state: State, idx: <span class="hljs-built_in">int</span>, row: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-built_in">str</span>:
    <span class="hljs-string">"""</span>
<span class="hljs-string">    Apply a style to the conversation table depending on the message's author.</span>
<span class="hljs-string"></span>
<span class="hljs-string">    Args:</span>
<span class="hljs-string">        - state: The current state of the app.</span>
<span class="hljs-string">        - idx: The index of the message in the table.</span>
<span class="hljs-string">        - row: The row of the message in the table.</span>
<span class="hljs-string"></span>
<span class="hljs-string">    Returns:</span>
<span class="hljs-string">        The style to apply to the message.</span>
<span class="hljs-string">    """</span>
    <span class="hljs-keyword">if</span> idx <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>
    <span class="hljs-keyword">elif</span> idx % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">"user_message"</span>
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-string">"gpt_message"</span>
</code></pre>
<p>We then apply this function to the table by adding the <code>style</code> property</p>
<pre><code class="language-python">&lt;|{conversation}|table|show_all|style=style_conv|&gt;
</code></pre>
<p>And voilà:</p>
<p align="center">
<img alt="The styled application" src="https://cdn-uploads.huggingface.co/production/uploads/63909280d2cf01fdfe33dc51/UBcpas1GjapfU5PCy7xk8.png" width="80%"/>
</p>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-9-more-features" id="step-9-more-features" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 9: More features
	</span>
</h1>
<p>I have added notifications, a sidebar with a button to clear the conversation
and a history of previous conversations. I won't go into the
details of how to do this here, but you can find the full code
in the <a href="https://github.com/Avaiga/demo-llm-chat" rel="nofollow">GitHub repository</a></p>
<h1 class="relative group flex items-center">
<a class="block pr-1.5 text-lg md:absolute md:p-1.5 md:opacity-0 md:group-hover:opacity-100 md:right-full" href="#step-10-deploying-the-app-to-taipy-cloud" id="step-10-deploying-the-app-to-taipy-cloud" rel="nofollow">
<span class="header-link"><svg aria-hidden="true" class="text-gray-500 hover:text-black dark:hover:text-gray-200 w-4" height="1em" preserveaspectratio="xMidYMid meet" role="img" viewbox="0 0 256 256" width="1em" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg></span>
</a>
<span>
		Step 10: Deploying the app to Taipy Cloud
	</span>
</h1>
<p>We are now going to deploy the app to Taipy Cloud so it is
accessible from anyone with a link.</p>
<p>Firstly we need to store the API key in an environment variable.
Replace the line that defines <code>headers</code> in Step 4 with:</p>
<pre><code class="language-python"><span class="hljs-keyword">import</span> os
headers = {<span class="hljs-string">"Authorization"</span>: <span class="hljs-string">f"Bearer <span class="hljs-subst">{os.environ[<span class="hljs-string">'HUGGINGFACE_API_KEY'</span>]}</span>"</span>}
</code></pre>
<p>Now, instead of having our API key in the code, the app will look
for it in the environment variables.</p>
<p>We can now deploy the app to Taipy Cloud:</p>
<ol>
<li>Connect to <a href="https://cloud.taipy.io/" rel="nofollow">Taipy Cloud</a> and sign in</li>
<li>Click on "Add Machine" and fill in the fields</li>
<li>Select the created machine and click on "Add app"</li>
<li>Zip the <code>main.py</code>, <code>main.css</code> and <code>requirements.txt</code> files and upload the zip file to the "App files" field. Fill in the other fields</li>
<li>In the "Environment Variables" tab, create a new environment variable called <code>HUGGINGFACE_API_KEY</code> and paste your API key as the value like in the image below</li>
<li>Press "Deploy app"</li>
</ol>
<p align="center">
<img alt="Environment Variables Tab" src="https://cdn-uploads.huggingface.co/production/uploads/63909280d2cf01fdfe33dc51/hvAVhgZ1UAGmWQ30OBnS1.png" width="80%"/>
</p>
<p>After a while, your app should be running and will be accessible
from the displayed link!</p>
<p align="center">
<img alt="Taipy Cloud Interface" src="https://cdn-uploads.huggingface.co/production/uploads/63909280d2cf01fdfe33dc51/ESgvjsvM84c_QZSiaKtjC.png" width="80%"/>
</p>
<p align="center">
<img alt="The final application" src="https://cdn-uploads.huggingface.co/production/uploads/63909280d2cf01fdfe33dc51/Y6TIRh-XcXnI-AO3soujF.png" width="80%"/>
</p>
