FastAPI中UploadFile转BytesIO适配PDFMiner/Tesseract-OCR问题
解决FastAPI UploadFile适配PDFMiner/Tesseract-OCR的两种方案
方案一:将UploadFile转为BytesIO(适配原有类文件对象逻辑)
FastAPI的UploadFile对象可通过read()方法获取字节内容,直接封装成BytesIO就能和你之前Streamlit环境下的逻辑无缝对接——因为BytesIO是标准类文件对象,和Streamlit返回的对象接口完全一致。
示例代码:
from fastapi import FastAPI, UploadFile from io import BytesIO app = FastAPI() # 假设你的TextExtraction类已有适配BytesIO的extract_text方法 class TextExtraction: @staticmethod def extract_text(file_obj): # 原有处理PDFMiner/Tesseract的逻辑,接收类文件对象 pass @app.post("/extract-text/") async def handle_upload(file: UploadFile): # 读取上传文件内容并转为BytesIO file_content = await file.read() bytes_io_obj = BytesIO(file_content) # 直接传入原有方法 extracted_text = TextExtraction.extract_text(bytes_io_obj) return {"extracted_text": extracted_text}
你之前尝试转成bytes类型失败,是因为bytes是字节串,不具备类文件对象的read()等操作方法,而PDFMiner/Tesseract的接口需要的是类文件对象或文件路径,所以转成BytesIO才是正确的适配方式。
方案二:用临时文件适配(针对需要文件路径的场景)
如果你的OCR/PDF处理逻辑必须依赖本地文件路径(比如Tesseract某些场景下只能识别文件路径而非类文件对象),可以用Python的tempfile模块创建临时文件,把UploadFile的内容写入后再传给处理方法。
示例代码:
from fastapi import FastAPI, UploadFile import tempfile import os from pdfminer.high_level import extract_text as pdf_extract import pytesseract from PIL import Image app = FastAPI() class TextExtraction: @staticmethod def extract_text(input_source): # 调整方法,同时支持类文件对象和文件路径 if isinstance(input_source, str): # 按文件后缀判断处理逻辑 if input_source.endswith(".pdf"): return pdf_extract(input_source) else: return pytesseract.image_to_string(input_source) else: # 原有类文件对象处理逻辑 if input_source.name.endswith(".pdf"): return pdf_extract(input_source) else: img = Image.open(input_source) return pytesseract.image_to_string(img) @app.post("/extract-text/") async def handle_upload(file: UploadFile): # 创建带后缀的临时文件,保证识别文件类型 file_suffix = f".{file.filename.split('.')[-1]}" if "." in file.filename else "" with tempfile.NamedTemporaryFile(delete=False, suffix=file_suffix) as temp_file: # 写入上传内容 temp_file.write(await file.read()) temp_file_path = temp_file.name try: # 传入临时文件路径给处理方法 extracted_text = TextExtraction.extract_text(temp_file_path) finally: # 用完删除临时文件,避免磁盘占用 os.unlink(temp_file_path) return {"extracted_text": extracted_text}
注意事项
- 临时文件要保留原文件后缀,否则PDFMiner/Tesseract可能无法正确识别文件类型
- 必须在
finally块中删除临时文件,防止程序异常时遗留文件占用磁盘
内容的提问来源于stack exchange,提问作者Sin of Greed
相关产品推荐
相关产品推荐

