Python 퀵스타트 — 첫 파싱 잡

Python 퀵스타트 — 첫 파싱 잡

Unstructured를 처음 쓰는 가장 빠른 방법은 Python SDK로 파일 하나를 파싱해 보는 거예요. 샘플 연례 보고서를 기준으로 잡(job)을 만들고 상태를 폴링한 뒤 결과를 내려받는 흐름을 볼게요. Python 3.11 이상이 필요해요.

출처: https://docs.unstructured.io/quickstart-api

1. 계정 생성과 API 키

transform.unstructured.io에서 등록하고 API 키를 복사해요.

2. Python SDK 설치

pip install "unstructured-client>=0.46.2"

3. 실행 스크립트

아래 스크립트는 Partitioner 노드만 써서 파일을 표준 문서 요소로 파싱해요. Auto 전략(설정의 subtype: "vlm", allow_fast: True)이 페이지를 평가해 Fast/High Res/VLM 파티셔닝 중 하나로 라우팅해 품질·속도·비용을 균형 있게 맞춰요. API_URLhttps://platform-api.transform.unstructured.io/api/v1로 미리 설정돼 있어요.

import json
import mimetypes
import os
import time

from unstructured_client import UnstructuredClient
from unstructured_client.models.operations import CreateJobRequest, DownloadJobOutputRequest
from unstructured_client.models.shared import BodyCreateJob, InputFiles

API_KEY = "YOUR_API_KEY_HERE"
INPUT_DIR = "/full/path/to/your/input/directory"
OUTPUT_DIR = "/full/path/to/your/output/directory"
API_URL = "https://platform-api.transform.unstructured.io/api/v1"

client = UnstructuredClient(api_key_auth=API_KEY, server_url=API_URL)

# Step 1: Create the job.
input_files = []
for filename in os.listdir(INPUT_DIR):
    full_path = os.path.join(INPUT_DIR, filename)
    if not os.path.isfile(full_path):
        continue
    content_type, _ = mimetypes.guess_type(full_path)
    input_files.append(InputFiles(
        content=open(full_path, "rb"),
        file_name=filename,
        content_type=content_type or "application/octet-stream",
    ))

try:
    response = client.jobs.create_job(
        request=CreateJobRequest(
            body_create_job=BodyCreateJob(
                request_data=json.dumps({
                    "job_nodes": [
                        {
                            "name": "Partitioner",
                            "type": "partition",
                            "subtype": "vlm",
                            "settings": {"is_dynamic": True, "allow_fast": True},
                        }
                    ]
                }),
                input_files=input_files,
            )
        )
    )
finally:
    for input_file in input_files:
        input_file.content.close()

job_id = response.job_information.id
print(f"Job ID: {job_id}")

# Step 2: Poll until the job completes.
while True:
    response = client.jobs.get_job(request={"job_id": job_id})
    status = response.job_information.status
    print(f"Job status: {status.value}")
    if status == "COMPLETED":
        break
    elif status in ("FAILED", "STOPPED"):
        raise RuntimeError(f"Job did not complete successfully: {status}")
    time.sleep(10)

# Step 3: Download the job output.
os.makedirs(OUTPUT_DIR, exist_ok=True)
output_node_file_ids = [f.file_id for f in (job_info.output_node_files or [])]
for file_id in output_node_file_ids:
    response = client.jobs.download_job_output(
        request=DownloadJobOutputRequest(job_id=job_id, file_id=file_id)
    )
    output_path = os.path.join(OUTPUT_DIR, f"{file_id}.json")
    with open(output_path, "w") as f:
        json.dump(response.any, f, indent=4)
    print(f"Saved: {output_path}")

표준 문서 요소

파싱 결과 JSON에는 문서 요소 타입이 담겨 있어요. 주요 타입은 Footer, Header, Image, ListItem, NarrativeText, PageBreak, PageNumber, Table, Title, UncategorizedText이에요. 각 요소에는 페이지 좌표(coordinates), 부모 관계(parent_id), 표의 HTML 렌더링(text_as_html), 이미지의 Base64(image_base64) 같은 메타데이터가 포함돼요.

더 알아보기