poster2json
Convert scientific posters (PDF/images) to structured JSON metadata using Large Language Models.
Documentation · Changelog · Report Bug · Request Feature
Description
poster2json extracts structured metadata from scientific conference posters (PDF or image format) into machine-actionable JSON conforming to the poster-json-schema.
The pipeline uses:
- Llama-3.1-8B-Instruct (a verbatim mirror of Meta's release; swap with any HuggingFace instruct model via
--model) for JSON structuring - pdfplumber for layout-aware PDF text extraction (stream-order
altolayout engine by default;POSTER2JSON_LAYOUT=blocksselects the XY-cut engine) - lingua-language-detector for ISO 639-1 language detection on body text (overrides any value the model emits — body text beats metadata-fragment guessing)
- ROR (
https://api.ror.org) for affiliation canonicalisation; matched names get a ROR identifier attached - ORCID (
https://pub.orcid.org) for author disambiguation; matched creators get an ORCID identifier attached (uses the authenticated Member API whenORCID_CLIENT_IDandORCID_CLIENT_SECRETare set, otherwise the public API)
Quick Start
Installation
pip install poster2json
CLI Usage
# Extract metadata from a poster (default: Llama-3.1-8B-Instruct @ 4bit)
poster2json extract poster.pdf -o result.json
# Use a different instruct model (any HuggingFace repo id works)
poster2json extract poster.pdf --model google/gemma-2-9b-it --quantization 4bit
# Trade VRAM for quality
poster2json extract poster.pdf --quantization 8bit
poster2json extract poster.pdf --quantization fp16
# Validate extracted JSON
poster2json validate result.json
# Process multiple posters
poster2json batch ./posters/ -o ./output/
Python API
from poster2json import extract_poster, validate_poster
# Extract metadata
result = extract_poster("poster.pdf")
print(result["titles"][0]["title"])
# Validate the result
is_valid = validate_poster(result)
Output Format
Output conforms to the poster-json-schema (DataCite 4.7):
{
"$schema": "https://posters.science/schema/v0.2/poster_schema.json",
"creators": [
{
"name": "Garcia, Sofia",
"givenName": "Sofia",
"familyName": "Garcia",
"affiliation": [
{
"name": "Stanford University",
"affiliationIdentifier": "https://ror.org/00f54p054",
"affiliationIdentifierScheme": "ROR",
"schemeURI": "https://ror.org/"
}
]
}
],
"titles": [
{ "title": "Machine Learning Approaches to Diabetic Retinopathy Detection" }
],
"publicationYear": null,
"language": "en",
"researchField": "Health Sciences",
"subjects": [
{ "subject": "Machine Learning" },
{ "subject": "Diabetic Retinopathy" }
],
"descriptions": [
{ "description": "We present a deep learning model...", "descriptionType": "Other" }
],
"publisher": null,
"content": {
"sections": [
{ "sectionTitle": "Abstract", "sectionContent": "..." },
{ "sectionTitle": "Methods", "sectionContent": "..." },
{ "sectionTitle": "Results", "sectionContent": "..." }
]
},
"imageCaptions": [{ "id": "fig1", "caption": "Figure 1. ROC curves showing..." }],
"tableCaptions": [{ "id": "table1", "caption": "Table 1. Performance metrics" }],
"formats": ["application/pdf"]
}
Notes on the auto-populated fields:
languageis detected from the raw body text (lingua heuristic). Returns null when text is too short (<200 chars / <50 non-ASCII codepoints) or the detector is unsure.researchFieldmust be one of the four OpenAlex top-level domains:Health Sciences,Life Sciences,Physical Sciences,Social Sciences. Null when the model can't pick one confidently.affiliationgets ROR enrichment when the matcher returns a high-confidence chosen result. Strings without a confident match pass through unchanged. SetPOSTER2JSON_ROR=0to disable.publisherandpublicationYearare always emitted asnull. They are platform-owned and set when the poster is published, not by extraction.formatsis derived from the input file's extension, not the model.
System Requirements
| Requirement | Specification |
|---|---|
| GPU | NVIDIA CUDA-capable, ≥8GB VRAM (default 4bit); ≥16GB for --quantization fp16 or image/OCR posters |
| RAM | ≥32GB recommended |
| Python | 3.10+ |
| OS | Linux, macOS, Windows (via WSL2) |
Performance
Validated on 20 manually annotated scientific posters (19 PDF via pdfplumber, 1 image via vision OCR):
| Metric | Score | Threshold |
|---|---|---|
| Word Capture | 0.92 | ≥0.75 |
| ROUGE-L | 0.85 | ≥0.75 |
| Number Capture | 0.97 | ≥0.75 |
| Field Proportion | 0.88 | 0.50–1.50 |
Pass Rate: 19/20 (95%). The single failure is a dense table/flowchart poster whose reference annotation splits one visual region into many fine-grained sections.
Documentation
| Document | Description |
|---|---|
| Architecture | Technical details & methodology |
| Evaluation | Validation metrics & results |
Development Setup
# Clone the repository
git clone https://github.com/fairdataihub/poster2json.git
cd poster2json
# Create a virtual environment
python -m venv .venv
# Activate the virtual environment
source venv/bin/activate
.venv\Scripts\activate # On Windows
# Install poetry
pip install poetry
# Install dependencies
poetry install
# Run tests
poe test
# Format code
poe format
If you are on windows and have multiple python versions, you can use the following commands:
py -0p # list all python versions
py -3.12 -m venv .venv
License
MIT License - see LICENSE for details.
Citation
@software{poster2json2026,
title = {poster2json: Scientific Poster to JSON Metadata Extraction},
author = {O'Neill, James and Soundarajan, Sanjay and Portillo, Dorian and Patel, Bhavesh},
year = {2026},
version = {0.8.0},
url = {https://github.com/fairdataihub/poster2json},
doi = {10.5281/zenodo.18320010}
}
Funding
This project is funded by The Navigation Fund (10.71707/rk36-9x79).
Contributing
Contributions welcome! Please see CONTRIBUTING.md for guidelines.
Metadata
Release files for poster2json 0.10.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| poster2json-0.10.5.tar.gz | 148.3 kB | Without provenance | Details for poster2json-0.10.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| poster2json-0.10.5-py3-none-any.whl | Python 3 | none | any | Details for poster2json-0.10.5-py3-none-any.whl |
Total release size: 304.0 kB
Release files / poster2json-0.10.5.tar.gz
| Download URL | poster2json-0.10.5.tar.gz |
|---|---|
| Size | 148.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e5d23ad9e990f5a469f0c1d0b4fb829ac4f160b99cde5a445de3a49e9814d0fd
|
|
BLAKE2b-256 checksum How to use checksums |
b6abb5d9f76ccd797002f805941bb2636ae5dea3013cac4d386a42153e1b76a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.5.1 CPython/3.12.15 Linux/6.17.0-1022-azure
|
Release files / poster2json-0.10.5-py3-none-any.whl
| Download URL | poster2json-0.10.5-py3-none-any.whl |
|---|---|
| Size | 155.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
75f26b986d5efb9789cbd828c8c48939850a4362ef64e4f3a3ae3cf86f829b96
|
|
BLAKE2b-256 checksum How to use checksums |
5468830c25f367588a865897f42b0a98135755420c42caabacb5e2ea583df903
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.5.1 CPython/3.12.15 Linux/6.17.0-1022-azure
|
Security for poster2json 0.10.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.