Metadata-Version: 2.4
Name: fixyourdocs
Version: 0.1.0
Summary: Reference Python SDK for the Docs Feedback Protocol
Project-URL: Homepage, https://docsfeedback.org
Project-URL: Repository, https://github.com/fixyourdocs/sdk-python
Project-URL: Specification, https://github.com/fixyourdocs/protocol
Author-email: FixYourDocs <hello@fixyourdocs.org>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agents,ai,docs,documentation,feedback,protocol
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Documentation
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.27
Requires-Dist: pydantic<3,>=2.6
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# fixyourdocs (Python SDK)

Reference Python SDK for the [Docs Feedback Protocol](https://github.com/fixyourdocs/protocol)
v0. The protocol lets AI agents file structured reports against
documentation pages when the docs break agent task flows.

- Spec: <https://docsfeedback.org>.
- Why this exists: [the FixYourDocs manifesto](https://github.com/fixyourdocs/manifesto/blob/main/MANIFESTO.md).

## Install

```sh
pip install fixyourdocs
```

Requires Python 3.9+.

## Usage (sync)

```python
from fixyourdocs import Client, Report

report = Report.create(
    doc_url="https://docs.example.com/getting-started",
    summary="The page does not document how to set the API_KEY env var.",
    kind="missing",
    agent_name="claude-code",
)

with Client(api_url="https://hub.fixyourdocs.io") as client:
    result = client.send(report)

print(result.id, result.is_duplicate)
```

## Usage (async)

```python
import asyncio
from fixyourdocs import AsyncClient, Report

async def main() -> None:
    report = Report.create(
        doc_url="https://docs.example.com/getting-started",
        summary="The page does not document how to set the API_KEY env var.",
        kind="missing",
        agent_name="claude-code",
    )
    async with AsyncClient(api_url="https://hub.fixyourdocs.io") as client:
        result = await client.send(report)
    print(result.id, result.is_duplicate)

asyncio.run(main())
```

## API shape

The wire format is a nested object (`agent`, `report`, `task_context`),
so the SDK exposes two ways to build a `Report`:

- **`Report.create(...)`** — ergonomic, flat keyword-argument
  constructor for the common case. Internally builds the nested
  wire-format structure.
- **`Report(agent=AgentInfo(...), report=ReportBody(...), ...)`** — the
  typed nested form, useful when constructing reports programmatically
  from already-typed sub-objects.

Both produce identical wire output.

## Errors

Non-2xx responses raise typed exceptions:

| Status | Exception |
|---|---|
| 400 | `ValidationError` (`.details`) |
| 401 | `AuthError` |
| 404 | `NotFoundError` |
| 410 | `OptedOutError` (`.since`) |
| 413 | `PayloadTooLargeError` (`.max_bytes`) |
| 415 | `UnsupportedMediaTypeError` |
| 422 | `PolicyRejectedError` (`.reason`) |
| 429 | `RateLimitedError` (`.retry_after`) |
| 5xx | `ServerError` (after one automatic retry on 502/503/504) |

All inherit from `FixYourDocsError`.

## Licence

Apache License 2.0 — see [LICENSE](LICENSE).

## Contributing

Contributions require a DCO sign-off and a signed Apache Individual
Contributor License Agreement — see [CONTRIBUTING.md](CONTRIBUTING.md).
