<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Streamlit</title>
    <description>The latest articles on DEV Community by Streamlit (@streamlit).</description>
    <link>https://dev.to/streamlit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1898802%2F721b8de8-1412-46aa-a2d9-df8b565019c0.png</url>
      <title>DEV Community: Streamlit</title>
      <link>https://dev.to/streamlit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/streamlit"/>
    <language>en</language>
    <item>
      <title>How to build a movie recommendation app without the complexities of vector databases</title>
      <dc:creator>Streamlit</dc:creator>
      <pubDate>Tue, 10 Sep 2024 22:52:16 +0000</pubDate>
      <link>https://dev.to/streamlit/how-to-build-a-movie-recommendation-app-without-the-complexities-of-vector-databases-39f9</link>
      <guid>https://dev.to/streamlit/how-to-build-a-movie-recommendation-app-without-the-complexities-of-vector-databases-39f9</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://blog.streamlit.io/how-to-recommendation-app-vector-database-weaviate/" rel="noopener noreferrer"&gt;Streamlit blog&lt;/a&gt; by &lt;a href="https://blog.streamlit.io/author/liz/" rel="noopener noreferrer"&gt;Liz Acosta&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You are what you eat; your model is what your model ingests.&lt;/p&gt;

&lt;p&gt;Not only does data inform AI systems, data is the output you ultimately receive. That’s why it’s important to have “good” data. It doesn’t matter how powerful your model is, garbage in will always result in garbage out.&lt;/p&gt;

&lt;p&gt;In software development, this isn’t a new concept or problem. However, AI demands a more sophisticated data strategy throughout the ETL process. This can slow the delivery of your AI-integrated applications.&lt;/p&gt;

&lt;p&gt;In this recipe, you’ll use Weaviate to abstract away the complexity associated with vector databases, allowing you to implement a powerful search and recommendation system with way less technical overhead. Then we’ll use Streamlit to build the chatbot part of the app. &lt;/p&gt;

&lt;p&gt;And don’t panic! There’s no frontend involved!&lt;/p&gt;

&lt;p&gt;Read on to learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Weaviate is&lt;/li&gt;
&lt;li&gt;What Streamlit is&lt;/li&gt;
&lt;li&gt;How to build a demo Weaviate movie recommendation Streamlit app&lt;/li&gt;
&lt;li&gt;How to query a Collection in Weaviate Cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don’t feel like reading? Here are some other ways to explore this demo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/streamlit/cookbook/tree/main/recipes/weaviate" rel="noopener noreferrer"&gt;Find the code in the Streamlit Cookbook repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=SQD-aWlhqvM" rel="noopener noreferrer"&gt;Watch a video walkthrough&lt;/a&gt; with Weaviate technical curriculum developer, JP Hwang&lt;/li&gt;
&lt;li&gt;&lt;a href="https://weaviate-movie-magic.streamlit.app/" rel="noopener noreferrer"&gt;Check out a deployed version of the app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Weaviate?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://weaviate.io/" rel="noopener noreferrer"&gt;Weaviate&lt;/a&gt; is an AI-native database designed to help you build amazing, scalable, and production-grade AI-powered applications. It offers robust features for data storage, retrieval, and querying as well as integrations with AI models, making it an excellent choice for developers looking to integrate AI capabilities into their apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Streamlit-Weaviate Connection
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/weaviate/st-weaviate-connection" rel="noopener noreferrer"&gt;Streamlit-Weaviate connection&lt;/a&gt; is a wrapper that simplifies the process of integrating Weaviate with Streamlit applications. This connection allows you to perform various operations, such as connecting to a remote or local Weaviate instance, performing queries, and using the underlying Weaviate Python client. The project is open-source so contributions are always welcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connect to a Weaviate Cloud instance:&lt;/strong&gt; Easily connect to a Weaviate cloud instance using a URL and API key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect to a locally running Weaviate instance:&lt;/strong&gt; Easily connect to a Weaviate instance running locally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perform queries:&lt;/strong&gt; Execute simple and advanced queries using the query or GraphQL query methods&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use the Weaviate Python client:&lt;/strong&gt; Leverage the full capabilities of the Weaviate Python client for more complex operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support for local instances:&lt;/strong&gt; Connect to a local Weaviate instance using default parameters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets management:&lt;/strong&gt; Streamlit can handle secret management for secure connections&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Streamlit?
&lt;/h2&gt;

&lt;p&gt;Streamlit is an open-source Python framework to build highly interactive apps – in only a few lines of code. Streamlit integrates with all the latest tools in &lt;a href="https://streamlit.io/generative-ai" rel="noopener noreferrer"&gt;generative AI&lt;/a&gt;, such as any LLM, vector database, or various AI frameworks like &lt;a href="https://blog.streamlit.io/langchain-streamlit/" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt;, &lt;a href="https://blog.streamlit.io/build-a-chatbot-with-custom-data-sources-powered-by-llamaindex/" rel="noopener noreferrer"&gt;LlamaIndex&lt;/a&gt;, or Weights &amp;amp; Biases. Streamlit’s &lt;a href="https://docs.streamlit.io/develop/api-reference/chat" rel="noopener noreferrer"&gt;chat elements&lt;/a&gt; make it especially easy to interact with AI so you can build chatbots that “talk to your data.”&lt;/p&gt;

&lt;p&gt;Combined with a platform like Replicate, Streamlit allows you to create generative AI applications without any of the app design overhead.&lt;/p&gt;

&lt;p&gt;To learn more about Streamlit, &lt;a href="https://blog.streamlit.io/streamlit-101-python-data-app/" rel="noopener noreferrer"&gt;check out the 101 guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;💡 To learn more about how Streamlit biases you toward forward progress, check out this &lt;a href="https://blog.streamlit.io/just-build-it-streamlit-opinionated-framework/" rel="noopener noreferrer"&gt;blog post&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the app recipe: Weaviate + Streamlit
&lt;/h2&gt;

&lt;p&gt;In this demo, you’ll spin up a movie recommendation app that utilizes Weaviate for backend data management and Streamlit chat elements on the frontend for interaction. The app accepts a natural language input from a user and uses Weaviate to translate the input into a query and then generate a list of movie titles.&lt;/p&gt;

&lt;p&gt;There are three different kinds of search modes available:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keyword:&lt;/strong&gt; This search mode uses BM25 to rank documents based on the relative frequencies of search terms. In this particular app, that means the results returned are based on how often the search keywords appear in the different movie properties.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantic:&lt;/strong&gt; This type of search uses vectors to generate results based on their similarity to your search query. In other words, the results returned are based on a similarity of “meaning.” To learn more about vector databases, check out Weaviate’s &lt;em&gt;&lt;a href="https://weaviate.io/blog/what-is-a-vector-database" rel="noopener noreferrer"&gt;Gentle Introduction to Vector Databases&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hybrid:&lt;/strong&gt; A hybrid search combines vector and BM25 searches to offer best-of-both-worlds search results. &lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Python &amp;gt;=3.8, !=3.9.7&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://console.weaviate.cloud" rel="noopener noreferrer"&gt;A Weaviate sandbox instance&lt;/a&gt;
(This will give you the API and URL to use in the code as well)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dashboard.cohere.com/welcome/register" rel="noopener noreferrer"&gt;A Cohere API key&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this app, the Cohere API is used for two different operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To summarize the query results into a natural language recommendation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://weaviate.io/developers/weaviate/model-providers/cohere" rel="noopener noreferrer"&gt;To transform the MovieDemo data and queries into high-dimensional vector representations&lt;/a&gt; for the semantic and hybrid search modes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note that both &lt;a href="https://weaviate.io/pricing" rel="noopener noreferrer"&gt;Weaviate&lt;/a&gt; and &lt;a href="https://docs.cohere.com/docs/rate-limits" rel="noopener noreferrer"&gt;Cohere&lt;/a&gt; have limits on their trial accounts. Check their websites for more details.&lt;/p&gt;

