# depwhy Documentation

`depwhy` explains Python dependency conflicts in plain English and suggests ranked fixes.

## Contents

- [README](../README.md) — installation, CLI usage, library API, and example output
- [CONTRIBUTING](../CONTRIBUTING.md) — development setup and contribution guidelines
- [CHANGELOG](../CHANGELOG.md) — version history

## Quick Links

- **Install**: `pip install depwhy`
- **Source**: https://github.com/terrymccann/depwhy
- **Issues**: https://github.com/terrymccann/depwhy/issues
- **PyPI**: https://pypi.org/project/depwhy/

## API Reference

The public library API exports four types and one function:

```python
from depwhy import analyze, ConflictReport, Conflict, FixCandidate, Constraint
```

### `analyze(source, *, python_version, platform, offline, cache_ttl_hours, max_concurrency) -> ConflictReport`

Analyzes a set of Python requirements for dependency conflicts. Always returns a
`ConflictReport` — never raises for logical conflicts. See the [README](../README.md)
for full usage examples.

### `ConflictReport`

```python
@dataclass(frozen=True)
class ConflictReport:
    has_conflicts: bool
    conflicts: list[Conflict]
    warnings: list[str]       # Narrowed-but-valid ranges; not hard failures
    analyzed_packages: int    # Total packages examined
```

### `Conflict`

```python
@dataclass(frozen=True)
class Conflict:
    package: str                        # The package that cannot be resolved
    problem: str                        # Plain-English one-liner
    constraints: list[Constraint]
    solution: FixCandidate              # Top recommended fix
    alternative: FixCandidate | None    # Second-best fix
```

### `FixCandidate`

```python
@dataclass(frozen=True)
class FixCandidate:
    description: str      # Human-readable explanation of the fix
    pip_command: str      # Copy-pasteable pip install command
    is_alternative: bool  # False = recommended fix; True = fallback
```

### `Constraint`

```python
@dataclass(frozen=True)
class Constraint:
    package: str       # e.g. "urllib3"
    specifier: str     # e.g. ">=1.21.1,<1.27"
    required_by: str   # e.g. "requests==2.28.0"
    chain: list[str]   # Full dependency chain from root to this constraint
```
