运行Streamlit应用时报ValueError:signal仅在主解释器主线程生效
问题:运行Streamlit应用时出现
ValueError: signal only works in main thread of the main interpreter错误 报错回溯
File "C:\Users\jalal\AppData\Local\Programs\Python\Python311\Lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 552, in _run_script exec(code, module.__dict__) File "C:\Users\jalal\python_work\application.py", line 18, in <module> app.run(debug=True) File "C:\Users\jalal\AppData\Local\Programs\Python\Python311\Lib\site-packages\flask\app.py", line 889, in run run_simple(t.cast(str, host), port, self, **options) File "C:\Users\jalal\AppData\Local\Programs\Python\Python311\Lib\site-packages\werkzeug\serving.py", line 1097, in run_simple run_with_reloader( File "C:\Users\jalal\AppData\Local\Programs\Python\Python311\Lib\site-packages\werkzeug\_reloader.py", line 439, in run_with_reloader signal.signal(signal.SIGTERM, lambda *args: sys.exit(0)) File "C:\Users\jalal\AppData\Local\Programs\Python\Python311\Lib\signal.py", line 56, in signal handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
涉及文件代码
application.py
from flask import Flask from flask.templating import render_template import streamlit as st import requests from streamlit_lottie import st_lottie st.set_page_config(page_title="Consultant Company", page_icon="hammer_and_wrench", layout="wide") app = Flask(__name__, static_url_path='/static') @app.route('/') def index(): return render_template('index.html', name='home') if __name__ == "__main__": app.run(debug=True)
navigation.py
import streamlit as st def navigation(): try: path = st.experimental_get_query_params()['p'][0] except Exception as e: st.error('Please use the main app.') return None return path if navigation() == "home": st.title('Home') st.write('This is the home page.') elif navigation() == "results": st.title('Results List') for item in range(25): st.write(f'Results {item}') elif navigation() == "analysis": st.title('Analysis') x, y = st.number_input('Input X'), st.number_input('Input Y') st.write('Result: ' + str(x+y)) elif navigation() == "examples": st.title('Examples Menu') st.write('Select an example.') elif navigation() == "logs": st.title('View all of the logs') st.write('Here you may view all of the logs.') elif navigation() == "verify": st.title('Data verification is started...') st.write('Please stand by....') elif navigation() == "config": st.title('Configuration of the app.') st.write('Here you can configure the application')
index.html
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="/static/styles/styles.css"> </head> <body> <div class="dropdown"> <button class="dropbtn">Dropdown</button> <div class="dropdown-content"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <ul> <li> <a class="navbar-brand" href="/"> <div class="logo-image"> <img src="/static/images/logo.png" class="img-fluid"> </div> </a> </li> <li> <a href="#" onclick="setURL('http://localhost:8501/?p=analysis')">Analysis</a> </li> <li> <a href="#" onclick="setURL('http://localhost:8501/?p=results')">Results</a> </li> <li> <a href="#" onclick="setURL('http://localhost:8501/?p=examples')">Examples</a> </li> </ul> <iframe src="http://localhost:8501/?p=home" id="streamlit_content" allowfullscreen frameborder="0" wmode="transparent"> Your browser doesn't support iframes </iframe> </body> <script> function setURL(url) { document.getElementById('streamlit_content').src = url; console.log('Works!') } </script> </html>
styles.css
body { font-family: 'Trebuchet MS', sans-serif; font-weight: bold; margin: 0; background-color: whitesmoke; } /* #31333f */ ul { list-style-type: none; font-size: large; margin: 0; padding: 0; overflow: hidden; background-color: #333; position: relative; width: 100%; height: 3.5rem; z-index: 999999; } li { height: 100%; float: left; } li a { display: block; color: white; text-align: center; padding: 18px 16px; height: 100%; text-decoration: none; } li a:hover:not(.active) { background-color: #111; } .active { background-color: #333; } .logo-image { width: 46px; height: 46px; overflow: hidden; margin-top: -25%; } iframe{ width: 100%; border: none; position: fixed; height: 100%; z-index: 0; } .dropbtn { background-color: #333; color: white; padding: 16px; font-size: large; font-family: 'Trebuchet MS', sans-serif; font-weight: bold; border: none; cursor: pointer; height: 3.5rem; } .dropdown { position: fixed; right: 0; z-index: 9999999999999; } .dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 9999999; } .dropdown-content a { color: black; padding: 12px 16px; text-decoration: none; display: block; } .dropdown-content a:hover {background-color: #f1f1f1} .dropdown:hover .dropdown-content { display: block; } .dropdown:hover .dropbtn { background-color: #333; }
问题原因
你将Flask和Streamlit代码混在同一个进程中:application.py里调用了Streamlit的st.set_page_config,而Streamlit本身会启动独立服务线程;同时Flask开启调试模式(debug=True),调试重载器会尝试在非主线程设置信号处理,触发Python信号机制的限制,导致报错。
解决方案
Flask和Streamlit是独立的Web框架,需分开作为两个服务运行:
1. 修改application.py,移除Streamlit相关代码
from flask import Flask from flask.templating import render_template app = Flask(__name__, static_url_path='/static') @app.route('/') def index(): return render_template('index.html', name='home') if __name__ == "__main__": # 指定Flask端口为5000,避免与Streamlit默认的8501端口冲突 app.run(debug=True, port=5000)
2. 单独启动Streamlit服务
打开新的命令提示符,运行以下命令启动navigation.py:
streamlit run navigation.py --server.port 8501
3. 验证服务运行
- Flask服务将在
http://localhost:5000启动 - Streamlit服务将在
http://localhost:8501启动 - 访问Flask地址,iframe会加载Streamlit内容,导航按钮可正常切换页面
内容的提问来源于stack exchange,提问作者arian
相关产品推荐
相关产品推荐