&lt;p&gt;💡 To learn more about API keys, check out the blog post &lt;a href="https://blog.streamlit.io/8-tips-for-securely-using-api-keys/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment setup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Local setup: Create a virtual environment&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the Cookbook repo: &lt;code&gt;git clone https://github.com/streamlit/cookbook.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;From the Cookbook root directory, change directory into the recipe: &lt;code&gt;cd recipes/weaviate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the necessary secrets to the &lt;code&gt;.streamlit/secrets_template.toml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;WEAVIATE_API_KEY&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"your weaviate key goes here"&lt;/span&gt;
&lt;span class="py"&gt;WEAVIATE_URL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"your weaviate url goes here"&lt;/span&gt; 
&lt;span class="py"&gt;COHERE_API_KEY&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"your cohere api key goes here"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the filename from secrets_template.toml to secrets.toml: &lt;code&gt;mv .streamlit/secrets_template.toml .streamlit/secrets.toml&lt;/code&gt;&lt;br&gt;
(To learn more about secrets handling in Streamlit, refer to the documentation &lt;a href="https://docs.streamlit.io/develop/concepts/connections/secrets-management" rel="noopener noreferrer"&gt;here&lt;/a&gt;.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a virtual environment: &lt;code&gt;python3 -m venv weaviatevenv&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Activate the virtual environment: &lt;code&gt;source weaviatevenv/bin/activate&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the dependencies: &lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Add data to your Weaviate Cloud&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Weaviate Cloud &lt;a href="https://weaviate.io/developers/weaviate/config-refs/schema#introduction" rel="noopener noreferrer"&gt;Collection&lt;/a&gt; and add data to it: &lt;code&gt;python3 helpers/add_data.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;(Optional) Verify the data: &lt;code&gt;python3 helpers/verify_data.py&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Query the MovieDemo collection in Weaviate Cloud
&lt;/h3&gt;

&lt;p&gt;You can access the &lt;a href="https://weaviate.io/developers/weaviate/connections/connect-query#example-query" rel="noopener noreferrer"&gt;Query&lt;/a&gt; panel via the Weaviate Cloud UI. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Copy and paste the following query in the editor:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;Get&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MovieDemo&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;"release_year"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
    &lt;span class="k"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;valueInt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1985&lt;/span&gt;&lt;span class="p"&gt;}){&lt;/span&gt; 
&lt;span class="n"&gt;budget&lt;/span&gt; 
&lt;span class="n"&gt;movie_id&lt;/span&gt; 
&lt;span class="n"&gt;overview&lt;/span&gt; 
&lt;span class="n"&gt;release_year&lt;/span&gt; 
&lt;span class="n"&gt;revenue&lt;/span&gt; 
&lt;span class="n"&gt;tagline&lt;/span&gt; 
&lt;span class="n"&gt;title&lt;/span&gt; 
&lt;span class="n"&gt;vote_average&lt;/span&gt; 
&lt;span class="p"&gt;}}}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the arrow to execute the query&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9KBz_nQ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-rt.googleusercontent.com/docsz/AD_4nXdufPHaFscBz3WAEP943zzLzF8l5Ylt4rSiX-sSWMhbmcGr7C5M-TbkJCc0PjfCEn-f9gLx7aosweXHGfdRJVFtvFQHMP4-bMQs6I4q3Tljh2NQ0vZWdqgYx4oTBPsQiBfTehWYWNMXGw5232Rx5hoFQP1v%3Fkey%3DI3XPnLBZfnTKn4Hrum-sGA" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9KBz_nQ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-rt.googleusercontent.com/docsz/AD_4nXdufPHaFscBz3WAEP943zzLzF8l5Ylt4rSiX-sSWMhbmcGr7C5M-TbkJCc0PjfCEn-f9gLx7aosweXHGfdRJVFtvFQHMP4-bMQs6I4q3Tljh2NQ0vZWdqgYx4oTBPsQiBfTehWYWNMXGw5232Rx5hoFQP1v%3Fkey%3DI3XPnLBZfnTKn4Hrum-sGA" title="Screenshot of the Weaviate Cloud UI" alt="Screenshot of the Weaviate Cloud UI" width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Weaviate Cloud Query tool is a browser-based GraphQL IDE. In the example query above, we are telling Weaviate to return the &lt;code&gt;budget, movie_id, overview, release_year, revenue, tagline, title, vote_average, vote_count&lt;/code&gt; properties for the objects in the MovieDemo collection with a &lt;code&gt;release_year&lt;/code&gt; of &lt;code&gt;1985&lt;/code&gt;. We do this by setting the &lt;code&gt;path&lt;/code&gt; to &lt;code&gt;["release_year"]&lt;/code&gt;, the &lt;code&gt;operator&lt;/code&gt; to &lt;code&gt;Equal&lt;/code&gt;, and the &lt;code&gt;valueInt&lt;/code&gt; to &lt;code&gt;1985&lt;/code&gt;.  We also limit the query results to three objects with &lt;code&gt;limit: 3&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;You should get back a result of three movies with the release year 1985.&lt;/p&gt;

&lt;p&gt;This is a simple query that forms the foundation of more complex queries. To learn more about different kinds of searches available with the Weaviate Cloud Query tool, &lt;a href="https://weaviate.io/developers/weaviate/search/basics" rel="noopener noreferrer"&gt;check out the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Run the demo Weaviate Streamlit recommendation app&lt;/p&gt;

&lt;p&gt;To run the demo app, use the Streamlit CLI: &lt;code&gt;streamlit run demo_app.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Running this command deploys the app to a port on &lt;code&gt;localhost&lt;/code&gt;. When you access this location, you should see a Streamlit app running. Please note that this version of the demo app does not feature the poster images so it will look different from the &lt;a href="https://weaviate-movie-magic.streamlit.app/" rel="noopener noreferrer"&gt;deployed app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jfeqe4uw4esqags8f6l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jfeqe4uw4esqags8f6l.gif" alt="A gif of the movie recommendation app demo" width="752" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vector databases made easy
&lt;/h3&gt;

&lt;p&gt;Using Streamlit-Weaviate Connection means you can easily create and integrate vector databases in your Streamlit apps.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;demo_app.py&lt;/code&gt;, the Weaviate connection is created here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup_weaviate_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env_vars&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Setup Weaviate connection&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weaviate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;WeaviateConnection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;env_vars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WEAVIATE_URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;env_vars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WEAVIATE_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;additional_headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-Cohere-Api-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;env_vars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COHERE_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using Streamlit &lt;a href="https://docs.streamlit.io/develop/api-reference/chat" rel="noopener noreferrer"&gt;chat elements&lt;/a&gt;, a prompt is created and a query is made here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MovieDemo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hybrid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
                &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;movie_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;filters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;                 &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;by_property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;release_year&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;greater_or_equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year_range&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;                  &lt;span class="n"&gt;Filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;by_property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;release_year&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;less_or_equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year_range&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SEARCH_LIMIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SEARCH_MODES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="n"&gt;grouped_task&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;rag_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;grouped_properties&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tagline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is a fully interactive recommendation app with no JavaScript experience required!&lt;/p&gt;

&lt;p&gt;If you would like to learn more about Weaviate, check out the &lt;a href="https://weaviate.io/developers/weaviate/quickstart" rel="noopener noreferrer"&gt;Weaviate Quickstart&lt;/a&gt; and &lt;a href="https://weaviate.io/developers/academy" rel="noopener noreferrer"&gt;Weaviate Academy&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unlock the potential of AI with Streamlit
&lt;/h2&gt;

&lt;p&gt;With Streamlit, months and months of app design work are &lt;em&gt;streamlined&lt;/em&gt; to just a few lines of Python. It’s the perfect framework for showing off your latest AI inventions. &lt;/p&gt;

&lt;p&gt;Get up and running &lt;strong&gt;&lt;em&gt;fast&lt;/em&gt;&lt;/strong&gt; with other AI recipes in the &lt;a href="https://github.com/streamlit/cookbook/tree/main" rel="noopener noreferrer"&gt;Streamlit Cookbook&lt;/a&gt;. (And don’t forget to show us what you’re building in the &lt;a href="https://discuss.streamlit.io/c/streamlit-examples/9" rel="noopener noreferrer"&gt;forum&lt;/a&gt;!)&lt;/p&gt;

