Repository navigation
Expand file tree
/
Copy pathpyproject.toml
More file actions
186 lines (174 loc) · 6.78 KB
/
Copy pathpyproject.toml
File metadata and controls
186 lines (174 loc) · 6.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
[build-system]
requires = ["setuptools>=68", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "py-idp"
version = "0.6.2"
description = "General-purpose, AI-enabled Intelligent Document Processing framework for Python. OCR + multimodal extraction with Pydantic schemas, confidence assessment, HITL review, and a built-in eval harness. Supports OpenAI, Anthropic, Ollama, and 8 China LLMs."
readme = "README.md"
requires-python = ">=3.10"
license = "AGPL-3.0-or-later"
authors = [
{ name = "Royce", email = "roycelam@umich.edu" },
]
keywords = [
"intelligent-document-processing",
"document-ai",
"ocr",
"llm",
"extraction",
"pydantic",
"multimodal",
"rag",
"information-extraction",
"invoice",
"pdf",
"schema-discovery",
]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
dependencies = [
"pydantic>=2.5",
"typer>=0.12",
"rich>=13.7",
"httpx>=0.27",
"python-dotenv>=1.0",
"tenacity>=8.2",
"streamlit>=1.32",
"pdfplumber>=0.10", # lightweight fallback parser
"tiktoken>=0.7", # token-budget chunking (chunker.TokenChunker, extract optimizer)
# Template frontmatter is YAML, and the bundled sample templates now
# load automatically (TemplateRegistry.load_with_fallback), so a
# default install must be able to parse them. Before v0.6.2 PyYAML was
# optional and only needed by users who pointed at their own
# templates/ dir -- which meant the shipped samples raised ImportError.
"PyYAML>=6.0",
]
[project.optional-dependencies]
# PyYAML is a core dependency as of v0.6.2 (the bundled sample templates
# load by default). This extra is retained as an explicit no-op so the
# error message in idp.templates and any existing install instructions
# that say `pip install py-idp[templates]` keep working.
templates = ["PyYAML>=6.0"]
# Default parser (IBM Docling). Heavy: ~500MB model deps.
docling = ["docling>=2.0"]
# Optional OCR fallback for noisy scans
ocr = ["pytesseract>=0.3.10", "Pillow>=10.0"]
# OpenAI-compatible API (also works with Anthropic via compatible gateways)
openai = ["openai>=1.30"]
anthropic = ["anthropic>=0.27"]
ollama = ["ollama>=0.2"]
# Hugging Face vision-language models (Nanonets-OCR2-3B + Baidu Unlimited-OCR).
# Heavy: ~3 GB pip install (torch + transformers), ~7 GB model weights.
# Runs offline on MPS (Apple Silicon) or CUDA. No API key needed.
hf-vlm = [
"torch>=2.1",
"transformers>=4.45",
"accelerate>=0.34",
"safetensors>=0.4",
"Pillow>=10.0",
"huggingface-hub>=0.24",
]
# API server example (FastAPI + uvicorn)
api = ["fastapi>=0.110", "uvicorn[standard]>=0.27"]
# China LLM providers (OpenAI-compatible; no extra deps required — uses httpx)
# The `openai` SDK is optional; install it if you prefer the SDK client to raw HTTP.
china = ["openai>=1.30"]
# PDF-to-image rendering for multimodal backends (PdfPagesParser + NanonetsVLBackend).
# Pillow is used for image preprocessing; pdf2image requires poppler-utils at runtime
# (apt install poppler-utils / brew install poppler).
pdf-render = ["pdf2image>=1.16", "Pillow>=10.0"]
# Evaluation
eval = ["datasets>=2.18", "pandas>=2.1"]
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.23",
"pytest-benchmark>=4.0",
"hypothesis>=6.80",
"httpx>=0.27", # FastAPI TestClient + integration tests
"ruff>=0.3",
"mypy>=1.8",
"types-PyYAML",
"reportlab>=4.0",
]
# Building the documentation site (mkdocs-material + mkdocstrings).
# Not required for running py-idp; only for `mkdocs build` / `mkdocs serve`.
docs = [
"mkdocs>=1.6",
"mkdocs-material>=9.5",
"mkdocstrings[python]>=0.25",
"pymdown-extensions>=10.7",
]
# Running the example notebooks in examples/notebooks/. nbformat/nbconvert are
# needed for re-executing notebooks; ipykernel to register the Python kernel
# in Jupyter. pandas is used by the batch notebook's DataFrame cell.
notebooks = [
"nbformat>=5.10",
"nbconvert>=7.0",
"ipykernel>=6.0",
"pandas>=2.1",
]
[project.scripts]
idp = "idp.pipeline.cli:app"
[project.urls]
Homepage = "https://github.com/rollroyces/py-idp"
Documentation = "https://rollroyces.github.io/py-idp/"
Issues = "https://github.com/rollroyces/py-idp/issues"
Changelog = "https://github.com/rollroyces/py-idp/blob/main/CHANGELOG.md"
# README in non-English languages — PyPI only renders one README per project,
# so non-English readers land here from the project page sidebar.
"繁體中文 README" = "https://github.com/rollroyces/py-idp/blob/main/README.zh-TW.md"
"简体中文 README" = "https://github.com/rollroyces/py-idp/blob/main/README.zh-CN.md"
"PyPI setup guide" = "https://github.com/rollroyces/py-idp/blob/main/docs/PYPI_SETUP.md"
[tool.setuptools.packages.find]
where = ["src"]
# Ship the bundled sample templates inside the package so
# `pip install py-idp` actually gets them. Without this they live only
# at the repo root (outside src/) and are absent from both the wheel
# and the sdist, leaving every installed user with an empty
# TemplateRegistry. `idp.templates` resolves the packaged copies at
# `importlib.resources` when no IDP_TEMPLATE_DIR / ./templates is set.
[tool.setuptools.package-data]
"idp.templates_pkg" = ["*.md"]
[tool.setuptools]
include-package-data = true
[tool.ruff]
line-length = 100
target-version = "py310"
# Jupyter notebooks (examples/notebooks/*.ipynb) are excluded — they have
# cell-by-cell imports and execution-order quirks that don't fit ruff's
# module-level model. Use `nbqa ruff` if you want notebook linting.
extend-exclude = ["examples/notebooks/*.ipynb"]
[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "SIM"]
ignore = ["E501"]
[tool.ruff.lint.per-file-ignores]
# Typer requires typer.Option/Argument in defaults — B008 is a false positive
# for any @app.command()-decorated function.
"src/idp/pipeline/cli.py" = ["B008"]
[tool.mypy]
python_version = "3.12"
# Plain mypy caught 13 real bugs (str→float assignment, dead string-passing
# code, None-attr crash, SqlStorage/Protocol signature mismatch). These extra
# flags add the highest-value checks WITHOUT the annotation churn that
# --strict would force on Typer CLI commands and Streamlit glue code:
no_implicit_optional = true
warn_unreachable = true
warn_redundant_casts = true
check_untyped_defs = true
# Optional deps (anthropic, docling, pytesseract) are imported lazily.
ignore_missing_imports = true
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
addopts = "-v --tb=short"
markers = [
"slow: marks tests as slow (real-network / real-LLM); skipped by default with `-m 'not slow'`",
]