본문 바로가기

안녕하세요!

카테고리 없음

[ Python ] Open WebUI 커스터마이징 - file upload(1)

try_upload


 

def try_upload(path, mime_type, upload_name):
    with open(path, "rb") as f:
        return requests.post(
            f"{WEBUI}/api/v1/files/",
            headers=HDR_FILE,
            files={"file": (upload_name, f, mime_type)},
            timeout=60,
        )

 

path : 업로드할 로컬 파일의 절대 경로

mime_type : 서버에 전달할 콘텐츠 타입

upload_name : 서버/웹UI에 표시될 파일명

with open(path, "rb") as f
  - 바이너리 읽기 모드로 file handle f 열기
  - text로 열게 되면 개행 및 인코딩의 변형 가능성이 있음
  - 이미지, 엑셀 등의 비정형 데이터를 안전하게 전송해야 함
  - with 블록을 벗어나면 파일은 자동으로 닫힘

requests.post(...)
  - f"{WEBUI}/api/v1/files/"  : .env에서 읽은 WEBUI_URL을 바탕으로 한 파일 업로드 앤드포인트
  - headers=HDR_FILE : Authorization(Barer 토큰)만 있음, content-Type 직접 지정 X
  - files={"file": (upload_name, f, mime_type)} : requests의 멀티파트 업로드 규약

 

# 공통 헤더(서버가 HTML을 주지 않도록 Accept 추가)
HDR_JSON = {
    "Authorization": f"Bearer {API_TOKEN}",
    "Content-Type": "application/json",  # 요청 방식 = json
    "Accept": "application/json",        # 응답 방식 = json
}
HDR_FILE = {"Authorization": f"Bearer {API_TOKEN}"}

 

body 파트에 있는 file은 멀티파트로 생성되기 때문에
header가 json 형태일지라도 body 타입과 불일치하게 되어
HDR_JSON을 사용하면 파싱에 실패하게 됨

Authorization만 주고 Content-Type을 비워두면
requests가 멀티파트에 맞는 Content-Type: multipart/form-data; boundary=...를 자동으로 삽입

 

poll_file_indexed


 

def poll_file_indexed(file_id: str, max_wait_sec=30, interval_sec=2):
    """간단 폴링으로 색인/추출 완료 추정"""
    deadline = time.time() + max_wait_sec
    last_ok = False
    while time.time() < deadline:
        try:
            r = requests.get(f"{WEBUI}/api/v1/files/{file_id}", headers=HDR_JSON, timeout=15)
            if r.status_code == 200:
                j = r.json()
                if isinstance(j, dict) and j.get("data"):
                    return True
                last_ok = True
        except Exception:
            pass
        time.sleep(interval_sec)
    return last_ok

 

max_wait_sec=30 : 폴링 최대 30초 동안 시도하는 목표 시간

interval_sec=2 : 각 시도 사이 대기 간격 2초

deadline = time.time() + max_wait_sec : 목표 종료 시각(UNIX 타임)

last_ok = False : 도중에 한 번이라도 200 OK를 받았는지 기억하는 플래그

최대 30초 동안 GET /api/v1/files/{file_id} 경로로 서버에 요청을 반복

서버에서 200 OK를 주고, 응답 JSON 안에 data가 채워져 있으면 last_ok = True 반환

data가 비어 있으면 2초 뒤에 다시 요청

30초가 지나면 머춤

 


loading