Shared PDF annotation engine for AEMS: schema-driven verdict markers, page-anchored highlights, and LLM-output payload contract
Project description
aems-pdf-annotator
Schema-driven PDF annotation engine for AEMS — the Assisted Exam Marking System.
What this is
A small, focused library that takes a structured annotation payload (LLM output, rubric verdicts, page-anchored highlights) and draws it onto a PDF using PyMuPDF. It powers the annotated marker PDFs that AEMS returns to instructors.
Key surfaces:
PDFAnnotation,BBox,AnnotationBatch— typed models for the annotation payload (Pydantic v2).payload_to_annotations(),feedback_items_to_annotations()— convert AEMS LLM output (the "annotation contract") into typed annotation objects.PDFAnnotator,apply_annotations(),apply_annotation_batch()— open a PDF, draw the annotations, save.- Validator + schemas — invariants on coordinates, colours, icons, verdicts.
Installation
pip install aems-pdf-annotator
Or from source:
pip install git+https://github.com/aems-app/aems-pdf-annotator
Requires Python 3.10+.
Minimal example
from aems_pdf_annotator import (
PDFAnnotation, BBox, AnnotationColor, AnnotationType,
apply_annotations,
)
annotations = [
PDFAnnotation(
page=1,
bbox=BBox(x=0.10, y=0.20, width=0.40, height=0.04),
annotation_type=AnnotationType.HIGHLIGHT,
color=AnnotationColor.GREEN,
content="Correct identification of the boundary condition.",
is_verdict=False,
),
PDFAnnotation(
page=1,
bbox=BBox(x=0.80, y=0.20, width=0.03, height=0.03),
annotation_type=AnnotationType.STAR,
color=AnnotationColor.GREEN,
content="PASS",
is_verdict=True,
),
]
apply_annotations(
input_pdf_path="input.pdf",
output_pdf_path="annotated.pdf",
annotations=annotations,
)
Coordinates are normalised (0.0–1.0) with (0, 0) at the top-left of the page; the renderer converts to PDF bottom-left internally.
Contract version
The LLM-output payload format follows a versioned contract. Current values are exported as CURRENT_CONTRACT_VERSION and CURRENT_COORDINATE_SPACE. payload_to_annotations() validates the incoming payload's contract version against SUPPORTED_CONTRACT_VERSIONS and raises ContractValidationError on a mismatch.
License
AGPL-3.0-or-later. See LICENSE.
This package wraps PyMuPDF, which is itself licensed under AGPL-3.0. Any program that imports aems_pdf_annotator in-process inherits the AGPL combined-work obligations. If that does not fit your distribution model, commercial PyMuPDF licensing is available from Artifex.
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aems_pdf_annotator-0.2.0.tar.gz.
File metadata
- Download URL: aems_pdf_annotator-0.2.0.tar.gz
- Upload date:
- Size: 269.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
26b7f1a250849a56c392b1f85a15a4c1661ad7f78d1262e4e103030e6b8028a2
|
|
| MD5 |
b749e1d7334a746cfada483b5103bd6c
|
|
| BLAKE2b-256 |
49c375ff0a441380e9fbef0dc63562c222f29216e22a85caf68cb607b4bba868
|
File details
Details for the file aems_pdf_annotator-0.2.0-py3-none-any.whl.
File metadata
- Download URL: aems_pdf_annotator-0.2.0-py3-none-any.whl
- Upload date:
- Size: 45.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b92a8480699dcb990fb6138b2841022b83d934a61a306de1f3538ef924fb68d0
|
|
| MD5 |
b8001d0cf073b502713ff52d70651cb0
|
|
| BLAKE2b-256 |
0ab1af48963829838222629217e026b342c3c97f1d37c853173d252c4ad63e3b
|