> ## Documentation Index
> Fetch the complete documentation index at: https://docs.domino.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Getting started with Streamlit in Domino

> Install Streamlit in a Compute Environment, build your app in /mnt, live-test via Jupyter Server Proxy, then publish using an app.sh that binds to port 8888 on 0.0.0.0 with headless mode enabled.

### **Version/Environment (if relevant):**

All versions. Requires a Compute Environment with Streamlit installed. Domino Standard Environments are recommended.

## **How To:**

### **Step 1 — Install Streamlit**

If you are using a [Domino Standard Environment](https://docs.dominodatalab.com/en/latest/user_guide/0d73c6/domino-standard-environments/), add the Streamlit package to your Compute Environment via one of the following methods:

**Dockerfile instruction:**

```
USER root
RUN pip install -U streamlit starlette
```

**requirements.txt:**

`streamlit
starlette`
**Note:** Some older versions of streamlit and starlette have compatibility issues, make sure you are using the latest versions.

### **Step 2 — Build your Streamlit app**

Create your Streamlit app file (e.g. `streamlit_app.py`) in your project's `/mnt` directory. The example below is a working demo adapted from [Streamlit's NYC Uber Ridesharing demo](https://github.com/streamlit/demo-uber-nyc-pickups) (updated for Streamlit 1.3.8):

```
import os
import altair as alt
import numpy as np
import pandas as pd
import pydeck as pdk
import streamlit as st

st.set_page_config(layout="wide", page_title="NYC Ridesharing Demo", page_icon=":taxi:")

@st.cache_resource
def load_data():
    path = "uber-raw-data-sep14.csv.gz"
    if not os.path.isfile(path):
        path = f"https://github.com/streamlit/demo-uber-nyc-pickups/raw/main/{path}"
    data = pd.read_csv(
        path,
        nrows=100000,
        names=["date/time", "lat", "lon"],
        skiprows=1,
        usecols=[0, 1, 2],
        parse_dates=["date/time"],
    )
    return data

def map(data, lat, lon, zoom):
    st.write(pdk.Deck(
        map_style="mapbox://styles/mapbox/light-v9",
        initial_view_state={"latitude": lat, "longitude": lon, "zoom": zoom, "pitch": 50},
        layers=[pdk.Layer("HexagonLayer", data=data, get_position=["lon", "lat"],
            radius=100, elevation_scale=4, elevation_range=[0, 1000],
            pickable=True, extruded=True)],
    ))

@st.cache_data
def filterdata(df, hour_selected):
    return df[df["date/time"].dt.hour == hour_selected]

@st.cache_data
def mpoint(lat, lon):
    return (np.average(lat), np.average(lon))

@st.cache_data
def histdata(df, hr):
    filtered = df[(df["date/time"].dt.hour >= hr) & (df["date/time"].dt.hour < (hr + 1))]
    hist = np.histogram(filtered["date/time"].dt.minute, bins=60, range=(0, 60))[0]
    return pd.DataFrame({"minute": range(60), "pickups": hist})

data = load_data()
row1_1, row1_2 = st.columns((2, 3))

if not st.session_state.get("url_synced", False):
    try:
        pickup_hour = int(st.query_params["pickup_hour"][0])
        st.session_state["pickup_hour"] = pickup_hour
        st.session_state["url_synced"] = True
    except KeyError:
        pass

def update_query_params():
    st.query_params["pickup_hour"] = st.session_state["pickup_hour"]

with row1_1:
    st.title("NYC Uber Ridesharing Data")
    hour_selected = st.slider("Select hour of pickup", 0, 23,
        key="pickup_hour", on_change=update_query_params)

with row1_2:
    st.write("""
## Examining how Uber pickups vary over time in New York City
    and at its major regional airports.""")

row2_1, row2_2, row2_3, row2_4 = st.columns((2, 1, 1, 1))
la_guardia = [40.7900, -73.8700]
jfk = [40.6650, -73.7821]
newark = [40.7090, -74.1805]
zoom_level = 12
midpoint = mpoint(data["lat"], data["lon"])

with row2_1:
    st.write(f"**All NYC from {hour_selected}:00 to {(hour_selected + 1) % 24}:00**")
    map(filterdata(data, hour_selected), midpoint[0], midpoint[1], 11)
with row2_2:
    st.write("**La Guardia Airport**")
    map(filterdata(data, hour_selected), la_guardia[0], la_guardia[1], zoom_level)
with row2_3:
    st.write("**JFK Airport**")
    map(filterdata(data, hour_selected), jfk[0], jfk[1], zoom_level)
with row2_4:
    st.write("**Newark Airport**")
    map(filterdata(data, hour_selected), newark[0], newark[1], zoom_level)

chart_data = histdata(data, hour_selected)
st.write(f"**Rides per minute between {hour_selected}:00 and {(hour_selected + 1) % 24}:00**")
st.altair_chart(
    alt.Chart(chart_data).mark_area(interpolate="step-after")
    .encode(x=alt.X("minute:Q", scale=alt.Scale(nice=False)),
            y=alt.Y("pickups:Q"), tooltip=["minute", "pickups"])
    .configure_mark(opacity=0.2, color="red"),
    use_container_width=True,
)
```

### **Step 3 — Live test from a workspace**

### JupyterLab

You can live test your Streamlit app from a JupyterLab workspace using Jupyter Server Proxy. Ensure that [JupyterLab](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html#pip) and [jupyter-server-proxy](https://jupyter-server-proxy.readthedocs.io/en/latest/install.html) are installed in your Compute Environment. Both are pre-installed in Domino Standard Environments.

1. Launch a JupyterLab workspace and open a new terminal.
2. Run your app from the `/mnt` directory:

   ```
   streamlit run streamlit_app.py --server.port 8501
   ```
3. Access the app in your browser using the following URL pattern (default Streamlit port is `8501`):

   ```
   https://<your-domino-url>/<username>/<project-name>/notebookSession/<run-id>/proxy/8501/
   ```

**Note:** The trailing `/` at the end of the URL is required. Omitting it will prevent the app from loading. The `<run-id>` can be found in the URL of the active workspace session.

### VSCode

Use the same process to start the app as above, but for live testing from a **VSCode workspace**, the URL structure differs — insert `/r/` before `notebookSession`:
ex.
`https://<your-domino-url>/<username>/<project-name>/r/notebookSession/<run-id>/proxy/8501/`

### **Step 4 — Publish the app in Domino**

Once development is complete, publish the app using an `app.sh` file. Create `app.sh` in the root of your project with the following contents:

```
#!/bin/bash
set -x
streamlit run streamlit_app.py \
    --server.port 8888 \
    --server.address 0.0.0.0 \
    --server.headless true

streamlit run streamlit_app.py
```

This file configures Streamlit to bind to the host and port Domino expects for published Apps. Once saved:

1. Navigate to **Deployment > Apps & Agents** in your project.
2. Click **Publish** and select **App**
3. Complete the form and click **Publish Domino App**.
4. Once the App is running, click **View App** to open it.

**Notes/Information:**

* See: [Live testing Streamlit in Domino on VSCode workspace](https://support.domino.ai/support/s/article/Live-testing-the-Streamlit-in-Domino-on-VSCode-workspace-1718868026350) (KB 000001036).
* For full Domino App publishing documentation, see: [Publish Apps — Domino Docs](https://docs.dominodatalab.com/en/latest/user_guide/71635d/publish-apps/).


## Related topics

- [How-to guides](/knowledge-base/how-to-guides-overview.md)
- [Getting started with Domino: Build a transaction review App](/cloud/platform-overview/getting-started-with-domino/index.md)
- [AWS Trainium and Inferentia silicon accelerators](/cloud/platform-capabilities/core-concepts/compute-environments/use-external-images/aws-accelerators.md)
- [Code examples](/cloud/examples/code-examples.md)
