Can a streamlit app be run within a flask app?
Asked Answered
C

2

11

No code here, just a question. I have tried various means to get a streamlit app to run within a flask app. Main reason? Using Flask for user authentication into the streamlit app. Cannot get it to work out. Is it not possible perhaps?

Concordia answered 25/11, 2021 at 16:8 Comment(2)
Using tokens? Authenticate users in Flask and give them back a token. Then from streamlit ask validation of token.Kazimir
Good suggestion. My first challenge is to merely be able to launch the streamlit app itself from within a flask page.Concordia
E
14

Streamlit uses Tornado to serve HTTP and WebSocket data to its frontend. That is, it’s already its own web server, and is written in an existing web framework; it wouldn’t be trivial to wrap it inside another web framework.

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. By using non-blocking network I/O, Tornado can scale to tens of thousands of open connections, making it ideal for long polling, WebSockets, and other applications that require a long-lived connection to each user.

Flask is a synchronous web framework and not ideal for WebSockets etc.

Serving an interactive Streamlit app via flask.render_template isn’t feasible, because Streamlit apps are not static; when you interact with your Streamlit app, it is re-running your Python code to generate new results dynamically

Follow these discussions for more info

Exum answered 26/11, 2021 at 6:39 Comment(1)
Than you for that detailed information. I’m hitting those links you provided to dig into it more.Concordia
T
0


import asyncio
import subprocess

from mlflow.server import app as mlflow_app

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.wsgi import WSGIMiddleware
import uvicorn
from fastapi.logger import logger
import uuid
from config import *

streamlit_app_process = None
streamlit_app_stdout = None
streamlit_app_stderr = None


async def registry_subprocess() -> None:
    logger.debug("registry distance_matrix")
    global streamlit_app_process
    global streamlit_app_stdout
    global streamlit_app_stderr
    id = str(uuid.uuid1())
    streamlit_app_stdout = open(f"/tmp/subprocess_stdout_{''.join(id.split('-'))}", 'w+b')
    streamlit_app_stderr = open(f"/tmp/subprocess_stderr_{''.join(id.split('-'))}", 'w+b')
    cmd = ['streamlit', 'run', f'{app_dir}/Home.py', f'--server.port={streamlit_app_port}', f'--server.address={streamlit_app_host}']
    logger.info(f"subprocess start cmd {cmd}")
    streamlit_app_process = subprocess.Popen(cmd, stdout=streamlit_app_stdout.fileno(), stderr=streamlit_app_stderr.fileno())
    logger.info(f"subprocess start success {streamlit_app_process.pid} uid:{id}")
    await asyncio.sleep(1)
    streamlit_app_stdout.flush()
    streamlit_app_stderr.flush()
    [logger.info(i) for i in streamlit_app_stdout.readlines()]
    [logger.info(i) for i in streamlit_app_stderr.readlines()]


async def close_subprocess() -> None:
    logger.debug("close subprocess")
    try:
        streamlit_app_process.kill()
        streamlit_app_stdout.flush()
        streamlit_app_stderr.flush()
        streamlit_app_stdout.close()
        streamlit_app_stderr.close()
    except Exception as error:
        logger.error(error)


application = FastAPI()
application.add_event_handler("startup", registry_subprocess)
application.add_event_handler("shutdown", close_subprocess)
application.add_middleware(
    CORSMiddleware,
    allow_origins='*',
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
application.mount(f"/{mlflow_app_prefix.strip('/')}", WSGIMiddleware(mlflow_app))

if __name__ == "__main__":
    uvicorn.run(application, host=mlflow_app_host, port=int(mlflow_app_port))


Teaspoon answered 10/8, 2022 at 8:12 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Messick

© 2022 - 2024 — McMap. All rights reserved.