我正在尝试使用streamlit和gpt索引创建某种虚拟测试网站。我不断收到同样的错误。
from gpt_index import GPTListIndex, readers, GPTSimpleVectorIndex, LLMPredictor, PromptHelper, download_loader
from langchain import OpenAI
import logging
import sys
import os
import streamlit as st
os.environ['OPENAI_API_KEY'] = "I am deleting my api key from this post"
fileup = st.file_uploader(label=" ")
SimpleDirectoryReader = download_loader("SimpleDirectoryReader")
loader = SimpleDirectoryReader(fileup)
documents = loader.load_data()
index = GPTSimpleVectorIndex(documents)
index.save_to_disk('index.json')
question = st.text_input("What do you want me to do with the file uploaded?")
response = index.query(question)
st.write(response)
为什么我不断收到“TypeError:预期的 str、bytes 或 os.PathLike 对象,而不是 NoneType”?
这是完整的错误:
Traceback (most recent call last):
File "/home/appuser/venv/lib/python3.9/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 565, in _run_script
exec(code, module.__dict__)
File "/app/indextest/streamlit_app.py", line 16, in <module>
loader = SimpleDirectoryReader(fileup)
File ".modules/file.py", line 67, in __init__
self.input_dir = Path(input_dir)
File "/usr/local/lib/python3.9/pathlib.py", line 1082, in __new__
self = cls._from_parts(args, init=False)
File "/usr/local/lib/python3.9/pathlib.py", line 707, in _from_parts
drv, root, parts = self._parse_args(args)
File "/usr/local/lib/python3.9/pathlib.py", line 691, in _parse_args
a = os.fspath(a)
TypeError: expected str, bytes or os.PathLike object, not NoneType
根据 Streamlit 文档,
st.file_uploader
要么返回 None
,要么返回 UploadedFileObject
(可以用作“类似文件”的对象):
https://docs.streamlit.io/library/api-reference/widgets/st.file_uploader
它没有明确提及它,但如果没有上传文件,它可能会返回
None
。我们无法告诉您为什么没有上传文件。
在您的情况下,这意味着
fileup
变量是 None
,这是 SimpleDirectoryReader
的无效参数,如错误消息所示。
文档中的示例包含一个
if
语句,仅当返回值不是 None
时才在脚本中继续。你可能也应该这样做。
fileuploader 返回以下类
class UploadedFile(io.BytesIO):
"""A mutable uploaded file.
This class extends BytesIO, which has copy-on-write semantics when
initialized with `bytes`.
"""
def __init__(self, record: UploadedFileRec, file_urls: FileURLsProto):
# BytesIO's copy-on-write semantics doesn't seem to be mentioned in
# the Python docs - possibly because it's a CPython-only optimization
# and not guaranteed to be in other Python runtimes. But it's detailed
# here: https://hg.python.org/cpython/rev/79a5fbe2c78f
super().__init__(record.data)
self.file_id = record.file_id
self.name = record.name
self.type = record.type
self.size = len(record.data)
self._file_urls = file_urls
def __eq__(self, other: object) -> bool:
if not isinstance(other, UploadedFile):
return NotImplemented
return self.file_id == other.file_id
def __repr__(self) -> str:
return util.repr_(self)
假设您尝试上传此文件,您首先必须保存该文件,然后上传它,因为它要求路径而不是(io.BytesIO)。
save_path = Path(save_folder, uploaded_file.name)
with open(save_path, mode='wb') as w:
w.write(uploaded_file.getvalue())
loader = SimpleDirectoryReader(save_path)
这将在您的系统上创建本地副本,并提供路径作为 SimpleDirectoryReader 函数的输入参数。