A Model-Driven QTI-Based pipeline that converts PDF-based assessments into QTI (Question & Test Interoperability) 3.0 format and then exports them as Moodle-compatible XML quizzes.
This pipeline automates the conversion of PDF documents into structured assessment formats:
- PDF → QTI XML - Extract questions from PDFs and generate QTI 3.0 XML using GPT API.
- QTI XML → QTI Model - Parse QTI XML into a QTI-based model.
- QTI Model → Moodle XML - Generate Moodle quiz XML from the QTI model.
PDF-to-LMS-Converter/
├── src/
│ ├── __init__.py
│ ├── __pycache__/
│ ├── pdf_to_qti/ # PDF processing and QTI generation
│ │ ├── __init__.py
│ │ ├── pdf_to_qti.py # Main PDF extraction and QTI generation
│ │ ├── config.py # Configuration settings (paths)
│ │ ├── __pycache__/
│ │ └── llm_assistant/ # Assistant materials for LLM-based QTI generation
│ │
│ └── qti_to_lms/ # QTI conversion and LMS export
│ ├── __init__.py
│ ├── besser_to_moodle.py # QTI model to Moodle XML conversion
│ ├── qti_to_besser.py # QTI XML to QTI model conversion
│ ├── qti_to_lms.py # Main qti_to_lms pipeline orchestrator
│ ├── __pycache__/
│ ├── metamodel/ # Domain models
│ │ └── qti.py # QTI-based metamodel classes
│ └── templates/ # Jinja2 templates
│ └── moodle_template.py.j2
│
├── evaluation_scripts/ # Evaluation scripts for correctness assessment
│ ├── pdf_to_qti_eval.py # Evaluates PDF-to-QTI conversion accuracy
│ └── qti_to_moodle_eval.py # Evaluates QTI-to-Moodle conversion accuracy
│
├── evaluation_results/ # Evaluation outputs
│ ├── Canterbury_Question_Bank/
│ └── QTI3_Examples/
├── extensibility/ # French language resources
├── run_pipeline.py # Main pipeline module
├── script.py # Example usage script
├── requirements.txt # Python dependencies
├── __pycache__/
└── README.md # This file
- Python 3.8+
- OpenAI API key (for LLM-based PDF analysis)
-
Clone or navigate to the project:
cd PDF-to-LMS-Converter -
Create a virtual environment (recommended):
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
-
Configure API key: Obtain an OpenAI API key and set it in your script (see Usage below).
To run the pipeline, create a Python script (e.g., script.py) that imports and calls the pdf_to_moodle function:
from run_pipeline import pdf_to_moodle
qti_file = pdf_to_moodle(
api_key="your-openai-api-key-here",
pdf_path=r"path\to\input\pdf\file.pdf",
output_folder=r"path\to\output\folder" # Optional
)Then run the script:
python script.pyThis will:
- Process the specified PDF file
- Generate QTI XML files
- Convert to QTI-based model
- Export to Moodle XML format in the specified output folder (or
output/by default)
| Package | Version | Purpose |
|---|---|---|
requests |
≥2.31.0 | HTTP requests for OpenAI API |
pdfplumber |
≥0.11.0 | PDF text extraction |
retrying |
≥1.3.3 | Retry logic for API calls |
jinja2 |
≥3.1.2 | Template rendering for Moodle XML |
Represents a QTI-based metamodel with these domain classes:
Enumerations:
NavigationModeEnum- Assessment navigation (LINEAR, NONLINEAR)SubmissionModeEnum- Response submission (INDIVIDUAL, SIMULTANEOUS)ShowHideEnum- Conditional visibility (SHOW, HIDE)
Core Classes:
AssessmentDefinition- Root container for a complete assessmentAssessmentPart- High-level Assessment division with navigation/submission modesAssessmentSection- Mid-level content organizer with visibility controlQuestion- Assessment item with body, responses, outcomes, and feedbackQuestionBody- Question content with selectable blocksResponseDeclaration- Expected response structure and scoringModalFeedback- Conditional feedback based on responses
- PDF Files - Assessment documents in
input/directory
- QTI XML (
output/qti_output.xml) - QTI 3.0 standard format - Moodle XML (
output/moodle.xml) - Moodle quiz import format
The codebase follows PEP 8 standards with strict pylint compliance.
- Ensure PDFs are text-based (not scanned images)
- Use
pdfplumberto manually Assessment extraction:pdfplumber.open("file.pdf")
- Check API key validity and quota
- Verify OpenAI API is accessible
- Check PDF file encoding
- Validate Moodle XML format
- Check compatibility with Moodle version
- Verify character encoding (UTF-8)