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

Azure容器应用部署FastAPI PDF处理服务后POST请求返回502/507/503错误排查求助

Azure容器应用部署FastAPI PDF处理服务后POST请求返回502/507/503错误排查求助

我在Azure容器应用中部署了一个基于FastAPI的Docker镜像应用,核心功能是接收上传的PDF文件,对内容进行脱敏处理后返回修改后的PDF。在本地开发环境运行时,整个流程完全正常,但部署到Azure后,调用POST接口/http_trigger时会返回以下错误:

upstream connect error or disconnect/reset before headers. reset reason: connection termination

不过简单的GET测试接口/hello(返回"hello world")却能正常响应,这说明容器应用的部署本身应该是成功的,但POST请求的处理环节出了问题。我查看了协议流日志,也没找到有用的排查信息。

我对Azure的使用经验不算多,真心希望能得到大家的帮助,谢谢!


main.py

from fastapi import FastAPI, HTTPException, File, UploadFile  
import logging  
import io  
from app.redact_pdf import redact_pdf  
from fastapi.responses import StreamingResponse  
  
app = FastAPI()  
  
@app.post("/http_trigger")  
async def http_trigger(file: UploadFile = File(...), language: str = None):  
    logging.info('FastAPI HTTP trigger function processed a request.')  
  
    if file.content_type == 'application/pdf':  
        input_pdf_stream = io.BytesIO(await file.read())  
  
        if not language:
            raise HTTPException(status_code=400, detail="The request does not contain language parameter.")  
  
        output_pdf_stream = redact_pdf(input_pdf_stream, language)  
          
        return StreamingResponse(  
            io.BytesIO(output_pdf_stream.read()),  
            media_type="application/pdf"  
        )  
    else:  
        raise HTTPException(status_code=400, detail="The request does not contain PDF data.")
    
@app.get("/hello")  
async def read_root():  
    return {"message": "hello world"}  

redact_pdf.py

import pymupdf
import re
import io
import cv2  
import numpy as np  
from flair.data import Sentence  
from flair.models import SequenceTagger  
  
def redact_pdf(input_pdf_stream, language):  
    if language not in ["EN", "DE"]:  
        raise ValueError("Invalid language selection. Please choose 'EN' for English or 'DE' for German.")  
   
    if language == "EN":  
        tagger = SequenceTagger.load("flair/ner-english-large")  
    else:  
        tagger = SequenceTagger.load("flair/ner-german-large")  
  Open PDF from BytesIO-Stream  
    doc = pymupdf.open("pdf", input_pdf_stream)  
  
    zip_code_pattern = re.compile(r'\b\d{5}\b')  # Beispiel: 12345  
    email_pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')  
  
    phone_patterns = [  
        re.compile(r'\b\d{3}[-.\s]?\d{3}[-.\s]?\d{4}\b'),  # 123-456-7890 oder 123 456 7890  
        re.compile(r'\(\d{3}\)\s*\d{3}[-.\s]?\d{4}\b'),    # (123) 456-7890  
        re.compile(r'\b\d{4}[-.\s]?\d{3}[-.\s]?\d{3}\b'),  # 1234-567-890  
    ]  
  
    for page_num in range(len(doc)):  
        page = doc.load_page(page_num)  
        text = page.get_text()  
    
        sentence = Sentence(text)  
        tagger.predict(sentence)  
   
        entities = [(entity.start_position, entity.end_position, entity.text) for entity in sentence.get_spans('ner') if entity.tag in ["PER", "ORG", "LOC"]]  
   
        for match in zip_code_pattern.finditer(text):  
            start, end = match.span()  
            entities.append((start, end, match.group()))  
    
        for pattern in phone_patterns:  
            for match in pattern.finditer(text):  
                start, end = match.span()  
                entities.append((start, end, match.group()))  
   
        for match in email_pattern.finditer(text):  
            start, end = match.span()  
            entities.append((start, end, match.group()))  
  
        print(entities)  
  
        for start, end, entity_text in entities:  
            search_results = page.search_for(entity_text)  
            if search_results:  
                for rect in search_results:  
                    page.add_redact_annot(rect, text="REDACTED", fill=(0, 0, 0))  
   
        page.apply_redactions()  
   
        pix = page.get_pixmap()  
        img = np.frombuffer(pix.samples, dtype=np.uint8).reshape(pix.height, pix.width, pix.n)  
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
    
        binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)  
  
        contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  
  
        for cnt in contours:  
            x, y, w, h = cv2.boundingRect(cnt)    
            if 30 < w < 400 and 5 < h < 150:   
                page.add_redact_annot(pymupdf.Rect(x, y, x+w, y+h), text="REDACTED", fill=(0, 0, 0))  
  
        page.apply_redactions()  
    
    output_pdf_stream = io.BytesIO()  
    doc.save(output_pdf_stream, garbage=4, deflate=True, clean=True)  
    output_pdf_stream.seek(0)  
  
    return output_pdf_stream

Dockerfile

# Start with the official Python image  
FROM python:3.9-slim  
  
# Set the working directory  
WORKDIR /app  
  
# Install system dependencies  
RUN apt-get update \  
    && apt-get install --no-install-recommends -y \  
    gcc \  
    build-essential \  
    libgl1-mesa-glx \  
    libglib2.0-0 \  
    && apt-get clean  
  
# Install python packages  
COPY requirements.txt .  
RUN pip install --no-cache-dir -r requirements.txt  
  
# Copy the application code  
COPY . .  
  
# Expose the port the app runs on  
EXPOSE 8000  
  
# Command to run the application  
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

备注:内容来源于stack exchange,提问作者leabum

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 15:48:10