&lt;p&gt;Happy Streamlit-ing! 🎈&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vectordatabase</category>
      <category>weaviate</category>
      <category>streamlit</category>
    </item>
    <item>
      <title>How to create an AI chatbot using one API to access multiple LLMs</title>
      <dc:creator>Streamlit</dc:creator>
      <pubDate>Fri, 23 Aug 2024 20:58:30 +0000</pubDate>
      <link>https://dev.to/streamlit/how-to-create-an-ai-chatbot-using-one-api-to-access-multiple-llms-452n</link>
      <guid>https://dev.to/streamlit/how-to-create-an-ai-chatbot-using-one-api-to-access-multiple-llms-452n</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://blog.streamlit.io/how-to-create-an-ai-chatbot-llm-api-replicate-streamlit/" rel="noopener noreferrer"&gt;Streamlit blog&lt;/a&gt; by &lt;a href="https://blog.streamlit.io/author/liz/" rel="noopener noreferrer"&gt;Liz Acosta&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Remember how cool it was playing with an AI image generator for the first time? Those twenty million fingers and nightmare spaghetti-eating images were more than just amusing, they inadvertently revealed that oops! AI models are only as smart as we are. Like us, they also struggle to draw hands.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvwx0q92zi8nmoy1ml5n.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvwx0q92zi8nmoy1ml5n.jpeg" alt="An AI generated image of a man eating spaghetti really weirdly." width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI models have quickly become more sophisticated, but now there are so many of them. And – again – like us, some of them are better at certain tasks than others. Take text generation, for example. Even though Llama, Gemma, and Mistral are all LLMs, some of them are better at generating code while others are better at brainstorming, coding, or creative writing. They offer different advantages depending on the prompt, so it may make sense to include more than one model in your AI application.&lt;/p&gt;

&lt;p&gt;But &lt;em&gt;how&lt;/em&gt; do you integrate all these models into your app &lt;em&gt;without&lt;/em&gt; duplicating code? How do you make your use of AI more modular and therefore easier to maintain and scale? That’s where an API can offer a standardized set of instructions for communicating across different technologies.&lt;/p&gt;

&lt;p&gt;In this blog post, we’ll take a look at how to use Replicate with Streamlit to create an app that allows you to configure and prompt different LLMs with a single API call. And don’t worry – when I say “app,” I don’t mean having to spin up a whole Flask server or tediously configure your routes or worry about CSS. Streamlit’s got that covered for you 😉&lt;/p&gt;

&lt;p&gt;Read on to learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Replicate is&lt;/li&gt;
&lt;li&gt;What Streamlit is&lt;/li&gt;
&lt;li&gt;How to build a demo Replicate chatbot Streamlit app&lt;/li&gt;
&lt;li&gt;And best practices for using Replicate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don’t feel like reading? Here are some other ways to explore this demo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find the code in the Streamlit Cookbook repo &lt;a href="https://github.com/streamlit/cookbook/tree/main/recipes/replicate" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Try out a deployed version of the app &lt;a href="https://replicate-recipe.streamlit.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Watch a video walkthrough from Replicate founding designer, Zeke Sikelianos, &lt;a href="https://youtu.be/zsQ7EN10zj8" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Replicate?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://replicate.com/" rel="noopener noreferrer"&gt;Replicate&lt;/a&gt; is a platform that enables developers to deploy, fine tune, and access open source AI models via a CLI, API, or SDK. The platform makes it easy to programmatically integrate AI capabilities into software applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Available models on Replicate
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text&lt;/strong&gt;: Models like &lt;a href="https://replicate.com/meta/meta-llama-3-8b-instruct" rel="noopener noreferrer"&gt;Llama 3&lt;/a&gt; can generate coherent and contextually relevant text based on input prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt;: Models like &lt;a href="https://replicate.com/stability-ai/stable-diffusion" rel="noopener noreferrer"&gt;stable diffusion&lt;/a&gt; can generate high-quality images from text prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech&lt;/strong&gt;: Models like &lt;a href="https://replicate.com/openai/whisper" rel="noopener noreferrer"&gt;whisper&lt;/a&gt; can convert speech to text while models like &lt;a href="https://replicate.com/lucataco/xtts-v2" rel="noopener noreferrer"&gt;xtts-v2&lt;/a&gt; can generate natural-sounding speech.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video&lt;/strong&gt;: Models like &lt;a href="https://replicate.com/lucataco/animate-diff" rel="noopener noreferrer"&gt;animate-diff&lt;/a&gt; or variants of stable diffusion like &lt;a href="https://replicate.com/cjwbw/videocrafter" rel="noopener noreferrer"&gt;videocrafter&lt;/a&gt; can generate and/or edit videos from text and image prompts, respectively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When used together, Replicate allows you to develop multimodal apps that can accept input and generate output in various formats whether it be text, image, speech, or video. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Streamlit?
&lt;/h2&gt;

&lt;p&gt;Streamlit is an open-source Python framework to build highly interactive apps – in only a few lines of code. Streamlit integrates with all the latest tools in &lt;a href="https://streamlit.io/generative-ai" rel="noopener noreferrer"&gt;generative AI&lt;/a&gt;, such as any LLM, vector database, or various AI frameworks like &lt;a href="https://blog.streamlit.io/langchain-streamlit/" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt;, &lt;a href="https://blog.streamlit.io/build-a-chatbot-with-custom-data-sources-powered-by-llamaindex/" rel="noopener noreferrer"&gt;LlamaIndex&lt;/a&gt;, or Weights &amp;amp; Biases. Streamlit’s &lt;a href="https://docs.streamlit.io/develop/api-reference/chat" rel="noopener noreferrer"&gt;chat elements&lt;/a&gt; make it especially easy to interact with AI so you can build chatbots that “talk to your data.”&lt;/p&gt;

&lt;p&gt;Combined with a platform like Replicate, Streamlit allows you to create generative AI applications without any of the app design overhead.&lt;/p&gt;

&lt;p&gt;💡 To learn more about how Streamlit biases you toward forward progress, check out this &lt;a href="https://blog.streamlit.io/just-build-it-streamlit-opinionated-framework/" rel="noopener noreferrer"&gt;blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To learn more about Streamlit, &lt;a href="https://blog.streamlit.io/streamlit-101-python-data-app/" rel="noopener noreferrer"&gt;check out the 101 guide&lt;/a&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Try the app recipe: Replicate + Streamlit
&lt;/h2&gt;

&lt;p&gt;But don’t take my word for it. Try out &lt;a href="https://replicate-recipe.streamlit.app/" rel="noopener noreferrer"&gt;the app yourself&lt;/a&gt; or &lt;a href="https://youtu.be/zsQ7EN10zj8" rel="noopener noreferrer"&gt;watch a video walk through&lt;/a&gt; and see what you think. &lt;/p&gt;

