Skip to content

Commit

Permalink
update streamlit example to not use tunnels
Browse files Browse the repository at this point in the history
  • Loading branch information
aksh-at committed Dec 14, 2023
1 parent 4d95e37 commit 7c1a66f
Showing 1 changed file with 52 additions and 15 deletions.
67 changes: 52 additions & 15 deletions 10_integrations/streamlit/serve_streamlit.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@
#
# # Run and share Streamlit apps
#
# This example supports running the Streamlit app ephemerally with `modal run`, and
# deploying a web endpoint from which others can spin up isolated instances of the Streamlit
# app, each accessible in the browser via URL!
# This example shows you how to run a Streamlit app with `modal serve`, and then deploy it as a serverless web app.
#
# ![example streamlit app](./streamlit.png)
#
# The example is structured as two files:
# This example is structured as two files:
#
# 1. This module, which defines the Modal objects (name the script `serve_streamlit.py` locally).
# 2. `app.py`, which is a Streamlit script and is mounted into a Modal function ([download script](https://github.com/modal-labs/modal-examples/blob/main/10_integrations/streamlit/app.py)).
# 2. `app.py`, which is any Streamlit script to be mounted into the Modal
# function ([download script](https://github.com/modal-labs/modal-examples/blob/main/10_integrations/streamlit/app.py)).

import pathlib

import modal

# ## Define container dependencies
#
# The `app.py` script imports three third-party packages, so we include these in the example's
# image definition.
# image definition. We also install `asgiproxy` to proxy the Streamlit server.

image = (
modal.Image.debian_slim()
Expand All @@ -33,15 +33,29 @@

stub = modal.Stub(name="example-modal-streamlit", image=image)

# ## Mounting the `app.py` script
#
# We can just mount the `app.py` script inside the container at a pre-defined path using a Modal
# [`Mount`](https://modal.com/docs/guide/local-data#mounting-directories).

streamlit_script_local_path = pathlib.Path(__file__).parent / "app.py"
streamlit_script_remote_path = pathlib.Path("/root/app.py")

# ## Mounting the `app.py` script
#
# As the Modal code and Streamlit code are isolated, we can just mount the latter into the container
# at a configured path, and pass that path to the Streamlit server.
if not streamlit_script_local_path.exists():
raise RuntimeError(
"app.py not found! Place the script with your streamlit app in the same directory."
)

streamlit_script_mount = modal.Mount.from_local_file(
streamlit_script_local_path,
streamlit_script_remote_path,
)

# ## Spawning the Streamlit server
#
# We could also import the module, and then pass `app.__path__` to Streamlit.
# Inside the container, we will run the Streamlit server in a background subprocess using
# `subprocess.Popen`. Here we define `spawn_server()` to do this and then poll until the server
# is ready to accept connections.

HOST = "127.0.0.1"
PORT = "8000"
Expand Down Expand Up @@ -83,13 +97,17 @@ def spawn_server():
)


streamlit_script_mount = modal.Mount.from_local_file(
streamlit_script_local_path,
streamlit_script_remote_path,
)
# ## Wrap it in an ASGI app
#
# Finally, Modal can only serve apps that speak the [ASGI](https://modal.com/docs/guide/webhooks#asgi) or
# [WSGI](https://modal.com/docs/guide/webhooks#wsgi) protocols. Since the Streamlit server is neither,
# we run a separate ASGI app that proxies requests to the Streamlit server using the `asgiproxy` package.
# Note that at this point `asgiproxy` has a bug with websocket handling, so we are using a
# [fork](https://github.com/modal-labs/asgiproxy) with the fix for this.


@stub.function(
# Allows 100 concurrent requests per container.
allow_concurrent_inputs=100,
mounts=[streamlit_script_mount],
)
Expand All @@ -111,3 +129,22 @@ def run():
)()
proxy_context = ProxyContext(config)
return make_simple_proxy_app(proxy_context)


# ## Iterate and Deploy
#
# While you're iterating on your screamlit app, you can run it "ephemerally" with `modal serve`. This will
# run a local process that watches your files and updates the app if anything changes.
#
# ```shell
# modal serve serve_streamlit.py
# ```
#
# Once you're happy with your changes, you can deploy your application with
#
# ```shell
# modal deploy serve_streamlit.py
# ```
#
# If successful, this will print a URL for your app, that you can navigate to from
# your browser 🎉 .

0 comments on commit 7c1a66f

Please sign in to comment.