Ctrl K
ComunidadGuías…

CONTRIBUTING.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Contributing to py-idp

Thanks for taking an interest. The bar is intentionally low: PRs that
land cleanly get merged quickly.

## TL;DR

```bash
git clone https://github.com/rollroyces/py-idp
cd py-idp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,eval]"
pytest -v && ruff check src tests examples && mypy src/idp
```

If all three are green, push and open a PR. CI runs the same matrix
on Linux / Python 3.10 / 3.11 / 3.12.

## Project layout

```
src/idp/
  core/         # Document, PipelineResult, base protocols
  parse/        # PDF / image / text parsers + router
  classify/     # rule-first doc-type classification
  extract/      # schema-driven LLM extraction
  assess/       # heuristic + LLM confidence
  validate/     # Pydantic + user-rule validation
  hitl/         # Streamlit review UI
  pipeline/     # orchestrator
  llm/          # backends (openai, anthropic, ollama, china:*, nanonets)
  storage/      # JSON / SQLite / in-memory HITL stores
  rl/           # policy update from review feedback
  errors.py metrics.py config.py ratelimit.py api.py _logging.py
```

## Adding a new LLM backend

1. Subclass `idp.llm.backend.Backend` and implement `complete()`.
2. If the provider is OpenAI-compatible, subclass `OpenAICompatibleBackend`
   in `idp.llm.compat` — saves you 50 lines of HTTP plumbing.
3. Register the name in `get_backend()` (`idp/llm/backend.py`).
4. Add the env-var prefix to the `Settings` model in `idp.config`.
5. Tests: extend `tests/test_backends.py` with a mocked test that
   doesn't require live credentials.

## Adding a new schema

Drop a Pydantic `BaseModel` subclass in `src/idp/core/schemas.py`,
list it in `BUILTIN_SCHEMAS`, and the CLI auto-picks it up via
`idp schemas`.

## Commit messages

Use [Conventional Commits](https://www.conventionalcommits.org/):

```
feat(extract): add field-level retry budget per backend
fix(storage): skip corrupt lines instead of crashing the read
docs(readme): cross-link discover_schema_sample
perf(hitl): lazy-import streamlit to avoid 20 MB import cost
```

The first line stays under 72 chars; wrap the body at 100. CI doesn't
lint commit messages but the release tool reads them.

## Code style

- **ruff** for lint + import order (`ruff check src tests examples`).
- **mypy --strict-ish** (`mypy src/idp/`) — keep public functions typed.
- **pytest** for tests. Prefer small unit tests; one integration test
  per backend is fine if it's mocked at the HTTP boundary.
* **Hypothesis** for property tests on parsing / extraction paths.

## Stats

458 tests, 58 mypy-checked modules, ruff-clean across `src/ tests/
examples/`. Coverage is highest on the validator, parser, and store
modules (see `tests/` for per-module coverage badges in the docstrings).

## What NOT to PR

- Whitespace-only changes, mass reformatting, dependency bumps without
  a motivating issue. Open an issue first.
- New dependencies in `core` — extras only (`[docling]`, `[openai]`,
  `[anthropic]`, `[hf-vlm]`, `[api]`, `[eval]`).
- Renames of public API symbols — we are pre-1.0, but renaming
  `Document` / `Pipeline` / `Backend` would break every downstream
  user. Open an issue first.

## Releasing

Only maintainers cut releases. The flow:

```bash
git tag v0.X.Y -m "v0.X.Y — <one-line summary>"
git push --tags
gh release create v0.X.Y --notes-file CHANGELOG.md
# → .github/workflows/publish.yml picks up the tag, builds, uploads to PyPI
```

The PyPI trusted-publishing workflow is already wired up
(`.github/workflows/publish.yml`).