A sophisticated PDF document processing system that leverages AI-powered extraction to convert unstructured PDF documents into structured data. Built with modern Python technologies and designed for enterprise document processing workflows.
qwen3.5:9b-q4_K_M, without sending PDF content to a cloud service/app/upload supports multi-file upload and creates batch/document records for trackingconfig.yaml owns paths, web/auth/logging settings,
custom-task approvals, and secret aliases—not new workflow definitions/app/upload, /app/processing, /app/review, /app/failures, and /app/reports/app/admin, /app/admin/users, /app/admin/pipeline,
/app/schemas, /app/admin/tasks, /app/settings/validation, and
/app/admin/auditClone the repository
git clone <your-repo-url>
cd pdfdoc_extraction
Install dependencies
py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
npm ci
npm ci installs the frontend build dependencies used when rebuilding
committed CSS or browser assets. Node.js/npm is not required to run the
application when those committed assets are already present.
Configure the system
Open the ignored local config.yaml and set deployment paths, web/auth
settings, and provider secret aliases. Do not place new tasks or
pipeline blocks there. Create folders required by watch_folder.dir and
web.upload_dir before startup.
Run the application
.\.venv\Scripts\python.exe main.py
main.py owns database migration when
database.run_migrations_on_startup is enabled. Its web and worker children
verify the resulting schema before starting.
Access the web interface
Open your browser and navigate to http://localhost:8000/app/upload
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
requirements.txt contains pinned application dependencies. Contributors and
test environments should install requirements-dev.txt, which includes the
runtime set plus pytest, coverage, and browser-test tooling:
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
Key dependencies:
llama-cloud): AI-powered document extraction through Extract v2ollama): Native local API access for GLM-OCR and
its optional document resolverliteparse): Local PDF text, OCR and word-coordinate parsing
for the LiteParse task; its adapter calls the loopback Ollama HTTP APIpdfjs-dist): Vendored browser module and worker for source-PDF review# config.yaml
web:
host: "127.0.0.1"
port: 8000
secret_key: "your_secret_key"
upload_dir: "web_upload"
database:
path: "data/app_state.sqlite3"
run_migrations_on_startup: true
review:
default_queue_name: "default_review"
lock_timeout_minutes: 60
watch_folder:
dir: "watch_folder" # required startup-compatibility path, not pipeline routing
validate_pdf_header: true
processing_dir: "processing_folder_default"
pipeline_secrets:
llamacloud-primary: "SET-ONLY-IN-THIS-LOCAL-IGNORED-FILE"
Create review forms and pipelines visually after startup: publish and activate a
review-form version when schema-driven review is needed, add tasks to a pipeline
draft, reference secrets as { "$secret": "llamacloud-primary" }, save,
validate, publish, and activate the pipeline. config.yaml does not need
top-level tasks or pipeline sections after migration.
The local GLM-OCR task is document-generic: each pipeline supplies its own field
schema and semantic instructions. Complete-document resolution can reconcile
scalar and flat-object values across multi-page PDFs and one configured logical
table from structured page evidence. A bill of lading, insurance document, or
invoice therefore uses the same task implementation but should use a dedicated
pipeline and matching review form. Published definitions that omit
resolution_mode retain legacy page-merge behavior; newly added GLM-OCR tasks
in the visual editor default to complete-document resolution.
For text/layout parsing followed by local structured extraction, add Lite Parse Extract in Admin → Pipeline. Configure fields and document guidance, then add a matching Review Gate and JSON or CSV storage. The LiteParse task requires a downloaded local GGUF model and a credential-free HTTP loopback endpoint. It supplies no numeric confidence; retained word boxes are diagnostic and are not shown as verified review highlights. See the LiteParse setup guide and six-invoice validation report.
LiteParse can process suitable documents faster because a normal attempt uses one Ollama request, avoiding GLM-OCR's multiple per-page and resolver calls. Actual speed depends on document size, model choice, OCR, and available memory.
For larger documents whose complete evidence or item output cannot fit one local-model request, GLM-OCR is better positioned through page-based extraction and chunked table resolution. Its document-mode header resolver still receives all page images, so this is a scalability selection criterion rather than a guarantee of unlimited size or better accuracy. See the document-size selection criteria.
Output folders are task-owned in the exact SQLite pipeline version. CSV/JSON
tasks use data_dir, local PDF storage uses files_dir, archive tasks use
archive_dir, and split tasks use split_dir. CSV/JSON/local-PDF/split tasks
create their output directory when execution begins if permissions allow;
ArchivePdfTask requires its configured archive directory to exist.
Deployment _dir keys are the paths that ConfigManager creates at startup,
except watch_folder.dir.
The current runtime uses the llama-cloud SDK and LlamaCloud client. New code should not use the legacy llama-cloud-services / LlamaExtract agent flow. agent_id is legacy; use configuration_id for saved Extract v2 configurations or omit it to build an inline schema from fields.
After validating a saved Extract v2 configuration in the LlamaCloud UI, you can
run a one-file SDK and workflow fit check against a local PDF. Sample PDF
documents are not included in the GitHub repository; provide your own test
document or use a PDF from your existing document set. The manual tool reads a
YAML task definition; it does not read SQLite or resolve pipeline_secrets.
Export/copy the selected pipeline definition to an ignored local smoke file and
provide the API key through the current process:
$env:LLAMA_CLOUD_API_KEY = "set-locally"
$pdfPath = "C:\path\to\your\test-document.pdf"
.\.venv\Scripts\python.exe tools\llamacloud_extract_smoke.py --config smoke-pipeline.yaml --file $pdfPath --configuration-id "cfg-..."
If configuration_id is already set in the smoke definition, omit the override
flag. Do not commit the smoke definition or output because they can contain
customer/provider data.
The script writes:
raw_extract_result.json: raw result.extract_result from LlamaCloud.workflow_normalized_data.json: data after matching returned keys to workflow
fields and applying configured types.workflow_fit_report.json: missing workflow fields, extra raw keys,
validation errors, and pass/fail status.To re-check a saved raw result without another LlamaCloud call:
.\.venv\Scripts\python.exe tools\llamacloud_extract_smoke.py --config smoke-pipeline.yaml --raw-json test\data\llamacloud_smoke\raw_extract_result.json
CONFIG_PATH: Custom path to configuration fileUSE_RELOAD: Enable auto-reload for development (true/false)SQLite is the primary workflow-state store. The application records:
Workflow state is persisted in SQLite. /api/files and /api/status/{file_id} remain as legacy response shapes backed by SQLite; filesystem status files are not used. Use /app/* pages for browser workflows.
Admins can remove eligible whole-batch history through Clean up processing data on the Pipeline page. Deleted pages become reusable; immediate database file shrinkage is not promised and compaction is separate maintenance. See the pipeline retention guide for archive prerequisites, protected work, retained files, and recovery limits.
Before first login, initialize the two fixed SQLite users:
.\.venv\Scripts\python.exe tools\setup_users.py --config config.yaml
For an upgrade from YAML credentials, preserve the existing admin hash while creating the operator account:
.\.venv\Scripts\python.exe tools\setup_users.py --config config.yaml --legacy-config config.yaml
After a successful import, remove the legacy authentication block. Passwords must contain uppercase, lowercase, numeric, and symbol characters and be 12–72 UTF-8 bytes.
http://localhost:8000/app/upload and select admin or operator/app/upload, select one exact eligible published
pipeline version for the whole batch, and submit one or more PDFs/app/processing or /app/batches/{batch_id} to track queued work, splitting, extraction, review, and completion state/app/review and /app/review/{review_item_id} for human review queues/app/documents/{document_id}/extraction for extracted fields and source PDF access/app/reports and click a recent batch row to view document task timelines and task-run details/app/admin/pipeline, review forms in /app/schemas, inspect tasks and
validation, manage users, and view the admin_ audit subset/app/admin/pipeline, publish and
activate the pipeline, then bind an existing, non-overlapping incoming
folder to one exact published versionwatch_folder.dir alone is only a
required startup-compatibility path and does not assign a workflow# Run with default configuration
.\.venv\Scripts\python.exe main.py
# Use custom configuration
.\.venv\Scripts\python.exe main.py --config-path custom_config.yaml
# Run without web server (watch folder only)
.\.venv\Scripts\python.exe main.py --no-web
POST /api/login: API user authenticationPOST /api/session/refresh: Refresh the authenticated sessionPOST /login: Browser login formGET /logout: Browser session terminationGET /api/admin/users: List fixed accounts (admin only)PUT /api/admin/users/{username}/password: Change an account password (admin only)Repeated failed login attempts are temporarily throttled and may return HTTP 429 Too Many Requests.
The admin account has full access. The operator account cannot access administrative pages or APIs. Admins manage both passwords at /app/admin/users; changing a password revokes existing sessions for that account.
GET /health/live: Public web-process liveness with no operational details.GET /health/ready: Public supervised-runtime readiness (503 until ready).GET /api/admin/runtime-health: Run-scoped component and database diagnostics (admin only).POST /upload: Retired non-durable upload endpoint; returns 410 GoneGET /api/pipelines/available: List exact pipeline versions eligible for the current userPOST /api/batches/upload: Upload a batch of PDFs with a required
pipeline_version_id, create SQLite batch/document records, and enqueue
durable processing jobs; multipart file data is streamed through disk-backed
staging under configured file-count, file-size, request-size, and concurrency limitsGET /api/batches: List ingestion batchesGET /api/upload-submissions/{submission_id}: Resolve an upload receipt;
cleaned history returns status: purged and requires a deliberate new uploadGET /api/batches/{batch_id}: Get batch detailsGET /api/batches/{batch_id}/documents: List batch documentsGET /api/batches/{batch_id}/split-results: Show split source/child document relationshipsGET /api/documents/{document_id}/task-runs: List task runs for a documentGET /api/documents/{document_id}/extraction: Read extraction result and normalized fieldsGET /api/documents/{document_id}/fields: Read extracted/reviewed fieldsGET /api/documents/{document_id}/file/pdf: Stream the source PDF or registered PDF artifactPOST /api/documents/{document_id}/resume: Resume a document after reviewGET /api/files: Legacy compatibility list backed by SQLite documentsGET /api/status/{file_id}: Legacy compatibility detail backed by SQLite documents, task runs, and artifactsGET /api/review/items: List review queue itemsPOST /api/review/items/{review_item_id}/claim: Claim a review itemPOST /api/review/items/{review_item_id}/complete: Complete review and persist corrected valuesGET /api/reports/summary: Processing and review activity summaryGET /api/admin/settings, PUT /api/admin/settings: Admin configuration stateGET /api/admin/audit: Admin audit events/api/admin/pipeline-templates: Create/list named templates; per-template
endpoints manage metadata, clone, draft save/validate/import/export/diff,
immutable publish, and version historyGET /api/admin/pipeline-templates/{template_id}/archive-preview: Explain
archive impact and watch-folder blockersPOST /api/admin/pipeline-templates/{template_id}/archive: Archive an inactive
pipeline after name confirmation; definitions and history remainPOST /api/admin/pipeline-templates/{template_id}/cleanup-preview: Preview
eligible whole batches before an exclusive UTC cutoff_datePOST /api/admin/pipeline-templates/{template_id}/cleanup: Confirm a current
preview and exact pipeline name to delete eligible processing history;
request/response details/api/admin/review-schemas: Create/list review forms; per-template endpoints
manage metadata, draft save/validate/import/export, immutable publish,
versions, and dependency usage/api/admin/watch-folder-bindings: List/create bindings; per-binding
PATCH and DELETE update or remove eligible unreferenced bindingsGET /api/admin/pipeline, PUT /api/admin/pipeline/draft,
POST /api/admin/pipeline/publish, review-gate-rules, split-settings, and
filesystem /api/schemas endpoints are legacy compatibility/configuration
surfaces. New workflow authoring uses the versioned template endpoints.pdfdoc_extraction/
├── 📄 main.py # Application entry point
├── 📄 config.yaml # Ignored local deployment configuration (not committed)
├── 📄 requirements.txt # Pinned runtime Python dependencies
├── 📄 requirements-dev.txt # Runtime plus test/browser tooling
├── 📄 package.json # Production frontend asset tooling
├── 📁 modules/ # Core application modules
│ ├── api_router.py # API composition and request handling
│ ├── config_manager.py # Deployment configuration
│ ├── db/ # SQLite schema, migrations, and repositories
│ ├── services/ # Workflow, review, upload, queue, admin, and artifact use cases
│ ├── workflow_loader.py # Approved configured-task execution
│ └── workflow_manager.py # Root, split-child, and resumed flows
├── 📁 standard_step/ # Processing pipeline steps
│ ├── extraction/ # Data extraction tasks
│ │ ├── extract_pdf.py # Generic PDF extraction
│ │ ├── llama_cloud_v2.py # LlamaCloud Extract v2
│ │ ├── glm_ocr_extract.py # Local Ollama-backed GLM-OCR
│ │ └── liteparse_extract.py # Local LiteParse + Ollama extraction
│ ├── storage/ # Data storage tasks
│ ├── split/ # PDF split and fan-out tasks
│ ├── review/ # Human-review gate
│ ├── rules/ # Business rule tasks
│ ├── archiver/ # File archiving tasks
│ ├── context/ # Context management tasks
│ └── housekeeping/ # Cleanup and maintenance tasks
├── 📁 tools/ # Administrative tools and config checker
│ └── config_check/ # CLI: python -m tools.config_check
├── 📁 web/ # Web interface
│ ├── server.py # FastAPI application
│ ├── templates/ # HTML templates
│ └── static/ # CSS, JavaScript, assets
├── 📁 test/ # Unit, service, workflow, integration, security, and visual tests
├── 📁 docs/ # Architecture, operations, administration, and user guides
├── 📁 tasks/ # Task creation guidance, plans, and archived work
└── 📁 pipeline_visual_editor_prototype/ # Separate React/Vite prototype, not production UI
Runtime directories such as data/, files/, processing*/, output/,
web_upload/, and watch_folder/ hold local state or generated/customer
artifacts; they are not source folders to commit.
Start at the documentation entrance and choose your reading path:
See the product roadmap for agreed future work and the linked assessment of comparable extraction products.
Clone and install
git clone <repository-url>
cd pdfdoc_extraction
py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
Run tests
.\.venv\Scripts\python.exe -m pytest -v
Development mode
$env:USE_RELOAD="true"
.\.venv\Scripts\python.exe main.py
# Run all tests
.\.venv\Scripts\python.exe -m pytest -v
# Run specific test file
.\.venv\Scripts\python.exe -m pytest -v test/core/test_config_manager.py
# Run static type checking when Pyright is installed (it is not pinned in requirements.txt)
pyright
Example focused validation for SQLite-backed ingestion and operator state:
.\.venv\Scripts\python.exe -m pytest -v test\integration\test_sqlite_only_workflow_state.py test\integration\test_batch_upload_api.py test\integration\test_reports_api.py test\integration\test_settings_api.py
Run the full suite before handing off broad or cross-cutting changes.
The end-to-end workflow fixture config also passes config-check:
.\.venv\Scripts\python.exe -m tools.config_check validate --config test\data\config.yaml --import-checks
Application won't start
app.supervisor.log for a missing or incompatible database schemaPDF processing fails
Web interface issues
logging.log_file is the base path for role-specific logs. With the default
app.log, normal startup writes app.supervisor.log, app.web.log, and
app.worker.log; relative paths are resolved beside the active configuration
file. logging.log_level applies to all three processes.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)No repository license file is currently present. Confirm the applicable usage and distribution terms with the project owner before redistributing the code.
For support and questions:
docs/ folderBuilt with ❤️ for intelligent document processing
A sophisticated PDF document processing system that leverages AI-powered extraction to convert unstructured PDF documents into structured data. Built with modern Python technologies and designed for enterprise document processing workflows.
qwen3.5:9b-q4_K_M, without sending PDF content to a cloud service/app/upload supports multi-file upload and creates batch/document records for trackingconfig.yaml owns paths, web/auth/logging settings,
custom-task approvals, and secret aliases—not new workflow definitions/app/upload, /app/processing, /app/review, /app/failures, and /app/reports/app/admin, /app/admin/users, /app/admin/pipeline,
/app/schemas, /app/admin/tasks, /app/settings/validation, and
/app/admin/auditClone the repository
git clone <your-repo-url>
cd pdfdoc_extraction
Install dependencies
py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
npm ci
npm ci installs the frontend build dependencies used when rebuilding
committed CSS or browser assets. Node.js/npm is not required to run the
application when those committed assets are already present.
Configure the system
Open the ignored local config.yaml and set deployment paths, web/auth
settings, and provider secret aliases. Do not place new tasks or
pipeline blocks there. Create folders required by watch_folder.dir and
web.upload_dir before startup.
Run the application
.\.venv\Scripts\python.exe main.py
main.py owns database migration when
database.run_migrations_on_startup is enabled. Its web and worker children
verify the resulting schema before starting.
Access the web interface
Open your browser and navigate to http://localhost:8000/app/upload
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
requirements.txt contains pinned application dependencies. Contributors and
test environments should install requirements-dev.txt, which includes the
runtime set plus pytest, coverage, and browser-test tooling:
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
Key dependencies:
llama-cloud): AI-powered document extraction through Extract v2ollama): Native local API access for GLM-OCR and
its optional document resolverliteparse): Local PDF text, OCR and word-coordinate parsing
for the LiteParse task; its adapter calls the loopback Ollama HTTP APIpdfjs-dist): Vendored browser module and worker for source-PDF review# config.yaml
web:
host: "127.0.0.1"
port: 8000
secret_key: "your_secret_key"
upload_dir: "web_upload"
database:
path: "data/app_state.sqlite3"
run_migrations_on_startup: true
review:
default_queue_name: "default_review"
lock_timeout_minutes: 60
watch_folder:
dir: "watch_folder" # required startup-compatibility path, not pipeline routing
validate_pdf_header: true
processing_dir: "processing_folder_default"
pipeline_secrets:
llamacloud-primary: "SET-ONLY-IN-THIS-LOCAL-IGNORED-FILE"
Create review forms and pipelines visually after startup: publish and activate a
review-form version when schema-driven review is needed, add tasks to a pipeline
draft, reference secrets as { "$secret": "llamacloud-primary" }, save,
validate, publish, and activate the pipeline. config.yaml does not need
top-level tasks or pipeline sections after migration.
The local GLM-OCR task is document-generic: each pipeline supplies its own field
schema and semantic instructions. Complete-document resolution can reconcile
scalar and flat-object values across multi-page PDFs and one configured logical
table from structured page evidence. A bill of lading, insurance document, or
invoice therefore uses the same task implementation but should use a dedicated
pipeline and matching review form. Published definitions that omit
resolution_mode retain legacy page-merge behavior; newly added GLM-OCR tasks
in the visual editor default to complete-document resolution.
For text/layout parsing followed by local structured extraction, add Lite Parse Extract in Admin → Pipeline. Configure fields and document guidance, then add a matching Review Gate and JSON or CSV storage. The LiteParse task requires a downloaded local GGUF model and a credential-free HTTP loopback endpoint. It supplies no numeric confidence; retained word boxes are diagnostic and are not shown as verified review highlights. See the LiteParse setup guide and six-invoice validation report.
LiteParse can process suitable documents faster because a normal attempt uses one Ollama request, avoiding GLM-OCR's multiple per-page and resolver calls. Actual speed depends on document size, model choice, OCR, and available memory.
For larger documents whose complete evidence or item output cannot fit one local-model request, GLM-OCR is better positioned through page-based extraction and chunked table resolution. Its document-mode header resolver still receives all page images, so this is a scalability selection criterion rather than a guarantee of unlimited size or better accuracy. See the document-size selection criteria.
Output folders are task-owned in the exact SQLite pipeline version. CSV/JSON
tasks use data_dir, local PDF storage uses files_dir, archive tasks use
archive_dir, and split tasks use split_dir. CSV/JSON/local-PDF/split tasks
create their output directory when execution begins if permissions allow;
ArchivePdfTask requires its configured archive directory to exist.
Deployment _dir keys are the paths that ConfigManager creates at startup,
except watch_folder.dir.
The current runtime uses the llama-cloud SDK and LlamaCloud client. New code should not use the legacy llama-cloud-services / LlamaExtract agent flow. agent_id is legacy; use configuration_id for saved Extract v2 configurations or omit it to build an inline schema from fields.
After validating a saved Extract v2 configuration in the LlamaCloud UI, you can
run a one-file SDK and workflow fit check against a local PDF. Sample PDF
documents are not included in the GitHub repository; provide your own test
document or use a PDF from your existing document set. The manual tool reads a
YAML task definition; it does not read SQLite or resolve pipeline_secrets.
Export/copy the selected pipeline definition to an ignored local smoke file and
provide the API key through the current process:
$env:LLAMA_CLOUD_API_KEY = "set-locally"
$pdfPath = "C:\path\to\your\test-document.pdf"
.\.venv\Scripts\python.exe tools\llamacloud_extract_smoke.py --config smoke-pipeline.yaml --file $pdfPath --configuration-id "cfg-..."
If configuration_id is already set in the smoke definition, omit the override
flag. Do not commit the smoke definition or output because they can contain
customer/provider data.
The script writes:
raw_extract_result.json: raw result.extract_result from LlamaCloud.workflow_normalized_data.json: data after matching returned keys to workflow
fields and applying configured types.workflow_fit_report.json: missing workflow fields, extra raw keys,
validation errors, and pass/fail status.To re-check a saved raw result without another LlamaCloud call:
.\.venv\Scripts\python.exe tools\llamacloud_extract_smoke.py --config smoke-pipeline.yaml --raw-json test\data\llamacloud_smoke\raw_extract_result.json
CONFIG_PATH: Custom path to configuration fileUSE_RELOAD: Enable auto-reload for development (true/false)SQLite is the primary workflow-state store. The application records:
Workflow state is persisted in SQLite. /api/files and /api/status/{file_id} remain as legacy response shapes backed by SQLite; filesystem status files are not used. Use /app/* pages for browser workflows.
Admins can remove eligible whole-batch history through Clean up processing data on the Pipeline page. Deleted pages become reusable; immediate database file shrinkage is not promised and compaction is separate maintenance. See the pipeline retention guide for archive prerequisites, protected work, retained files, and recovery limits.
Before first login, initialize the two fixed SQLite users:
.\.venv\Scripts\python.exe tools\setup_users.py --config config.yaml
For an upgrade from YAML credentials, preserve the existing admin hash while creating the operator account:
.\.venv\Scripts\python.exe tools\setup_users.py --config config.yaml --legacy-config config.yaml
After a successful import, remove the legacy authentication block. Passwords must contain uppercase, lowercase, numeric, and symbol characters and be 12–72 UTF-8 bytes.
http://localhost:8000/app/upload and select admin or operator/app/upload, select one exact eligible published
pipeline version for the whole batch, and submit one or more PDFs/app/processing or /app/batches/{batch_id} to track queued work, splitting, extraction, review, and completion state/app/review and /app/review/{review_item_id} for human review queues/app/documents/{document_id}/extraction for extracted fields and source PDF access/app/reports and click a recent batch row to view document task timelines and task-run details/app/admin/pipeline, review forms in /app/schemas, inspect tasks and
validation, manage users, and view the admin_ audit subset/app/admin/pipeline, publish and
activate the pipeline, then bind an existing, non-overlapping incoming
folder to one exact published versionwatch_folder.dir alone is only a
required startup-compatibility path and does not assign a workflow# Run with default configuration
.\.venv\Scripts\python.exe main.py
# Use custom configuration
.\.venv\Scripts\python.exe main.py --config-path custom_config.yaml
# Run without web server (watch folder only)
.\.venv\Scripts\python.exe main.py --no-web
POST /api/login: API user authenticationPOST /api/session/refresh: Refresh the authenticated sessionPOST /login: Browser login formGET /logout: Browser session terminationGET /api/admin/users: List fixed accounts (admin only)PUT /api/admin/users/{username}/password: Change an account password (admin only)Repeated failed login attempts are temporarily throttled and may return HTTP 429 Too Many Requests.
The admin account has full access. The operator account cannot access administrative pages or APIs. Admins manage both passwords at /app/admin/users; changing a password revokes existing sessions for that account.
GET /health/live: Public web-process liveness with no operational details.GET /health/ready: Public supervised-runtime readiness (503 until ready).GET /api/admin/runtime-health: Run-scoped component and database diagnostics (admin only).POST /upload: Retired non-durable upload endpoint; returns 410 GoneGET /api/pipelines/available: List exact pipeline versions eligible for the current userPOST /api/batches/upload: Upload a batch of PDFs with a required
pipeline_version_id, create SQLite batch/document records, and enqueue
durable processing jobs; multipart file data is streamed through disk-backed
staging under configured file-count, file-size, request-size, and concurrency limitsGET /api/batches: List ingestion batchesGET /api/upload-submissions/{submission_id}: Resolve an upload receipt;
cleaned history returns status: purged and requires a deliberate new uploadGET /api/batches/{batch_id}: Get batch detailsGET /api/batches/{batch_id}/documents: List batch documentsGET /api/batches/{batch_id}/split-results: Show split source/child document relationshipsGET /api/documents/{document_id}/task-runs: List task runs for a documentGET /api/documents/{document_id}/extraction: Read extraction result and normalized fieldsGET /api/documents/{document_id}/fields: Read extracted/reviewed fieldsGET /api/documents/{document_id}/file/pdf: Stream the source PDF or registered PDF artifactPOST /api/documents/{document_id}/resume: Resume a document after reviewGET /api/files: Legacy compatibility list backed by SQLite documentsGET /api/status/{file_id}: Legacy compatibility detail backed by SQLite documents, task runs, and artifactsGET /api/review/items: List review queue itemsPOST /api/review/items/{review_item_id}/claim: Claim a review itemPOST /api/review/items/{review_item_id}/complete: Complete review and persist corrected valuesGET /api/reports/summary: Processing and review activity summaryGET /api/admin/settings, PUT /api/admin/settings: Admin configuration stateGET /api/admin/audit: Admin audit events/api/admin/pipeline-templates: Create/list named templates; per-template
endpoints manage metadata, clone, draft save/validate/import/export/diff,
immutable publish, and version historyGET /api/admin/pipeline-templates/{template_id}/archive-preview: Explain
archive impact and watch-folder blockersPOST /api/admin/pipeline-templates/{template_id}/archive: Archive an inactive
pipeline after name confirmation; definitions and history remainPOST /api/admin/pipeline-templates/{template_id}/cleanup-preview: Preview
eligible whole batches before an exclusive UTC cutoff_datePOST /api/admin/pipeline-templates/{template_id}/cleanup: Confirm a current
preview and exact pipeline name to delete eligible processing history;
request/response details/api/admin/review-schemas: Create/list review forms; per-template endpoints
manage metadata, draft save/validate/import/export, immutable publish,
versions, and dependency usage/api/admin/watch-folder-bindings: List/create bindings; per-binding
PATCH and DELETE update or remove eligible unreferenced bindingsGET /api/admin/pipeline, PUT /api/admin/pipeline/draft,
POST /api/admin/pipeline/publish, review-gate-rules, split-settings, and
filesystem /api/schemas endpoints are legacy compatibility/configuration
surfaces. New workflow authoring uses the versioned template endpoints.pdfdoc_extraction/
├── 📄 main.py # Application entry point
├── 📄 config.yaml # Ignored local deployment configuration (not committed)
├── 📄 requirements.txt # Pinned runtime Python dependencies
├── 📄 requirements-dev.txt # Runtime plus test/browser tooling
├── 📄 package.json # Production frontend asset tooling
├── 📁 modules/ # Core application modules
│ ├── api_router.py # API composition and request handling
│ ├── config_manager.py # Deployment configuration
│ ├── db/ # SQLite schema, migrations, and repositories
│ ├── services/ # Workflow, review, upload, queue, admin, and artifact use cases
│ ├── workflow_loader.py # Approved configured-task execution
│ └── workflow_manager.py # Root, split-child, and resumed flows
├── 📁 standard_step/ # Processing pipeline steps
│ ├── extraction/ # Data extraction tasks
│ │ ├── extract_pdf.py # Generic PDF extraction
│ │ ├── llama_cloud_v2.py # LlamaCloud Extract v2
│ │ ├── glm_ocr_extract.py # Local Ollama-backed GLM-OCR
│ │ └── liteparse_extract.py # Local LiteParse + Ollama extraction
│ ├── storage/ # Data storage tasks
│ ├── split/ # PDF split and fan-out tasks
│ ├── review/ # Human-review gate
│ ├── rules/ # Business rule tasks
│ ├── archiver/ # File archiving tasks
│ ├── context/ # Context management tasks
│ └── housekeeping/ # Cleanup and maintenance tasks
├── 📁 tools/ # Administrative tools and config checker
│ └── config_check/ # CLI: python -m tools.config_check
├── 📁 web/ # Web interface
│ ├── server.py # FastAPI application
│ ├── templates/ # HTML templates
│ └── static/ # CSS, JavaScript, assets
├── 📁 test/ # Unit, service, workflow, integration, security, and visual tests
├── 📁 docs/ # Architecture, operations, administration, and user guides
├── 📁 tasks/ # Task creation guidance, plans, and archived work
└── 📁 pipeline_visual_editor_prototype/ # Separate React/Vite prototype, not production UI
Runtime directories such as data/, files/, processing*/, output/,
web_upload/, and watch_folder/ hold local state or generated/customer
artifacts; they are not source folders to commit.
Start at the documentation entrance and choose your reading path:
See the product roadmap for agreed future work and the linked assessment of comparable extraction products.
Clone and install
git clone <repository-url>
cd pdfdoc_extraction
py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
Run tests
.\.venv\Scripts\python.exe -m pytest -v
Development mode
$env:USE_RELOAD="true"
.\.venv\Scripts\python.exe main.py
# Run all tests
.\.venv\Scripts\python.exe -m pytest -v
# Run specific test file
.\.venv\Scripts\python.exe -m pytest -v test/core/test_config_manager.py
# Run static type checking when Pyright is installed (it is not pinned in requirements.txt)
pyright
Example focused validation for SQLite-backed ingestion and operator state:
.\.venv\Scripts\python.exe -m pytest -v test\integration\test_sqlite_only_workflow_state.py test\integration\test_batch_upload_api.py test\integration\test_reports_api.py test\integration\test_settings_api.py
Run the full suite before handing off broad or cross-cutting changes.
The end-to-end workflow fixture config also passes config-check:
.\.venv\Scripts\python.exe -m tools.config_check validate --config test\data\config.yaml --import-checks
Application won't start
app.supervisor.log for a missing or incompatible database schemaPDF processing fails
Web interface issues
logging.log_file is the base path for role-specific logs. With the default
app.log, normal startup writes app.supervisor.log, app.web.log, and
app.worker.log; relative paths are resolved beside the active configuration
file. logging.log_level applies to all three processes.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)No repository license file is currently present. Confirm the applicable usage and distribution terms with the project owner before redistributing the code.
For support and questions:
docs/ folderBuilt with ❤️ for intelligent document processing