Repository navigation
Expand file tree
/
Copy pathpyproject.toml
More file actions
130 lines (121 loc) · 4.11 KB
/
Copy pathpyproject.toml
File metadata and controls
130 lines (121 loc) · 4.11 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
[project]
name = "openfoia"
version = "4.7.0"
description = "Local-first investigation toolkit for journalists, researchers, and citizens"
readme = "README.md"
license = "AGPL-3.0"
requires-python = ">=3.11"
dependencies = [
# Core — always needed, pure Python or lightweight
"fastapi>=0.109.0",
"uvicorn>=0.27.0",
"sqlalchemy>=2.0.0",
"alembic>=1.13.0",
"httpx>=0.26.0",
"pydantic>=2.5.0",
"pydantic-settings>=2.1.0",
"typer>=0.9.0",
"rich>=13.7.0",
"python-multipart>=0.0.6",
"jinja2>=3.1.0",
"pypdf>=3.17.0",
"python-docx>=1.1.0",
"aiofiles>=23.2.0",
]
[project.optional-dependencies]
# OCR — requires system packages: tesseract-ocr, poppler-utils
ocr = [
"pytesseract>=0.3.10",
"pdf2image>=1.16.0",
]
# Delivery gateways
fax = ["twilio>=8.10.0", "reportlab>=4.0.0"]
mail = ["lob>=4.0.0"]
# Cloud AI providers
cloud-ai = ["anthropic>=0.18.0", "openai>=1.10.0"]
# Local NER models
ner = ["gliner>=0.2.0"]
ner-spacy = ["spacy>=3.7.0"]
# Tor routing
tor = ["socksio>=1.0.0"]
# Browser automation
browser = ["playwright>=1.40.0"]
# Outlook MSG email files
email-files = ["extract-msg>=0.48.0"]
# DocumentCloud integration
documentcloud = ["documentcloud>=4.0.0"]
# Encrypted database.
# sqlcipher3-binary ships prebuilt wheels; pysqlcipher3 is unmaintained
# (2021), source-only, and no longer pip-installs on modern Python — which
# made the encryption feature effectively unreachable. Both drivers are
# supported at runtime, so an existing pysqlcipher3 install keeps working.
encryption = ["sqlcipher3-binary>=0.5.0"]
# Everything
all = [
"openfoia[ocr,fax,mail,cloud-ai,ner,tor,browser,email-files,encryption]",
]
# Development
dev = [
"pytest>=7.4.0",
"pytest-asyncio>=0.23.0",
"pytest-cov>=4.1.0",
"ruff>=0.1.0",
"mypy>=1.8.0",
# tests/test_plugin.py parses plugin frontmatter. Test-only -- keep it out
# of core deps.
"pyyaml>=6.0",
]
[project.scripts]
openfoia = "openfoia.cli:app"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
# The rule set is pinned explicitly, never inherited from ruff's defaults:
# CI installs an unpinned `ruff>=0.1.0`, so relying on defaults lets a new
# ruff release silently change what CI enforces (which is exactly how this
# repo went from green to 325 errors on unchanged code).
#
# Widen this list deliberately, and fix the findings — do not narrow it to
# make a build pass.
select = [
"E4", "E7", "E9", # pycodestyle (the historical default subset)
"F", # pyflakes
"I", # import sorting
"UP", # pyupgrade
"B", # bugbear
"SIM", # simplify
"DTZ", # naive datetimes — caught a real deadline bug
"C4", # comprehensions
"PIE",
"RUF",
]
ignore = [
# `class X(str, Enum)` -> `StrEnum` changes what `str(X.MEMBER)` returns
# ("federal" instead of "AgencyLevel.FEDERAL"). These enums are persisted
# through SQLAlchemy and serialized into API responses and exports, so
# that is a data-format change wearing a lint fix's clothing. Worth doing
# deliberately with migration checks, not as part of a lint sweep.
"UP042",
]
# Not enabled yet, tracked as follow-up:
# BLE001 (~82) — blind `except Exception`. High signal for this codebase:
# a swallowed exception is what made a failed records lookup report as a
# clean result. Fixing it needs a per-site audit of error handling, which
# is its own reviewable change rather than a bulk sweep.
# S (bandit) — mostly subprocess/randomness false positives here, plus
# S101 which is just "asserts in tests".
[tool.ruff.lint.per-file-ignores]
# FastAPI's dependency-injection idiom is `arg = Depends(...)` in the
# signature default; B008 flags every route.
"openfoia/server.py" = ["B008"]
# Typer's CLI idiom is the same: `arg: T = typer.Option(...)`.
"openfoia/cli.py" = ["B008"]
# Tests legitimately use `assert`, private access, and broad `raises`.
"tests/*" = ["S101", "SLF001"]
[tool.mypy]
python_version = "3.11"
strict = true