본문으로 건너뛰기

PDF 원본 분석과 인용 보존하기

px.DocumentAnalysis는 원본 PDF의 정확한 콘텐츠 참조, 페이지 정보와 추출된 구간을 보존하는 불변 값입니다. px.DocumentCitation은 그 분석의 구간을 정확히 가리킵니다. 두 값은 UI나 Client 없이 Core에서 검증하고 직렬화할 수 있습니다.

python
from pathlib import Path
from pipelinexlab import px

# processor_result는 지원하는 document-analysis schema의 추출 결과 dict입니다.
analysis = px.DocumentAnalysis.from_wire(processor_result)
Path("analysis.json").write_bytes(analysis.canonical_bytes)

reopened = px.DocumentAnalysis(Path("analysis.json").read_bytes())
citation = reopened.citation(["paragraph_1", "paragraph_2"])
Path("citation.json").write_bytes(citation.canonical_bytes)

selected = px.DocumentCitation(Path("citation.json").read_bytes()).resolve(reopened)

canonical_bytes는 Core가 검증한 canonical JSON이며 content_ref는 그 bytes의 digest 참조입니다. to_dict()는 분리된 복사본을 반환합니다. 인용의 segment_keys는 중복 없이 분석의 읽기 순서를 따라야 합니다. 원본 파일이나 엔진·모델·설정·분석 구간이 바뀌면 기존 인용을 새 분석으로 옮겨 해석하지 않고 거절합니다.

페이지의 mediaBoxcropBox는 PDF point 단위, 좌하단 원점의 회전 전 좌표입니다. cropBox는 MediaBox 안의 유효한 표시 영역입니다. 구간의 regions회전 전 CropBox의 좌상단 원점에서 0..1로 정규화한 좌표이며, rotationDegrees는 0/90/180/270입니다. 좌표와 신뢰도는 기존 정밀도·scale 제한을 따르는 canonical decimal 문자열을 사용합니다. 화면 확대율이나 뷰어 내부 문자 인덱스는 저장하지 않습니다.

segments의 배열 순서가 논리적 읽기 순서입니다. 원문, 페이지, 영역, text-layer | ocr, 신뢰도와 언어를 함께 보존합니다. language는 제품 UI의 ko/en 목록과 무관한 언어 태그이며 대소문자 표기를 정규화합니다. 언어를 기록할 수 있다는 사실이 해당 언어의 OCR·번역 엔진을 설치하거나 실행할 수 있다는 뜻은 아닙니다. 언어 태그의 문법 확인은 language-tags의 RFC 5646 parser를 사용합니다.

이 API는 입력 데이터의 계약을 검증합니다. PDF bytes의 실제 읽기 권한, 추출 엔진의 실행 증명, OCR·번역 실행, 결과 검토와 Report 반영을 수행하지 않습니다. 파일에 저장한 인용을 다시 열려면 해당 인용이 참조하는 분석과 원본도 함께 보존해야 합니다.

잘못된 값은 px.ErrorValueError로 처리할 수 있고 .diagnostics를 제공합니다. 미지원 버전 등의 native 거부는 .original_bytes에 원래 bytes를 보존합니다.

정확한 형식은 V1 schemaV2 schema, 호출 형식은 SDK 문법을 따릅니다.

처리한 페이지 범위 보존하기

V2는 processedPageIndices에 처리를 끝낸 페이지를 기록합니다. 0부터 시작하는 물리적 페이지 번호를 중복 없이 오름차순으로 넣으며, 최소 한 페이지가 필요합니다. 모든 구간의 pageIndex는 이 범위에 속해야 합니다. source.pages는 여전히 원본 전체의 페이지 정보입니다.

예를 들어 3페이지 원본에서 processedPageIndices: [0, 2], segments: []이면 첫째·셋째 페이지를 처리했지만 추출 구간은 없다는 뜻입니다. 둘째 페이지는 처리 완료 범위에 없습니다. 이 기록은 원본이 실제로 비어 있다는 판정이나 OCR 품질·검토 승인을 뜻하지 않습니다.

V1은 완료 범위를 알 수 없는 기존 값으로 그대로 읽습니다. 구간이 없거나 원본 페이지 정보가 있다는 이유로 완료 범위를 채우거나 V2로 자동 변환하지 않습니다. 기존 canonical bytes와 digest·인용은 유지됩니다. 범위를 추가한 V2는 별도의 분석 식별자를 가집니다. V2 출력을 도입하는 엔진 버전·설정 변경은 기존 processor 참조에 반영합니다. 기존 완료 작업이나 분석 바이트를 덮어써서 형식만 바꾸지 않습니다.

Runtime은 V2 추출 결과의 완료 범위가 요청한 페이지와 일치하는지 확인합니다. V2 분석을 번역 입력으로 사용할 때도 요청 페이지가 완료 범위에 포함돼야 합니다. 기존 V1 엔진 결과는 계속 지원하지만 완료 범위가 검증됐다고 간주하지 않습니다. 이 정보는 기존 client.retain_document와 문서 내보내기·가져오기로 분석 바이트와 함께 보존합니다.

분석 bytes 다시 열기

px.DocumentAnalysis(data: bytes)는 지원하는 버전의 저장 bytes를 검증합니다.

추출 결과 검증하기

px.DocumentAnalysis.from_wire(document: dict)는 같은 검증을 dict에 적용합니다.

분석 복사본 읽기

analysis.to_dict()의 반환값을 수정해도 원래 분석은 바뀌지 않습니다.

구간 인용 만들기

analysis.citation(segment_keys: list[str])는 비어 있거나 중복·미등록·역순인 선택을 거절합니다.

인용 bytes 다시 열기

px.DocumentCitation(data: bytes)는 인용 형식을 검증합니다. 대상의 존재 확인은 resolve에서 합니다.

인용 dict 검증하기

px.DocumentCitation.from_wire(document: dict)는 같은 형식 검증을 dict에 적용합니다.

인용 복사본 읽기

citation.to_dict()는 원본·분석 참조와 선택 구간 key의 분리된 복사본입니다.

정확한 분석으로 인용 해석하기

citation.resolve(analysis: DocumentAnalysis)는 정확한 원본·분석 digest와 선택 순서를 확인한 뒤 list[dict]로 구간 복사본을 반환합니다. 재추출 결과로 자동 이동하지 않습니다.