# `mgf-http` — typed async HTTP client for mgf-common consumers

[![Registry](https://img.shields.io/badge/registry-Codeberg-blue)](https://codeberg.org/magogi-admin/mgf-http)
[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://codeberg.org/magogi-admin/mgf-http)

> **Shape:** Federation sibling of `mgf-common`. The current
> `mgf-common` pin window is shown in this package's
> [Codeberg registry](https://codeberg.org/magogi-admin/mgf-http) — sourced
> from `pyproject.toml` at release time, so this README can't go
> stale. (Per v2.6 DOC-01 / project-shape taxonomy. PAPER-38.)
>
> **Sibling of [`mgf-common`](https://codeberg.org/magogi-admin/mgf-common)
> under the `mgf.*` namespace.** Houses the typed httpx wrapper that
> previously lived under `mgf.common.http.*` — extracted at
> mgf-common v0.29 / mgf-http v0.1 per the
> [federation split plan](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/docs/release/federation_roadmap.md).

## What this provides

| Submodule | What |
|---|---|
| `mgf.http` | `AsyncHttpClient` — thin wrapper over `httpx.AsyncClient` with retries, timeouts, header redaction, OTel-aware logging, typed error translation. `RetryPolicy` — exponential backoff with jitter; per-request override. |
| `mgf.http.exceptions` | `HttpTransportError(OperationError)` — transport-layer failure (timeout, connect-refused, network unreachable). Renamed from `HttpClientError` at the v0.29 cutover to disambiguate from `mgf.common.exceptions.HttpClientError` (the HTTP-01 4xx-class hierarchy parent, which stays in mgf-common). |

## Install

```bash
pip install mgf-http
# Or with the test extra (respx for mocking httpx in your tests):
pip install 'mgf-http[test]'
```

Pulls in `mgf-common` and `httpx` automatically.

## Quick start

```python
import asyncio
from mgf.http import AsyncHttpClient, RetryPolicy

async def main() -> None:
    async with AsyncHttpClient(
        base_url="https://api.example.com",
        timeout=10.0,
        retry=RetryPolicy(max_attempts=3),
    ) as http:
        response = await http.get("/users", params={"page": 1})
        response.raise_for_status()
        users = response.json()

asyncio.run(main())
```

The client auto-derives a User-Agent of the shape
`<app>/<ver> mgf-http/<libver>` from `mgf.common.app_name()` /
`mgf.common.app_version()` (call `mgf.common.bootstrap()` at startup
for accurate identity). Authorization / Cookie / X-Api-Key family
headers are redacted in logs and OTel spans automatically.

## Documentation

- [`docs/recipes/http.md`](docs/recipes/http.md) — full HTTP-client walkthrough.
- [`docs/cutover/v0.1.0.md`](docs/cutover/v0.1.0.md) — maiden voyage migration story (the v0.29 split, including the `HttpClientError` → `HttpTransportError` rename).
- [`PUBLIC_API.md`](PUBLIC_API.md) — full public surface contract.
- [`CHANGELOG.md`](CHANGELOG.md) — release history.

For the federation-wide engineering standards (DESIGN_PRINCIPLES,
ERROR_HANDLING, SECURITY, etc.) see
[`mgf-standard/docs/standards/`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/).
This sibling inherits them by reference; the standards
source-of-truth lives in mgf-common.

> **Conformance: L2** per [`mgf-standard/docs/standards/`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/). Per-rule audit ledger: [`docs/inprogress/MGF_STANDARDS_CONFORMANCE.md`](docs/inprogress/MGF_STANDARDS_CONFORMANCE.md). L2 means every federation **MUST** rule applies, evidenced by the tracker.

## Status

🚧 **Experimental** — every public name is `experimental` per AP-09.
Promotion to `stable` happens release-by-release as consumer feedback
in [`mgf-common/FEEDBACK.md`](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/FEEDBACK.md)
converges. The 0.x window applies. Pin tightly:
`mgf-http = ">=0.X.0,<0.Y"`.

## Cross-references

- **Filing process for sharp edges**: open an entry on
  [`mgf-common/FEEDBACK.md`](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/FEEDBACK.md)
  with `[mgf-http]` prefix, OR file directly on this repo's Issues →
  maintainer mirrors into the canonical FEEDBACK.md.
- **Federation pattern**:
  [`mgf-common/docs/design/federation.md`](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/docs/design/federation.md).
- **The split that created this sibling**:
  [`mgf-common/docs/release/federation_roadmap.md`](https://codeberg.org/magogi-admin/mgf-common/src/branch/main/docs/release/federation_roadmap.md).