&lt;p&gt;In this demo, you’ll spin up a Streamlit chatbot app with Replicate. The app uses a single API to access three different LLMs and adjust parameters such as temperature and top-p. These parameters influence the randomness and diversity of the AI-generated text, as well as the method by which tokens are selected.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;What is model temperature?&lt;/strong&gt; Temperature controls how the model selects tokens. A lower temperature makes the model more conservative, favoring common and “safe” words. Conversely, a higher temperature encourages the model to take more risks by selecting less probable tokens, resulting in more creative outputs.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;What is top-p?&lt;/strong&gt; Also known as “nucleus sampling” — is another method for adjusting randomness. It works by considering a broader set of tokens as the top-p value increases. A higher top-p value leads to a more diverse range of tokens being sampled, producing more varied outputs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Python version &amp;gt;=3.8, !=3.9.7&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://replicate.com/signin?next=/account/api-tokens" rel="noopener noreferrer"&gt;Replicate API key&lt;/a&gt;
(Please note that a payment method is required to access features beyond the free trial limits.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 To learn more about API keys, check out the blog post &lt;a href="https://blog.streamlit.io/8-tips-for-securely-using-api-keys/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment setup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Local setup&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the Cookbook repo: &lt;code&gt;git clone https://github.com/streamlit/cookbook.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;From the Cookbook root directory, change directory into the Replicate recipe: &lt;code&gt;cd recipes/replicate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add your Replicate API key to the &lt;code&gt;.streamlit/secrets_template.toml&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;Update the filename from &lt;code&gt;secrets_template.toml&lt;/code&gt; to &lt;code&gt;secrets.toml&lt;/code&gt;: &lt;code&gt;mv .streamlit/secrets_template.toml .streamlit/secrets.toml&lt;/code&gt;
(To learn more about secrets handling in Streamlit, refer to the documentation &lt;a href="https://docs.streamlit.io/develop/concepts/connections/secrets-management" rel="noopener noreferrer"&gt;here&lt;/a&gt;.)&lt;/li&gt;
&lt;li&gt;Create a virtual environment: &lt;code&gt;python -m venv replicatevenv&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Activate the virtual environment: &lt;code&gt;source replicatevenv/bin/activate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install the dependencies: &lt;code&gt;pip install -r requirements.txt&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/features/codespaces" rel="noopener noreferrer"&gt;GitHub Codespaces&lt;/a&gt; setup&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;From the Cookbook repo on GitHub, create a new codespace by selecting the &lt;code&gt;Codespaces&lt;/code&gt; option from the &lt;code&gt;Code&lt;/code&gt; button &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---YrYAF72--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-rt.googleusercontent.com/docsz/AD_4nXd30IZpZnjtyWBJpMFpB85Wcl4oujtML69aRtNYhKaeIUs8poTx0JySj_A5vKTzZQi1gztyFS8B1XCIoK7e5rMQi4qEQRh6XMH4bwo4DP0hOHCH4KZazjsb63d7YDdaLTL6xBkW3iXSG8wnpTW20qB1v9g2%3Fkey%3DXZj3BdzpB11OGJG4ELwXuQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---YrYAF72--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-rt.googleusercontent.com/docsz/AD_4nXd30IZpZnjtyWBJpMFpB85Wcl4oujtML69aRtNYhKaeIUs8poTx0JySj_A5vKTzZQi1gztyFS8B1XCIoK7e5rMQi4qEQRh6XMH4bwo4DP0hOHCH4KZazjsb63d7YDdaLTL6xBkW3iXSG8wnpTW20qB1v9g2%3Fkey%3DXZj3BdzpB11OGJG4ELwXuQ" title="image_tooltip" alt="A screenshot of GitHub codespaces" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the codespace has been generated, add your Replicate API key to the &lt;code&gt;recipes/replicate/.streamlit/secrets_template.toml&lt;/code&gt; file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the filename from &lt;code&gt;secrets_template.toml&lt;/code&gt; to &lt;code&gt;secrets.toml&lt;/code&gt;&lt;br&gt;
(To learn more about secrets handling in Streamlit, refer to the documentation &lt;a href="https://docs.streamlit.io/develop/concepts/connections/secrets-management" rel="noopener noreferrer"&gt;here&lt;/a&gt;.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the Cookbook root directory, change directory into the Replicate recipe: &lt;code&gt;cd recipes/replicate&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the dependencies: &lt;code&gt;pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Run a text generation model with Replicate
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Create a file in the &lt;code&gt;recipes/replicate&lt;/code&gt; directory called &lt;code&gt;replicate_hello_world.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following code to the file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;replicate&lt;/span&gt;   

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;toml&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="c1"&gt;# Read the secrets from the secrets.toml file
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.streamlit/secrets.toml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;secrets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;toml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create an environment variable for the Replicate API token 
&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;REPLICATE_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;REPLICATE_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Run a model
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;replicate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;meta/meta-llama-3-8b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is Streamlit?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the script: &lt;code&gt;python replicate_hello_world.py&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You should see a print out of the text generated by the model.&lt;/p&gt;

&lt;p&gt;To learn more about Replicate models and how they work, you can refer to their documentation &lt;a href="https://replicate.com/docs/reference/how-does-replicate-work" rel="noopener noreferrer"&gt;here&lt;/a&gt;. At its core, a Replicate “model” refers to a trained, packaged, and published software program that accepts inputs and returns outputs.&lt;/p&gt;

&lt;p&gt;In this particular case, the model is &lt;code&gt;meta/meta-llama-3-8b&lt;/code&gt; and the input is &lt;code&gt;"prompt": "What is Streamlit?"&lt;/code&gt;. When you run the script, a call is made to the Replicate endpoint and the printed text is the output returned from the model via Replicate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run the demo Replicate Streamlit chatbot app
&lt;/h3&gt;

&lt;p&gt;To run the demo app, use the Streamlit CLI: &lt;code&gt;streamlit run streamlit_app.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Running this command deploys the app to a port on &lt;code&gt;localhost&lt;/code&gt;. When you access this location, you should see a Streamlit app running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zUp6BPuI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-rt.googleusercontent.com/docsz/AD_4nXcqrpBFcEhZ0MlHHcuAt8jiDYknILLfz8vfU3DJVjvwrHLkiw92WLGNNPnxFJ4vUW6zJtb689KA-TBuJoA0QwOjJsOcgrSviBWyNlCvvlh_udku-0_O3MjFabQW7aa5qTVtBWuCFSnj5OEaiwcaHlXwrFA%3Fkey%3DXZj3BdzpB11OGJG4ELwXuQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zUp6BPuI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-rt.googleusercontent.com/docsz/AD_4nXcqrpBFcEhZ0MlHHcuAt8jiDYknILLfz8vfU3DJVjvwrHLkiw92WLGNNPnxFJ4vUW6zJtb689KA-TBuJoA0QwOjJsOcgrSviBWyNlCvvlh_udku-0_O3MjFabQW7aa5qTVtBWuCFSnj5OEaiwcaHlXwrFA%3Fkey%3DXZj3BdzpB11OGJG4ELwXuQ" title="A gif of the demo app" alt="A gif of the demo app" width="800" height="575"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use this app to prompt different LLMs via Replicate and produce generative text according to the configurations you provide.&lt;/p&gt;

&lt;h3&gt;
  
  
  A common API for multiple LLM models
&lt;/h3&gt;

&lt;p&gt;Using Replicate means you can prompt multiple open source LLMs with one API which helps simplify AI integration into modern software flows.&lt;/p&gt;

&lt;p&gt;This is accomplished in the following block of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;replicate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                             &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt_template&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{prompt}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                             &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;top_p&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;top_p&lt;/span&gt;&lt;span class="p"&gt;,}):&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;model&lt;/code&gt;, &lt;code&gt;temperature&lt;/code&gt;, and &lt;code&gt;top p&lt;/code&gt; configurations are provided by the user via Streamlit’s &lt;a href="https://docs.streamlit.io/develop/api-reference#input-widgets" rel="noopener noreferrer"&gt;input widgets&lt;/a&gt;. Streamlit’s &lt;a href="https://docs.streamlit.io/develop/api-reference#chat-elements" rel="noopener noreferrer"&gt;chat elements&lt;/a&gt; make it easy to integrate chatbot features in your app. The best part is you don’t need to know JavaScript or CSS to implement and style these components – Streamlit provides all of that right out of the box.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replicate best practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use the best model for the prompt
&lt;/h3&gt;

&lt;p&gt;Replicate provides an API endpoint to search for public models. You can also explore featured models and use cases on their website. This makes it easy to find the right model for your specific needs.&lt;/p&gt;

&lt;p&gt;Different models have different performance characteristics. Use the appropriate model based on your needs for accuracy and speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improve performance with webhooks, streaming, and image URLs
&lt;/h3&gt;

&lt;p&gt;Replicate's output data is only available for an hour. Use webhooks to save the data to your own storage. You can also set up webhooks to handle asynchronous responses from models. This is crucial for building scalable applications.&lt;/p&gt;

&lt;p&gt;Leverage streaming when possible. Some models support streaming, allowing you to get partial results as they are being generated. This is ideal for real-time applications.&lt;/p&gt;

&lt;p&gt;Using image URLs provides improved performance over the use of uploaded images encoded by base 64.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unlock the potential of AI with Streamlit
&lt;/h2&gt;

&lt;p&gt;With Streamlit, months and months of app design work are &lt;em&gt;streamlined&lt;/em&gt; to just a few lines of Python. It’s the perfect framework for showing off your latest AI inventions. &lt;/p&gt;

&lt;p&gt;Get up and running &lt;strong&gt;&lt;em&gt;fast&lt;/em&gt;&lt;/strong&gt; with other AI recipes in the &lt;a href="https://github.com/streamlit/cookbook/tree/main" rel="noopener noreferrer"&gt;Streamlit Cookbook&lt;/a&gt;. (And don’t forget to show us what you’re building in the &lt;a href="https://discuss.streamlit.io/c/streamlit-examples/9" rel="noopener noreferrer"&gt;forum&lt;/a&gt;!)&lt;/p&gt;

&lt;p&gt;Happy Streamlit-ing! 🎈&lt;/p&gt;

</description>
      <category>streamlit</category>
      <category>python</category>
      <category>llm</category>
      <category>replicate</category>
    </item>
    <item>
      <title>Streamlit 101: The fundamentals of a Python data app</title>
      <dc:creator>Streamlit</dc:creator>
      <pubDate>Tue, 20 Aug 2024 20:28:49 +0000</pubDate>
      <link>https://dev.to/streamlit/streamlit-101-the-fundamentals-of-a-python-data-app-2k3f</link>
      <guid>https://dev.to/streamlit/streamlit-101-the-fundamentals-of-a-python-data-app-2k3f</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://blog.streamlit.io/streamlit-101-python-data-app/" rel="noopener noreferrer"&gt;Streamlit blog&lt;/a&gt; by &lt;a href="https://blog.streamlit.io/author/chanin/" rel="noopener noreferrer"&gt;Chanin Nantasenamat&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Picture this: You’re a data scientist and the company you work for needs to make some decisions – fast! You need a way to munge the numbers, investigate emerging trends, and help your stakeholders take action on those trends. You know that a data app would be the perfect solution for the job, but you don’t have time to get bogged down in complex web development, tedious UI styling, or slow iteration cycles.&lt;/p&gt;

