Day 74 of 80

Cloud Deployment

Phase 8: Deployment & UI

What You'll Build Today

Today is a massive milestone. For the last 73 days, everything you have built has lived exclusively inside your computer. If you wanted to show a friend your AI application, you had to invite them over and have them look at your screen.

Today, we break those walls down. You are going to take the application you built yesterday (or a simplified version we create today) and put it on the public internet.

By the end of this session, you will have two working URLs that you can text to anyone in the world, and they will be able to use your AI tool on their own phone or laptop.

Here is what you will master:

* Cloud Hosting: You will learn why we don't just run servers on our laptops and how to rent tiny slices of supercomputers (servers) from providers like Render and Streamlit Cloud.

* Dependency Management: You will learn how to write a "recipe" (requirements.txt) so the cloud computer knows exactly which libraries to install to make your code run.

* Environment Variables: You will learn how to securely pass your OpenAI API keys to the cloud without publicly posting them on the internet (which would be a security disaster).

* Client-Server Communication in the Cloud: You will rewire your frontend to talk to your live backend instead of your local machine.

Let's go live.

The Problem

Imagine you have just finished building an amazing AI text summarizer. It works perfectly. You are so proud that you want to send it to your best friend to try out.

You look at your browser address bar, copy the link, and text it to them:

http://localhost:8501

Two minutes later, they reply: "It doesn't work. It says the site can't be reached."

You are confused. You click the link. It works fine for you!

Why this happens: localhost is a special address that means "this computer." When you click it, your computer talks to itself. When your friend clicks it, their computer talks to their computer—which doesn't have your code running on it.

