Skip to content

Commit

Permalink
Removed writefile codeblocks
Browse files Browse the repository at this point in the history
  • Loading branch information
takumiohym committed Sep 24, 2024
1 parent 794b617 commit 0361779
Showing 1 changed file with 50 additions and 116 deletions.
166 changes: 50 additions & 116 deletions scaffolds/streamlit_on_cloudrun/llm_chatbot/build_app.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -50,36 +50,10 @@
"id": "a1a8b040-a64a-4925-bd96-123185f4c66f",
"metadata": {},
"source": [
"## Build a streamlit application"
]
},
{
"cell_type": "markdown",
"id": "a441f6b6-bca9-4aad-95f9-84a53fc2119a",
"metadata": {},
"source": [
"### Import Libraries\n",
"First, we'll import the necessary Python libraries, including Streamlit itself, as well as `vertexai` to interact with Gemini."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2faaa4f9-7c12-4d59-bb00-d78afd65aecf",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%writefile app.py\n",
"\"\"\"Streamlit Chatbot App\"\"\"\n",
"---\n",
"## Build a streamlit application\n",
"\n",
"import os\n",
"import time\n",
"\n",
"import streamlit as st\n",
"import vertexai\n",
"from vertexai.generative_models import Content, GenerativeModel, Part"
"The application code is written in [app.py](./app.py). Here let's check important concepts in the code."
]
},
{
Expand All @@ -88,40 +62,32 @@
"metadata": {},
"source": [
"### Add text elements\n",
"<div class=\"alert alert-info\">\n",
"\n",
"```python\n",
"st.set_page_config(page_title=\"Chat with Gemini\", page_icon=\"\")\n",
"\n",
"st.title(\"Chat with Gemini\")\n",
"\n",
"st.markdown(\"Welcome to this simple web application to chat with Gemini\")\n",
"```\n",
"</div>\n",
"\n",
"Streamlit eventually renders a web page, but we can simply use Python modules to define the visual and behavior of it.\n",
"\n",
"We'll start by configuring some metadata for our app.\n",
"\n",
"- [`st.set_page_config`](https://docs.streamlit.io/develop/api-reference/configuration/st.set_page_config) lets us customize aspects like the page title and favicon (the little icon that appears in your browser tab).\n",
"\n",
"Streamlit provides a variety of ways to display text content:\n",
"\n",
"- [`st.title`](https://docs.streamlit.io/develop/api-reference/text/st.title) is used to add a main heading to our page.\n",
"- You can also use [`st.header`](https://docs.streamlit.io/develop/api-reference/text/st.header) and [`st.subheader`](https://docs.streamlit.io/develop/api-reference/text/st.subheader) for smaller headings.\n",
"- [`st.text`](https://docs.streamlit.io/develop/api-reference/text/st.text) is for displaying plain text.\n",
"- [`st.markdown`](https://docs.streamlit.io/develop/api-reference/text/st.markdown) lets you add formatted text using Markdown syntax.\n",
"For more options, you can check the Streamlit documentation for [other text elements](https://docs.streamlit.io/develop/api-reference/text).\n",
"\n",
"Streamlit also offer a \"swiss-army knife\" command called [`st.write`](https://docs.streamlit.io/develop/api-reference/write-magic/st.write). It can handle many types of content, including text, DataFrames (tables of data), Matplotlib plots, and even Keras machine learning models.\n",
"\n",
"Also, here we define a few global variables that we'll use later."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cb068578-b530-4baa-a57d-b06571696076",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%writefile -a app.py\n",
"\n",
"st.set_page_config(page_title=\"Chat with Gemini\", page_icon=\"\")\n",
"\n",
"st.title(\"Chat with Gemini\")\n",
"\n",
"st.markdown(\"Welcome to this simple web application to chat with Gemini\")"
"Streamlit also offer a \"swiss-army knife\" command called [`st.write`](https://docs.streamlit.io/develop/api-reference/write-magic/st.write). It can handle many types of content, including text, DataFrames (tables of data), Matplotlib plots, and even Keras machine learning models.\n"
]
},
{
Expand All @@ -131,20 +97,11 @@
"source": [
"And let's setup some variables.\n",
"\n",
"The environment variables (`GCP_PROJECT` and `GCP_REGION`) can be set later when we deploy the app to Cloud Run."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "333a8c52-48f2-44c5-8ce2-e0a433bf95c6",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%writefile -a app.py\n",
"The environment variables (`GCP_PROJECT` and `GCP_REGION`) can be set later when we deploy the app to Cloud Run.\n",
"\n",
"<div class=\"alert alert-info\">\n",
"\n",
"```python\n",
"PROJECT_ID = os.environ.get(\"GCP_PROJECT\")\n",
"LOCATION = os.environ.get(\"GCP_REGION\")\n",
"\n",
Expand All @@ -153,7 +110,9 @@
"if \"gemini_model\" not in st.session_state:\n",
" st.session_state[\"gemini_model\"] = \"gemini-1.5-flash-001\"\n",
"\n",
"model = GenerativeModel(st.session_state[\"gemini_model\"])"
"model = GenerativeModel(st.session_state[\"gemini_model\"])\n",
"```\n",
"</div>"
]
},
{
Expand All @@ -169,13 +128,23 @@
"If the `\"messages\"` key is not present in the session state (when you open the page first), we initialize the list. If the key is already created, we iterate the list and show each message on the page.\n",
"\n",
"For chatbot apps, we can use the [`st.chat_message`](https://docs.streamlit.io/develop/api-reference/chat/st.chat_message) container to show each message on the page.<br>\n",
"We can use `with` notation to add elements to the returned container or simply call methods directly on the returned object like:\n",
"We can use `with` notation to add elements to the returned container or simply call methods directly on the returned object.\n",
"E.g.,\n",
"\n",
"<div class=\"alert alert-info\">\n",
"\n",
"```python\n",
"for message in st.session_state.messages:\n",
" with st.chat_message(name=message[\"role\"], avatar=message[\"avatar\"]):\n",
" st.markdown(message[\"content\"])\n",
"```\n",
"or\n",
"```python\n",
"for message in st.session_state.messages:\n",
" message = st.chat_message(name=message[\"role\"], avatar=message[\"avatar\"])\n",
" message.markdown(message[\"content\"])\n",
"```\n",
"</div>\n",
"\n",
"The chat_message takes two arguments:\n",
"- `name`: The name of the message author. It can be \"human\"/\"user\" or \"ai\"/\"assistant\" to enable preset styling and avatars.\n",
Expand All @@ -184,54 +153,25 @@
" - Some emoji formats are supported. See [the document](https://docs.streamlit.io/develop/api-reference/chat/st.chat_message) for the details.\n",
" - If it is None (default), the icon will be determined by name (\"user\"/\"human\" or \"ai\"/\"assistant\")\n",
"  \n",
"We pass these arguments from each message dictionary we'll add later.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "24219edd-cd10-432d-aa4a-7be9251f5487",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%writefile -a app.py\n",
"\n",
"# Initialize chat history\n",
"if \"messages\" not in st.session_state:\n",
" st.session_state.messages = []\n",
"\n",
"# Display chat messages from history on app rerun\n",
"for message in st.session_state.messages:\n",
" with st.chat_message(name=message[\"role\"], avatar=message[\"avatar\"]):\n",
" st.markdown(message[\"content\"])"
"We pass these arguments from each message dictionary we'll add later.\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "81422c28-68cc-4a9a-a593-9700366e0276",
"metadata": {},
"source": [
"### Helper Functions for conversations\n",
"Let's define the helper functions we'll use later.\n",
"\n",
"The `generate_response` function starts a chat with Gemini using a history in the session.\n",
"\n",
"The `stream` function will be used later to write the Gemini response in a stream for a more interactive user experience, instead of writing all the responses simultaneously."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4538bc0a-c486-48d3-9742-a84c6b07fca5",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%writefile -a app.py\n",
"The `stream` function will be used later to write the Gemini response in a stream for a more interactive user experience, instead of writing all the responses simultaneously.\n",
"\n",
"<div class=\"alert alert-info\">\n",
"\n",
"```python\n",
"def generate_response(input_text):\n",
" chat = model.start_chat(\n",
" history=[\n",
Expand All @@ -245,7 +185,9 @@
"def stream(text):\n",
" for word in text.split(\" \"):\n",
" yield word + \" \"\n",
" time.sleep(0.02)"
" time.sleep(0.02)\n",
"```\n",
"</div>"
]
},
{
Expand All @@ -259,22 +201,11 @@
"1. Show the user input on the page. We use `st.chat_message` as `\"user\"` name and `st.write` to add a message.\n",
"2. Add the user input to the message history in the session state.\n",
"3. Call Gemini and write the response. Here, we use `\"assistant\"` as the name and specify the Gemini icon as the avatar. Also, use `st.write_stream` with the `stream` function to show the response in a stream.\n",
"4. Add the Gemini response to the message history in the session state."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "55490f20-f594-4648-a7ae-d84fd23520c3",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%%writefile -a app.py\n",
"4. Add the Gemini response to the message history in the session state.\n",
"\n",
"<div class=\"alert alert-info\">\n",
"\n",
"# React to user input\n",
"```python\n",
"if prompt := st.chat_input(\"Write a promt\"):\n",
" # 1. Write the user message\n",
" with st.chat_message(name=\"user\", avatar=None):\n",
Expand All @@ -295,14 +226,17 @@
" \"content\": response.text,\n",
" \"avatar\": \"assets/gemini-icon.png\",\n",
" }\n",
" )\n"
" )\n",
"```\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "7a1c0808-5299-4527-9df5-1492beb7d9d5",
"metadata": {},
"source": [
"---\n",
"## Deploying the App on Cloud Run\n",
"Our Streamlit application is ready! Let's deploy it to Google Cloud Run, a serverless platform designed to run containerized applications seamlessly.\n",
"\n",
Expand Down

0 comments on commit 0361779

Please sign in to comment.