pyproject.toml
Rama main · réplica de lectura del repositorio original.
[project]
name = "lectio"
version = "0.1.0"
description = "Browser-based RSS and Atom reader"
readme = "README.md"
requires-python = ">=3.15"
dependencies = [
"aiosqlite",
"fastapi",
"feedparser>=6.0.14",
"httpx",
"pillow>=12.3.0",
"smartcrop>=0.5",
"itsdangerous",
"jinja2",
"python-multipart",
"reader>=3.27",
"beautifulsoup4",
"readability-lxml",
"sqlalchemy",
"resend",
"uvicorn[standard]",
"markdown>=3.10.2",
"pysocks>=1.7.1",
# httpx's own SOCKS proxy support needs socksio specifically — pysocks
# above is a separate library that only requests/reader's session knows
# how to use, not something httpx's proxy= kwarg can consume.
"socksio>=1.0.0",
]
[project.optional-dependencies]
# Tooling-only: drives scripts/refresh_screenshots.py. Not needed at runtime.
# Install with `uv sync --extra screenshots && uv run playwright install chromium`.
screenshots = [
"playwright>=1.44",
]
[dependency-groups]
dev = [
"pytest>=8.4.0",
"ruff",
"ty",
"uv",
"uvicorn[standard]>=0.44.0",
# starlette's TestClient prefers httpx2; without it the suite emits a
# StarletteDeprecationWarning. Test-only — production code still uses httpx.
"httpx2",
# Drives the browser verification of UI work (launch the app, click through
# it, assert on the real DOM). Also in the `screenshots` extra, which exists
# as a no-dev install path — but a plain `uv sync` prunes anything outside
# the default groups, so leaving it only there silently removed the tooling
# mid-session. The wheel alone is cheap; browsers are a separate
# `playwright install chromium` and are NOT fetched by syncing.
"playwright>=1.44",
]
[tool.ruff]
line-length = 140
[tool.ruff.lint]
extend-ignore = ["E203"]
select = ["E", "F", "W", "I", "B"]
[tool.ruff.lint.per-file-ignores]
# main.py registers a feedparser date handler *before* its remaining imports, so
# the handler is in place before `reader` (which imports feedparser) parses
# anything. The late import block is that deliberate ordering, not drift — E402
# flags all 55 of them and none will ever be "fixed", so the rule is noise here
# and would block every change that adds an import.
#
# B008 flags FastAPI's `Query(...)`/`File(...)`/`Form(...)` route defaults as
# "function call in argument default" — that's the framework's required idiom
# (FastAPI inspects the default at import time to build request parsing), not
# a mutable-default bug, so the rule is a false positive here specifically.
"main.py" = ["E402", "B008"]
# Extracted route modules (Plan.md's main.py/index.html breakup) hit the same
# FastAPI-default false positive as main.py above, for routes that took a
# File(...)/Form(...)/Query(...) default with them when they moved out.
"routes/*.py" = ["B008"]
# Ruff is the canonical linter/formatter for this project. The `select` list
# enables pycodestyle (`E`), pyflakes (`F`), warnings (`W`), isort-style
# import ordering (`I`) and bugbear (`B`). Add or remove checks here if
# you want stricter or looser linting.