如何将Streamlit上传的YAML文件转换为Python字典?
解决Streamlit上传YAML配置文件转Python字典的问题
问题场景
开发Streamlit应用时,通过streamlit.sidebar.file_uploader()上传YAML配置文件,尝试读取并转换为Python字典时连续遇到报错:
- 直接用
open()读取触发TypeError - 改用
.getvalue()后触发OSError
初始代码及错误
import streamlit as st import yaml config = st.sidebar.file_uploader("Upload config file") if config is not None: with open(config, 'r') as uploaded_config: loaded_config = yaml.safe_load(uploaded_config) st.write(loaded_config['scoring'])
错误信息:
TypeError: expected str, bytes or os.PathLike object, not UploadedFile Traceback: File "/Users/user/opt/anaconda3/envs/npextension_app_env/lib/python3.8/site-packages/streamlit/scriptrunner/script_runner.py", line 557, in _run_script exec(code, module.__dict__) File "app.py", line 8, in <module> with open(config, 'r') as uploaded_config:
修改后代码及新错误
import streamlit as st import yaml config = st.sidebar.file_uploader("Upload config file") if config is not None: with open(config.getvalue(), 'r') as uploaded_config: loaded_config = yaml.safe_load(uploaded_config) st.write(loaded_config['scoring'])
新错误信息:
OSError: [Errno 63] File name too long: b'features_list:\n - NO2 Mean\n - 03 Mean\n - SO2 Mean\n - is_weekend\n\nevents_list:\n - is_xmas\n\nds: Date Local\n\ny: CO Mean\n\nscoring: mae\n\nfreq: D\n\ntest_p: 0.06\n\nvalid_p: 0.1\n\nk: 3\n' Traceback: File "/Users/user/opt/anaconda3/envs/npextension_app_env/lib/python3.8/site-packages/streamlit/scriptrunner/script_runner.py", line 557, in _run_script exec(code, module.__dict__) File "app.py", line 8, in <module> with open(config.getvalue(), 'r') as uploaded_config:
上传的YAML文件内容
features_list: - NO2 Mean - 03 Mean - SO2 Mean - is_weekend events_list: - is_xmas ds: Date Local y: CO Mean scoring: mae freq: D test_p: 0.06 valid_p: 0.1 k: 3
错误原因
- 第一个错误:
streamlit.sidebar.file_uploader()返回的是UploadedFile对象,而非文件路径字符串,open()函数需要传入路径,因此类型不匹配报错。 - 第二个错误:
UploadedFile.getvalue()返回的是文件的字节内容,把字节内容当作文件名传给open(),自然会出现“文件名过长”的错误。
正确解决方案
直接利用UploadedFile对象的read()方法读取字节内容,再传给yaml.safe_load()解析:
import streamlit as st import yaml config = st.sidebar.file_uploader("Upload config file") if config is not None: # 读取文件字节内容并解析为YAML loaded_config = yaml.safe_load(config.read()) # 验证读取结果 st.write(loaded_config['scoring'])
如果需要处理编码问题,可以先将字节内容解码为字符串:
loaded_config = yaml.safe_load(config.read().decode('utf-8'))
内容的提问来源于stack exchange,提问作者mad_scientist
相关产品推荐
相关产品推荐