&lt;p&gt;Creating interactive data applications shouldn't be this hard! 😭&lt;/p&gt;

&lt;p&gt;This is exactly why Streamlit exists.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll cover the fundamentals of Streamlit, how it works, and how you can get started with it. You can find the example code for this post &lt;a href="https://github.com/sfc-gh-cnantasenamat/streamlit101" rel="noopener noreferrer"&gt;here&lt;/a&gt; or &lt;a href="https://www.youtube.com/watch?v=UI4f4iiVT6c" rel="noopener noreferrer"&gt;watch the step-by-step video tutorial&lt;/a&gt; on YouTube.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Streamlit?
&lt;/h2&gt;

&lt;p&gt;Streamlit is an open-source Python framework to build highly interactive data apps – in only a few lines of code. The point of Streamlit is to allow you to focus on what’s most important to you: Your data analysis!  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intuitive syntax&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of Streamlit’s standout features is that it has intuitive default styles “baked in” so you can deploy and share polished apps with anyone anywhere. For example, to write a header, you use &lt;code&gt;st.header()&lt;/code&gt;. To add some text, you use &lt;code&gt;st.write()&lt;/code&gt;. Need a divider? Just use &lt;code&gt;st.divider()&lt;/code&gt;. No CSS, HTML, or JavaScript experience required!  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seamlessly composable, AI compatible&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With Streamlit, you don’t have to do any “app thinking” – you don’t have to think about the UI, the styling, or the routing. Streamlit simply extends what you’re already doing in Python. &lt;/p&gt;

&lt;p&gt;It's compatible with a wide range of data libraries, including &lt;a href="https://pandas.pydata.org/" rel="noopener noreferrer"&gt;Pandas&lt;/a&gt;, &lt;a href="https://numpy.org/" rel="noopener noreferrer"&gt;NumPy&lt;/a&gt;, and &lt;a href="https://altair-viz.github.io/" rel="noopener noreferrer"&gt;Altair&lt;/a&gt;. Streamlit integrates with all the latest tools in &lt;a href="https://streamlit.io/generative-ai" rel="noopener noreferrer"&gt;generative AI&lt;/a&gt;, such as any LLM, vector database, or various AI frameworks like &lt;a href="https://blog.streamlit.io/langchain-streamlit/" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt;, &lt;a href="https://blog.streamlit.io/build-a-chatbot-with-custom-data-sources-powered-by-llamaindex/" rel="noopener noreferrer"&gt;LlamaIndex&lt;/a&gt;, or Weights &amp;amp; Biases. Streamlit’s &lt;a href="https://docs.streamlit.io/develop/api-reference/chat" rel="noopener noreferrer"&gt;chat elements&lt;/a&gt; make it especially easy to interact with AI so you can build chatbots that “talk to your data.” &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your go-to UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Streamlit gets you to a working version 0 of your app faster. You can get your app in front of users faster, get feedback faster, and improve faster. Streamlit makes your iteration cycles shorter.&lt;/p&gt;

&lt;p&gt;Today the Streamlit community has over 300k monthly active developers and is used by 80% of Fortune 50 companies. Whether you’re on a data team, a seasoned data scientist, or a new Python developer, the possibilities with Streamlit are endless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with Streamlit using Codespaces
&lt;/h2&gt;

&lt;p&gt;There are many ways to get &lt;a href="https://docs.streamlit.io/get-started/installation" rel="noopener noreferrer"&gt;started with Streamlit&lt;/a&gt;. For this blog post, we are going to use GitHub Codespaces. Codespaces is a cloud-hosted development environment where you can use an &lt;a href="https://docs.streamlit.io/get-started/installation/community-cloud" rel="noopener noreferrer"&gt;in-browser editor to start coding&lt;/a&gt; with Streamlit.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Launch Codespaces&lt;/p&gt;

&lt;p&gt;Start by launching Codespaces from within your GitHub account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r_1etZoK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.streamlit.io/content/images/2024/07/image-2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r_1etZoK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://blog.streamlit.io/content/images/2024/07/image-2.jpg" title="A screenshot of how to create a new GitHub codespace" alt="A screenshot of how to create a new GitHub codespace" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Spin up a new instance&lt;/p&gt;

&lt;p&gt;Create a new instance using a blank Codespaces template.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uHiWiVyH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXcSxIVjF0V0oWiEU14zedw2VT4_XeN7qpAXsrW9er9fdKLdbEEoacsMI2uKXzZ8d2b-tX7Jga5grK1Qx6jx3tKjU3LV3KvK3Uw47MTgfKettVnhMPC1IP0Oy_Q75LFEeXF6SjiOsRkRXkL5yQNehfuzrMur%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uHiWiVyH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXcSxIVjF0V0oWiEU14zedw2VT4_XeN7qpAXsrW9er9fdKLdbEEoacsMI2uKXzZ8d2b-tX7Jga5grK1Qx6jx3tKjU3LV3KvK3Uw47MTgfKettVnhMPC1IP0Oy_Q75LFEeXF6SjiOsRkRXkL5yQNehfuzrMur%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" title="A screenshot of how to create a new GitHub codespace" alt="A screenshot of how to create a new GitHub codespace" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Streamlit &lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;pip install streamlit&lt;/code&gt; to install the framework.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o4b8wUe1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXccCl9kzxDJaxQ-juTQxa1STrG4QNsaWotQaj_IBkfmRhEkO0ipM5hgRBAjWHw9B39aImEp1KJnOPL5aMmC-jp5eOJVbN5MQrfmIlKLcLo1imt9K0psvF79SjFWSvPeqOCXOaclB_RFOBpkRT24ejBdI0g%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o4b8wUe1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXccCl9kzxDJaxQ-juTQxa1STrG4QNsaWotQaj_IBkfmRhEkO0ipM5hgRBAjWHw9B39aImEp1KJnOPL5aMmC-jp5eOJVbN5MQrfmIlKLcLo1imt9K0psvF79SjFWSvPeqOCXOaclB_RFOBpkRT24ejBdI0g%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" title="A screenshot of how to create a new GitHub codespace" alt="A screenshot of how to create a new GitHub codespace" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a simple app &lt;/p&gt;

&lt;p&gt;You can create a basic “Hello world” app in just two lines of code by creating a new Python file called &lt;code&gt;streamlit_app.py&lt;/code&gt; and adding the following code to it:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import streamlit as st

st.write("My first Streamlit app 🎈")
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run your app&lt;/p&gt;

&lt;p&gt;Run your new app with the command &lt;code&gt;streamlit run streamlit_app.py&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;View your app &lt;/p&gt;

&lt;p&gt;Your app should appear in a new browser tab – see how quick that was?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bAo-ljK9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXePMmfH6AFNQ4zqWZfyMth9Hx6l8GKjG2JbejsMLQdXgVVsycKgiOOeqyaKoN5YQ2BNHeXZUaw6d5QX3W1kTbl0O-Osy2V3mWRkOSSDM0DydiICQ80e4D_o_nXtRZyYfRPedKhUMHpHXrtfohIVdRvdJZQ%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bAo-ljK9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXePMmfH6AFNQ4zqWZfyMth9Hx6l8GKjG2JbejsMLQdXgVVsycKgiOOeqyaKoN5YQ2BNHeXZUaw6d5QX3W1kTbl0O-Osy2V3mWRkOSSDM0DydiICQ80e4D_o_nXtRZyYfRPedKhUMHpHXrtfohIVdRvdJZQ%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" title="A screenshot of a Streamlit app" alt="A screenshot of a Streamlit app" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we have our first Streamlit app built out, let’s see how we can extend the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a typical Streamlit app
&lt;/h2&gt;

&lt;p&gt;The most important part of a good data app is effectively visualizing your data analysis so insights are easier to glean. Interactivity helps users explore the data.&lt;/p&gt;

&lt;p&gt;Let’s take a look at different ways to visualize data and add interaction with Streamlit. &lt;/p&gt;

&lt;h3&gt;
  
  
  Load your data
&lt;/h3&gt;

&lt;p&gt;Before we get into any of the example data visualizations, we need to load our data. The following code uses Pandas to create a function that loads the data from a CSV file.&lt;/p&gt;

