You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 23:15:42