To fix this the "hard way," you would have to:

  • Figure out your home network's public IP address.
  • Log into your WiFi router admin panel.
  • Set up "Port Forwarding" (risky if you don't know security).
  • Leave your laptop turned on, lid open, and plugged in 24/7.
  • If your WiFi goes down or your laptop sleeps, your app dies.
  • The "Painful" Python Reality:

    Even if you tried to share your code so they could run it, they would need Python installed. If you sent them your script, it would crash immediately because they don't have your libraries.

    You might try to explain how to install them:

    "Okay, open your terminal. Type pip install openai. Oh, you have Python 3.8? You need 3.10. Okay, upgrade Python. Now install pandas. Wait, that version conflicts with..."

    It is a nightmare. There has to be a way to just give them a working link.

    Let's Build It

    We are going to deploy this in two parts.

  • The Backend: Your FastAPI logic (hosted on Render).
  • The Frontend: Your Streamlit UI (hosted on Streamlit Community Cloud).
  • We need two separate hosts because Streamlit Cloud is specialized just for UI, while Render is great for generic backend APIs.

    Step 1: Prepare Your Project Structure

    First, we need to ensure your files are organized correctly. The cloud needs to know exactly what libraries you are using.

    Create a folder named deployment_day and create these three files inside it:

    File 1: requirements.txt

    This is the recipe for the cloud server. It tells the server what to install.

    fastapi
    

    uvicorn

    requests

    streamlit

    python-dotenv

    openai

    File 2: backend.py

    This is a simple API. We will deploy this first.

    from fastapi import FastAPI
    

    import os

    app = FastAPI()

    @app.get("/")

    def home():

    return {"message": "Hello from the Cloud Backend!"}

    @app.get("/calculate/{number}")

    def calculate(number: int):

    # Simulate some logic

    result = number * 2

    return {

    "original": number,

    "doubled": result,

    "server_location": "I am running on a remote server!"

    }

    File 3: frontend.py

    This is your UI. Note that the URL is currently empty.

    import streamlit as st
    

    import requests

    st.title("☁️ My First Cloud App")

    # IMPORTANT: We will update this URL after deploying the backend

    BACKEND_URL = "http://localhost:8000"

    st.write("This app connects to a separate backend server.")

    number = st.number_input("Enter a number to double:", value=5)

    if st.button("Calculate"):

    try:

    # We append the endpoint path to the base URL

    response = requests.get(f"{BACKEND_URL}/calculate/{number}")

    if response.status_code == 200:

    data = response.json()

    st.success(f"Result: {data['doubled']}")

    st.info(f"Server says: {data['server_location']}")

    else:

    st.error("Error connecting to backend")

    except Exception as e:

    st.error(f"Connection failed: {e}")

    st.warning("Did you remember to change the BACKEND_URL variable?")

    Step 2: Push to GitHub

    Cloud providers usually pull your code directly from GitHub.

  • Create a new repository on GitHub named day-74-deploy.
  • Upload (or push) your three files (requirements.txt, backend.py, frontend.py) to this repository.
  • Crucial: Ensure you do NOT upload a .env file containing real API keys. We will handle keys separately.
  • Step 3: Deploy the Backend (Render)

    We will use Render (render.com) because it has a generous free tier for web services.

  • Create an account on Render.
  • Click "New +" and select "Web Service".
  • Connect your GitHub account and select your day-74-deploy repository.
  • Configuration Settings:
  • * Name: my-api-backend (or similar)

    * Runtime: Python 3

    * Build Command: pip install -r requirements.txt

    * Start Command: uvicorn backend:app --host 0.0.0.0 --port 10000

  • Click "Create Web Service".
  • Explanation of Start Command:

    * uvicorn: The server software.

    * backend:app: Look in backend.py for the object named app.

    * --host 0.0.0.0: Accept connections from anywhere (required for cloud).

    * --port 10000: Render expects apps to listen on port 10000 by default.

    Render will now start "building." It will download Python, install the libraries from your requirements file, and start the app. This takes about 2-3 minutes.

    When it finishes, look for your Service URL at the top left. It will look like:

    https://my-api-backend.onrender.com Test it: Click that link. You should see {"message": "Hello from the Cloud Backend!"}.

    Step 4: Connect Frontend to Backend

    Now we have a problem. Your frontend.py file on GitHub still says:

    BACKEND_URL = "http://localhost:8000"

    If you deploy the frontend now, it will look for the backend on the cloud server's localhost, which doesn't exist.

  • Edit frontend.py on your computer.
  • Update the variable with your new Render URL (no trailing slash):
  •     # REPLACE THIS with your actual Render URL
    

    BACKEND_URL = "https://my-api-backend.onrender.com"

  • Save, commit, and push this change to GitHub.
  • Step 5: Deploy the Frontend (Streamlit Cloud)

    Streamlit has its own hosting service that is incredibly easy to use.

  • Go to share.streamlit.io and sign in with GitHub.
  • Click "New app".
  • Select Repository: Choose day-74-deploy.
  • Main file path: Enter frontend.py.
  • Click "Deploy!".
  • Streamlit will now bake your app. You will see a terminal on the right showing the installation process (reading your requirements.txt).

    The Result:

    Once finished, you will be redirected to a public URL (usually https://your-repo-name.streamlit.app).

    Try it out! Enter a number and click "Calculate."

  • Your browser talks to Streamlit Cloud (Frontend).
  • Streamlit Cloud talks to Render (Backend).
  • Render calculates and responds.
  • Streamlit displays the result.
  • You now have a fully distributed cloud architecture.

    Handling Secrets (API Keys)

    If your app used OpenAI, you would need to set the API key. Never put the key in your code on GitHub.

    On Render:
  • Go to your Dashboard > Environment.
  • Add a generic variable: Key = OPENAI_API_KEY, Value = sk-....
  • On Streamlit Cloud:
  • Go to your App Settings (three dots) > Settings > Secrets.
  • Enter your secrets in TOML format:
  • ``toml

    OPENAI_API_KEY = "sk-..."

    `

    In your Python code, you access these exactly the same way you did locally:

    import os
    

    api_key = os.getenv("OPENAI_API_KEY")

    # or st.secrets["OPENAI_API_KEY"] for Streamlit specific features

    Now You Try

    You have a live pipeline. Now, let's verify that updating it works.

    1. The "Under Construction" Update

    Modify your frontend.py to add a sidebar with an "About Me" section.

    Push the code to GitHub. Watch your Streamlit app URL. It should detect the change and update automatically within a minute or two. You don't need to redeploy manually!

    2. The Backend Expansion

    Modify backend.py to add a new endpoint called /health.

    @app.get("/health")
    

    def health_check():

    return {"status": "healthy", "uptime": "good"}

    Push to GitHub. Render will detect the push and rebuild your server. Wait for the "Deploy Succeeded" message in the Render dashboard, then try visiting your-render-url/health.

    3. Visualizing the Connection

    In frontend.py, add a line that prints the BACKEND_URL to the screen using st.code(BACKEND_URL). This is a helpful debugging trick to ensure your deployed frontend is actually pointing to the correct place and not localhost.

    Challenge Project

    Task: The Feedback Loop

    Your challenge is to create a deployment that actually collects data from users.

    Requirements:
  • Modify your Backend to have a list called feedback_store = [].
  • Create a POST endpoint /feedback that accepts a text string and appends it to that list.
  • Modify your Frontend to have a text area "Leave Feedback" and a "Submit" button.
  • When submitted, send the text to your Backend.
  • The Goal: Send your Streamlit link to 3 friends (or open it on your phone and pretend to be 3 people). Have them submit feedback.
  • Add a "View Admin Data" checkbox on your frontend that fetches and displays the list of feedback from the backend.
  • Note: On the free tier of Render, if the app restarts (which happens often), your
    feedback_store list will be wiped clean because it's just in memory. That is okay for today. In the future, we will use a database to make data permanent. Expected Output:

    You should be able to type "Great job!" on your phone, hit submit, and immediately see "Great job!" appear in the list on your laptop's browser when you refresh the Admin view.

    What You Learned

    Today you moved from a local developer to a cloud engineer.

    * Public vs. Local: You learned that localhost is a trap and that public URLs require a server listening on 0.0.0.0.

    * Infrastructure as Code: You learned that requirements.txt` is essential for recreating your environment on a strange computer.

    * Continuous Deployment: You saw how pushing code to GitHub automatically triggers updates on your live sites.

    Why This Matters:

    AI is useless if it stays on your laptop. Whether you are building a portfolio to get hired or a tool to help your team at work, deployment is the bridge between "code" and "product."

    Tomorrow: Now that your app is live, it might look a little rough. Tomorrow, we focus on UI Polish and Final Touches to make your application look professional and trustworthy.