&lt;p&gt;Then we use the &lt;code&gt;@st.cache_data&lt;/code&gt; decorator to speed up our app. Learn more about caching in Streamlit &lt;a href="https://docs.streamlit.io/develop/api-reference/caching-and-state/st.cache_data" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Make sure to add Pandas to your imports before you use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@st.cache_data

def load_data():

return pd.read_csv("https://github.com/dataprofessor/population-dashboard/raw/master/data/us-population-2010-2019-reshaped.csv", index_col=0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 1: Inspect your data
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.streamlit.io/develop/api-reference/data/st.data_editor" rel="noopener noreferrer"&gt;&lt;code&gt;st.data_editor&lt;/code&gt;&lt;/a&gt; displays data in an editable table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;st.header("1. Inspect the data 🔍")

st.write("`st.data_editor` allows us to display AND edit data")

st.data_editor(df)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6kOCgMJH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXcisoLGAfViq1nlp0zIBr4bRujnSFumdN6vBXp42ILE84x9sk7WzEnNrEZ6GlBWpaW2GbCt6Dn8QjJRFRRselNnyTZGHb6Uowk2iRwpE3MNeHQR1LzMAy6ZPq85PcSKTCQtikBe-8WE2DBSAHSfQ7C5JYC6%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6kOCgMJH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXcisoLGAfViq1nlp0zIBr4bRujnSFumdN6vBXp42ILE84x9sk7WzEnNrEZ6GlBWpaW2GbCt6Dn8QjJRFRRselNnyTZGHb6Uowk2iRwpE3MNeHQR1LzMAy6ZPq85PcSKTCQtikBe-8WE2DBSAHSfQ7C5JYC6%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" title="A screenshot of a data editor in the Streamlit app" alt="A screenshot of a data editor in the Streamlit app" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2: A simple bar chart
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.streamlit.io/develop/api-reference/charts/st.bar_chart" rel="noopener noreferrer"&gt;&lt;code&gt;st.bar_chart&lt;/code&gt;&lt;/a&gt; displays the data in a bar chart form. In the following code, we create a bar chart with our data and declare the x and y axis as states and population, respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;st.header("2. Get started with a simple bar chart 📊")

st.write("Let's chart the US state population data from the year 2019")

st.bar_chart(df[['year', 'states', 'population']],

             x='states',

             y='population')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cEhHbdWj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXdVSPkDSXv3QcMMAgOwZwtHBD9yT1MdFX-Q9mg1yQseJaF-FbSlAVolZEGLrT36F2EVHNUKVtM6wtwRw7RWMr0pEgPFo5T5akv9Qo-YaXUOT_umzjR443bb8ESMlGw7aWLQyWPFm62jWqVngI3fvcKZko0%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cEhHbdWj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXdVSPkDSXv3QcMMAgOwZwtHBD9yT1MdFX-Q9mg1yQseJaF-FbSlAVolZEGLrT36F2EVHNUKVtM6wtwRw7RWMr0pEgPFo5T5akv9Qo-YaXUOT_umzjR443bb8ESMlGw7aWLQyWPFm62jWqVngI3fvcKZko0%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" title="A screenshot of a bar chart in the Streamlit app" alt="A screenshot of a bar chart in the Streamlit app" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 3: Add interactivity to a bar chart
&lt;/h3&gt;

&lt;p&gt;The more interactive your app, the more your data comes to life for your users. With Streamlit, it’s easy to add &lt;a href="https://docs.streamlit.io/develop/api-reference/widgets/st.selectbox" rel="noopener noreferrer"&gt;selection boxes&lt;/a&gt;, &lt;a href="https://docs.streamlit.io/develop/api-reference/widgets/st.slider" rel="noopener noreferrer"&gt;sliders&lt;/a&gt;, and &lt;a href="https://docs.streamlit.io/develop/api-reference/widgets/st.number_input" rel="noopener noreferrer"&gt;numerical inputs&lt;/a&gt; so users can explore your data.&lt;/p&gt;

&lt;p&gt;The following code contains three different types of interactivity. Comment and uncomment the code to see which one suits your needs the best.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;st.header("3. Now make it interactive")

st.write("It's your turn to select a year")

# Using st.selectbox

selected_year = st.selectbox("Select a year",

                             list(df.year.unique())[::-1])

# Using st.slider

# selected_year = st.slider("Select a year", 2010, 2019)

# Using st.number_input

# selected_year = st.number_input("Enter a year",

# placeholder="Enter a year from 2010-2019", value=2019)

if selected_year:

    df_selected_year = df[df.year == selected_year]

    # Display chart

    st.bar_chart(df_selected_year,

                 x='states',

                 y='population')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H6PtSnrw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXcaiE7OD3EGLdPAVMBe6N7TQD-IekYIWMJP3yKJl7wtpYqWqC9Sddm9bIIS_RYbByB9YeW8IsMmxZVfLrXJnHDVy9M2JqbWIemuqIHy43cAa0Bu9Yei_Nm7dia79IV7sRD44VHdJJ5dwl7fd5N2mrKFTGkz%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H6PtSnrw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXcaiE7OD3EGLdPAVMBe6N7TQD-IekYIWMJP3yKJl7wtpYqWqC9Sddm9bIIS_RYbByB9YeW8IsMmxZVfLrXJnHDVy9M2JqbWIemuqIHy43cAa0Bu9Yei_Nm7dia79IV7sRD44VHdJJ5dwl7fd5N2mrKFTGkz%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" title="A screenshot of a bar chart in the Streamlit app" alt="A screenshot of a bar chart in the Streamlit app" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 4: Integrate another Python library to create a line chart
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.streamlit.io/develop/api-reference/charts/st.altair_chart" rel="noopener noreferrer"&gt;&lt;code&gt;st.altair_chart&lt;/code&gt;&lt;/a&gt; uses the Vega-Altair library to display data as a line chart. Please note that you’ll have to import Altair before you can use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
st.header("4. How about a line chart? 📈")

st.write("Track changes over time")

df_line_chart = df.copy()

df_line_chart['year'] = df_line_chart['year'].astype(str)

c = (

    alt.Chart(df_line_chart)

     .mark_line()

     .encode(x=alt.X('year'),

             y=alt.Y('population'),

             color='states')

)

st.altair_chart(c, use_container_width=True)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9eFynXer--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXf5av0wPXTWAsy1B2mt3lxTNGJl5P1zojc7PO26LytAxjhdwGX5B8g8fngeBCJkVhm9OQ3hM7vk6EE_tA2_2fsLZ--ANY7Tpdci55i6pnCK9swsoWZ2i6nhVzHHMQxTqbL-tA3jAzb22m1PulgP_OHLgxE%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9eFynXer--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXf5av0wPXTWAsy1B2mt3lxTNGJl5P1zojc7PO26LytAxjhdwGX5B8g8fngeBCJkVhm9OQ3hM7vk6EE_tA2_2fsLZ--ANY7Tpdci55i6pnCK9swsoWZ2i6nhVzHHMQxTqbL-tA3jAzb22m1PulgP_OHLgxE%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" title="A screenshot of a line chart in a Streamlit app" alt="A screenshot of a line chart in a Streamlit app" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 5: Add interactivity to an Altair line chart
&lt;/h3&gt;

&lt;p&gt;Like the bar chart above, you can add interactivity to a line chart with &lt;a href="https://docs.streamlit.io/develop/api-reference/widgets/st.multiselect" rel="noopener noreferrer"&gt;&lt;code&gt;st.multiselect&lt;/code&gt;&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;st.header("5. Sprinkle in more interactivity")

st.write("Use `st.multiselect` and `st.slider` for data filter before chart creation")

states = st.multiselect("Pick your states",

                        list(df.states.unique())[::-1],

                        "California")

date_range = st.slider("Pick your date range",

                       2010, 2019,

                       (2010, 2019))

if states:

    chart_data = df[df['states'].isin(states)]

    chart_data = chart_data[chart_data['year'].between(date_range[0], date_range[1])]

    chart_data['year'] = chart_data['year'].astype(str)

    c = (

        alt.Chart(chart_data)

         .mark_line()

         .encode(x=alt.X('year'),

                 y=alt.Y('population'),

                 color='states')

    )

    st.altair_chart(c, use_container_width=True)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sibSLCc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXdgv0U1lX3l3n5mB3J1VBs2_1GKCz0y4GUplOUeo4ju3knvCiDbCs6VXjHqiEw58iEfVY5gsJKj3fFCig-EMZD3eX0t0Xi3d9deTDemiDzjTksNx8eiJ6QqZJj_jqSCBpQEnXyiUwyUBMMDtap3U7PoyKk%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sibSLCc4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://lh7-us.googleusercontent.com/docsz/AD_4nXdgv0U1lX3l3n5mB3J1VBs2_1GKCz0y4GUplOUeo4ju3knvCiDbCs6VXjHqiEw58iEfVY5gsJKj3fFCig-EMZD3eX0t0Xi3d9deTDemiDzjTksNx8eiJ6QqZJj_jqSCBpQEnXyiUwyUBMMDtap3U7PoyKk%3Fkey%3DQmeZUXI9p9_0ZjPMOWbOTQ" title="A screenshot of a line chart in a Streamlit app" alt="A screenshot of a line chart in a Streamlit app" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The best part is you don’t have to deal with styling all of these different elements – Streamlit takes care of that for you!&lt;/p&gt;

&lt;h2&gt;
  
  
  Extending Streamlit functionality
&lt;/h2&gt;

&lt;p&gt;And that’s just the beginning! To find the right API for your needs, check out the &lt;a href="https://docs.streamlit.io/develop/api-reference" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While Streamlit's native framework is flexible enough for most use cases, there may be times when you need to extend its functionality. The Streamlit community has built hundreds of reusable components that you can easily integrate into your app. These custom-built components turn complex JavaScript code into a single line of Python, making it easier than ever to add advanced features to your app.&lt;/p&gt;

&lt;p&gt;You can find available components &lt;a href="https://streamlit.io/components" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying Streamlit apps
&lt;/h2&gt;

&lt;p&gt;Deploying your Streamlit app is straightforward and can be done in several ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local Deployment:&lt;/strong&gt; Run your app locally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server Deployment:&lt;/strong&gt; Deploy your app on your preferred server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://streamlit.io/cloud" rel="noopener noreferrer"&gt;Streamlit Community Cloud&lt;/a&gt;:&lt;/strong&gt; A completely free way to deploy and share your apps. With millions of views each month, public apps on Streamlit Community Cloud are indexable by Google and can be discovered by anyone around the world. It's a fantastic way to showcase your creativity – whether you're building chatbots, visualizing machine learning models, creating internal tools, or working on your latest passion project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To learn more about different deployment options, read the documentation &lt;a href="https://docs.streamlit.io/deploy" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling with Snowflake
&lt;/h2&gt;

&lt;p&gt;For those looking for extended scale and security, Streamlit also works seamlessly on the Snowflake platform, where all infrastructure and role-based governance are handled for you. To learn more about Streamlit in Snowflake, refer to the documentation &lt;a href="https://docs.snowflake.com/developer-guide/streamlit/about-streamlit" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What will you build?
&lt;/h2&gt;

&lt;p&gt;Streamlit is revolutionizing the way we build and share data applications. Its speed, intuitive syntax, and seamless composability make it an invaluable tool for anyone working with data. Dive into Streamlit today and start building your own interactive data apps.&lt;/p&gt;

&lt;p&gt;We can't wait to see what you create!&lt;/p&gt;

&lt;p&gt;Happy Streamlit-ing! 🎈&lt;/p&gt;

</description>
      <category>streamlit</category>
      <category>python</category>
      <category>dataapp</category>
      <category>datavisualization</category>
    </item>
    <item>
      <title>Just build it</title>
      <dc:creator>Streamlit</dc:creator>
      <pubDate>Tue, 13 Aug 2024 01:29:31 +0000</pubDate>
      <link>https://dev.to/streamlit/just-build-it-how-we-design-streamlit-to-bias-you-toward-forward-progress-520d</link>
      <guid>https://dev.to/streamlit/just-build-it-how-we-design-streamlit-to-bias-you-toward-forward-progress-520d</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on the &lt;a href="https://blog.streamlit.io/just-build-it-streamlit-opinionated-framework/" rel="noopener noreferrer"&gt;Streamlit blog&lt;/a&gt; by &lt;a href="https://blog.streamlit.io/author/thiago/" rel="noopener noreferrer"&gt;Thiago Teixeira&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you’re reading this, you’re probably already familiar with Streamlit. If not, here’s a summary: Streamlit is a Python framework for building data apps. It’s opinionated, it has batteries included, and it’s deeply tied to a specific design system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It’s focused on data apps.&lt;/strong&gt; Everything we do stems from this. We don’t target generic apps like the ones on your phone or your favorite SaaS, but the kinds of apps data scientists and ML engineers need to make their work impactful at their organizations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It’s opinionated&lt;/strong&gt; because we want to promote a fast, iterative workflow, and to uphold what we think are best practices in engineering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It has batteries included&lt;/strong&gt; so most of what you need to get started is in the library itself.&lt;/li&gt;
&lt;li&gt;And finally, &lt;strong&gt;it’s tied to a design system&lt;/strong&gt; so you don’t spend time building a component library, visual language, or identity. You just get started — and &lt;em&gt;fast&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, I could tell you about how we started Streamlit. About how it started from a good hunch, based on our previous experience in industry and academia. About how we dove deep into different companies and observed their data scientists and ML engineers at work in order to shape Streamlit. But&lt;a href="https://towardsdatascience.com/coding-ml-tools-like-you-code-ml-models-ddba3357eace" rel="noopener noreferrer"&gt; Adrien already did that very well 5 years ago&lt;/a&gt;, and I don’t think I can top it!&lt;/p&gt;

&lt;p&gt;So instead, I’ll talk about how our deep focus on data apps translates into product decisions we make every day. And for this, I’ll start with a tale …&lt;/p&gt;

&lt;h2&gt;
  
  
  The 10x new hire
&lt;/h2&gt;

&lt;p&gt;Once upon a time, a Data Science team built a powerful forecast model of the company’s most important metrics. The Finance Team saw it and loved it, and then asked for a live version they could use in their weekly meetings. So the Data Team filed a request with the Tools Team to build a data app, and the Tools Team put it on their queue.&lt;/p&gt;

&lt;p&gt;Three months and many meetings later, the app was delivered and it was beautiful. &lt;/p&gt;

&lt;p&gt;But there was a wrinkle: When Finance tried it out, it wasn’t quite what they needed. So they filed another request with the Data Team, who passed it onto the Tools Team, and the Tools Team put it on their queue. Many months passed.&lt;/p&gt;

&lt;p&gt;At that point, an unsuspecting New Hire joined the Data Team and was assigned a starter project: Putting together a quick data app to unblock the Finance Team while they waited for &lt;em&gt;the real app&lt;/em&gt; from the Tools Team.&lt;/p&gt;

&lt;p&gt;After some googling, the New Hire discovered Streamlit and, within a day, was able to share a minimal app with colleagues. It wasn’t perfect, but she addressed some of the feedback and updated the app. The next day, she showed it to her contact in the Finance Team, got more feedback, and refined the app accordingly.&lt;/p&gt;

&lt;p&gt;Within three days, the Finance Team was regularly using the app in their meetings. They had more feedback and the New Hire quickly addressed it in newer versions.&lt;/p&gt;

&lt;p&gt;Within a week, the CEO was using the app and the New Hire was hailed as a hero 💪&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this happens
&lt;/h2&gt;

&lt;p&gt;We’ve seen that story transpire countless times. The reason the New Hire’s app wins in the end is because &lt;strong&gt;a simple app today is better than an over-designed app 3 months late.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In fact, this is exactly how the best startups build their products! They ship a minimum viable product (&lt;a href="https://en.wikipedia.org/wiki/Minimum_viable_product" rel="noopener noreferrer"&gt;MVP&lt;/a&gt;), put it in customers’ hands as soon as possible, and iterate relentlessly.&lt;/p&gt;

&lt;p&gt;And in the process, they incrementally harden the underlying infrastructure. Because there’s a corollary to the New Hire’s story: As the team continues to use the app, they gradually productionize it.&lt;/p&gt;

&lt;p&gt;That set of bespoke Pandas transformations that are super slow? They pull it into a separate data pipeline and some materialized tables.&lt;/p&gt;

&lt;p&gt;That complex computation that other apps want to use? They move it into a RESTful service. They refactor the app into multiple pages as it grows. They write tests, they set up CI. And the app becomes bullet-proof.&lt;/p&gt;

&lt;p&gt;The benefits of this flow are clear:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You build better apps&lt;/strong&gt; because you often don’t know what you need until you try it out. So by building and user-testing, and building and user-testing again, you end up with a better app than if you had planned the whole thing ahead of time only to belatedly realize it’s not the solution you thought it was.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You get value from day 1.&lt;/strong&gt; As you’re building and user-testing, you &lt;em&gt;already&lt;/em&gt; have a useful app. And it only gets more and more useful along the way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You don’t overbuild.&lt;/strong&gt; Instead of building a pipeline at the same time as you build your app, you just get the app out and then harden it as it proves its usefulness. However, not all apps are useful, and not all useful apps live for long enough to require hardening. So you only spend your precious brain cycles on apps that are both useful and long-lived.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The way you start is simple: You &lt;strong&gt;just build it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intentional design
&lt;/h2&gt;

&lt;p&gt;We like to think that it’s no accident the New Hire’s story happens at so many different companies. We like to think this story happens because &lt;strong&gt;we intentionally design Streamlit to promote forward progress&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you first start writing an app, &lt;em&gt;forward progress&lt;/em&gt; means having a draft in 5 minutes that is already useful in &lt;em&gt;some&lt;/em&gt; way. And one thing that definitely makes an app more useful is interactivity. So, from early on, we had a strong sense that we should make interactivity as simple as possible. &lt;/p&gt;

&lt;p&gt;For example, you shouldn’t have to create a “View” with a slider in it, then a “Controller” with a callback function that modifies the “Model” used by the slider (in other words, the&lt;a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" rel="noopener noreferrer"&gt; MVC paradigm&lt;/a&gt;). Instead we came up with a single-line solution:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;value = st.slider("Pick a number", 0, 100)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You type that and get an app that already does something. &lt;em&gt;Forward progress!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then, when building&lt;a href="https://docs.streamlit.io/develop/api-reference/caching-and-state/st.session_state" rel="noopener noreferrer"&gt; Session State&lt;/a&gt; two years later, we quickly learned that the proposed API would easily lead to off-by-one errors, and the only solution that worked was callbacks. Scarred by our past experiences with MVC and similar paradigms, we spent quite some time on the problem to come up with a decidedly “&lt;em&gt;Streamlit-y”&lt;/em&gt; version of callbacks that avoided all that complexity. And — more importantly — the solution doesn’t force you to use callbacks from the get-go, but allows you to layer them on later as needed. &lt;em&gt;Forward progress!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another example that is near and dear to us —and certainly to the community— is styling. On one hand, the easiest thing for us to do would be to simply tack on support for CSS directly into Streamlit, with something like &lt;code&gt;st.css(...)&lt;/code&gt; or &lt;code&gt;st.write(..., style="css goes here")&lt;/code&gt;. But when we experiment with it, we notice unfettered access to styling quickly becomes a &lt;em&gt;hindrance&lt;/em&gt; toward forward progress. Rather than get that first version out to stakeholders, people get stuck combing through&lt;a href="https://developer.mozilla.org/en-US/" rel="noopener noreferrer"&gt; MDN&lt;/a&gt;, fighting the&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance" rel="noopener noreferrer"&gt; cascade&lt;/a&gt;, tweaking selectors, and obsessing about single pixels. And, to top it off, the end result is often flaky and distracting.&lt;/p&gt;

&lt;p&gt;So we tackle these requests by asking ourselves these questions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“What is the underlying problem people are trying to solve?”&lt;/li&gt;
&lt;li&gt;“How common is that problem?”&lt;/li&gt;
&lt;li&gt;“Can we solve it ourselves and help free the developer?” &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on the answers to these questions, we follow one of two approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Provide a one-line, opinionated solution to the problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This happened a few months ago. We noticed tons of developers using CSS hacks to place a logo at the top-left corner of their apps, so we decided to give them a one-line solution with &lt;code&gt;st.logo()&lt;/code&gt;. &lt;a href="https://docs.streamlit.io/develop/api-reference/media/st.logo" rel="noopener noreferrer"&gt;This new command&lt;/a&gt; draws their custom logo, makes it responsive to the sidebar’s state, makes sure it doesn’t overlap any content, and just looks good by default.&lt;/p&gt;

&lt;p&gt;That’s also how we added&lt;a href="https://docs.streamlit.io/develop/api-reference/text/st.markdown" rel="noopener noreferrer"&gt; text colors, lines under headers, borders around containers, vertical alignment, Material icons&lt;/a&gt;, and so on. They’re certainly opinionated solutions in terms of visuals and behavior, but the advantage is you just say what you want, Streamlit does it, and you move on to the next thing. &lt;em&gt;Forward progress!&lt;/em&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Provide a curated set of knobs … and watch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a one-line opinionated solution won’t cut it, we introduce a minimal set of “knobs,” observe the result, and iterate. Since we don’t want to break compatibility, most of our features are&lt;a href="https://www.youtube.com/watch?v=rxsdOQa_QkM" rel="noopener noreferrer"&gt; one-way doors,&lt;/a&gt; meaning we must proceed with caution.&lt;/p&gt;

&lt;p&gt;An example of this is &lt;em&gt;theming&lt;/em&gt;. Everyone wants their apps to match their company’s colors and, of course, the exact colors vary by company. But Streamlit’s interface is made up of several dozen colors, and selecting a visually-pleasing combination can consume several hours. So our first stab at this problem was to&lt;a href="https://docs.streamlit.io/develop/concepts/configuration/theming" rel="noopener noreferrer"&gt; let you pick just 4 colors,&lt;/a&gt; and Streamlit calculates all the others for you. &lt;em&gt;Forward progress!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We’re now busy behind the scenes thinking up &lt;em&gt;a second stab&lt;/em&gt; at this problem — an expanded solution that gives you&lt;a href="https://youtu.be/eQY7hfkw-Ag?t=1066" rel="noopener noreferrer"&gt; more knobs&lt;/a&gt; (beyond colors, even!) without sacrificing iteration speed. Similarly, we’re also considering new, more flexible layout options beyond columns.&lt;/p&gt;

&lt;p&gt;We have nothing to announce right now, but definitely keep an eye out 😉&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In sum, we don’t want anything to distract you from forward progress. With every step we take, we try our hardest to provide a framework that abstracts away HTML, JS, CSS, HTTP, routes, serialization, callbacks, and all sorts of engineering details. This way, &lt;strong&gt;you’re able to focus on putting the power of data at the fingertips of your stakeholders so they, too, can make &lt;em&gt;forward progress&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq84z9aprlaifzz5wq8fd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq84z9aprlaifzz5wq8fd.jpeg" alt="A stylized image of a rocket ship taking off." width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Iteration makes perfect
&lt;/h2&gt;

&lt;p&gt;At Streamlit, we are avid users of Streamlit ourselves, which means we have our own pet peeves and feature requests. We share your pain points, and we’re always iterating on the library. We never want to stop iterating! Our commitment to this is demonstrated in the way we ship a new release each month.&lt;/p&gt;

&lt;p&gt;We’re also inspired by the Streamlit community and your ingenuity. We constantly encounter &lt;a href="https://streamlit.io/gallery" rel="noopener noreferrer"&gt;apps&lt;/a&gt; and&lt;a href="https://streamlit.io/components" rel="noopener noreferrer"&gt; custom components&lt;/a&gt; that push the boundaries of Streamlit in ways we never thought possible, giving us new ideas for things to bring into the core library. The community is easily the best part of this job!&lt;/p&gt;

&lt;p&gt;Because of that, we have so much more in store for you. We develop&lt;a href="https://github.com/streamlit/streamlit/pulls" rel="noopener noreferrer"&gt; in the open&lt;/a&gt;, so you can always find our roadmap at&lt;a href="https://roadmap.streamlit.app" rel="noopener noreferrer"&gt; roadmap.streamlit.app&lt;/a&gt; or attend the next&lt;a href="https://www.youtube.com/watch?v=eQY7hfkw-Ag&amp;amp;t=16s" rel="noopener noreferrer"&gt; Quarterly Showcase&lt;/a&gt;, where our product managers discuss the latest in Streamlit, like&lt;a href="https://www.youtube.com/live/eQY7hfkw-Ag?si=q8JpIEH3yxeOrTGu&amp;amp;t=1019" rel="noopener noreferrer"&gt; vertical alignment&lt;/a&gt; and advanced theming.&lt;/p&gt;

&lt;p&gt;The beauty about iterating is that the best days are always ahead. We’re humbled to have you along for the ride.&lt;/p&gt;

&lt;p&gt;Happy Streamlit-ing! 🎈&lt;/p&gt;

</description>
      <category>streamlit</category>
      <category>python</category>
      <category>designprocess</category>
    </item>
  </channel>
</rss>
