Streamlit文件上传路径传递及缓存重复执行问题
问题描述
初始问题:Streamlit上传文件无法读取
我编写了一个接收文件路径的document_loader函数,代码如下:
from typing import Optional from langchain_core.documents import Document from langchain.document_loaders import PyPDFLoader def document_loader(doc_path: str) -> Optional[Document]: """ 将指定格式的文档转换为Langchain Document对象 参数: doc_path (str): PDF文档的路径字符串 返回: Optional[Document]: Document类实例;若文件未找到则返回None """ loader = PyPDFLoader(doc_path) docs = loader.load() print("Document loader done")
PyPDFLoader是基于PyPDF2的封装,用于读取PDF文件路径。
当硬编码文件路径调用该函数时:
document_loader('/Users/Documents/hack/data/abc.pdf')
函数可正常读取PDF文件。
但尝试通过Streamlit的file_uploader()让用户上传PDF文件时:
import streamlit as st import os uploaded_file = st.sidebar.file_uploader("Upload a file", key= "uploaded_file") print(st.session_state.uploaded_file) if uploaded_file is not None: filename = st.session_state.uploaded_file.name print(os.path.abspath(st.session_state.uploaded_file.name)) document_loader(f'"{os.path.abspath(filename)}"')
出现报错:
ValueError: File path "/Users/Documents/hack/data/abc.pdf" is not a valid file or url
其中print(os.path.abspath(st.session_state.uploaded_file.name))输出的路径与硬编码路径完全一致。注:Streamlit运行在本地笔记本的localhost上,我通过本地运行的Streamlit应用上传PDF。
后续问题:临时文件导致缓存失效
按照建议添加tempfile后,读取问题解决,但出现新问题:传递临时文件路径的函数会在用户每次交互时重复执行。原因是临时文件路径自动变化,即使给函数添加了@st.cache_data装饰器也无效。上传的PDF文件未改变,不希望重复执行该函数(每次执行会产生成本),而Streamlit已弃用allow_mutation=True参数,需解决该问题。当前代码如下:
import streamlit as st import tempfile from typing import Optional from langchain_core.documents import Document from langchain.document_loaders import PyPDFLoader @st.cache_data def document_loader(doc_path: str) -> Optional[Document]: """ 将指定格式的文档转换为Langchain Document对象 参数: doc_path (str): PDF文档的路径字符串 返回: Optional[Document]: Document类实例;若文件未找到则返回None """ loader = PyPDFLoader(doc_path) docs = loader.load() print("Document loader done") uploaded_file = st.sidebar.file_uploader("Upload a file", key= "uploaded_file") if uploaded_file is not None: with tempfile.NamedTemporaryFile(delete=False) as temp_file: temp_file.write(uploaded_file.getvalue()) temp_file_path = temp_file.name print(temp_file_path) custom_qa = document_loader(temp_file_path)
内容的提问来源于stack exchange,提问作者Baktaawar
相关产品推荐
相关产品推荐

