# pnotp

> Official Python client for P¬P: zero-retention inference for frontier models.
> One account key (`pnotp_sk_...`) calls Claude, Gemini, Gemma, DeepSeek, Kimi,
> Qwen and GLM through https://api.pnotp.ai/v1. P¬P keeps no copy of the prompt
> or the answer, and every call returns a receipt signed with Ed25519. The same
> key drives hosted agents, Laya decisions and, as an extra, training and
> deploying your own models. Full docs: https://docs.pnotp.ai

The SDK is self-documenting and the docs are offline (no key, no network). Always
prefer the in-package help over remembered signatures: it is generated by
introspection and matches the installed version exactly.

## Help (call these from Python)
- `pnotp.help()`: overview + topic list.
- `pnotp.help("<topic>")`: a topic page. Topics: overview, install, auth,
  quickstart, compliant-llm, migrating, laya, agents, brains, tools,
  neural-networks, training, deployments, inference, compliance, architectures,
  credits, errors, help.
- `pnotp.help.search("...")`: rank topics + the live API reference.
- `pnotp.help(pnotp.Client.chat)` / `pnotp.help("Client.train")`: a symbol's signature + docstring.
- `pnotp.help.errors`: the exception catalog.
- `pnotp.help.toby("...")`: ask P¬P's hosted assistant in plain English (needs
  `PNOTP_API_KEY` and a positive balance; falls back to local docs when offline,
  never raises).
- `pnotp.help.as_tool()`: a tool so a running `pnotp.Agent` can ask Toby mid-loop.

## Errors
- All exceptions subclass `pnotp.PnotpError` and carry `.help`.
- `AuthError` (bad/missing key), `InsufficientCreditsError` (402), `NotFoundError`
  (404), `TimeoutError`, `MaxStepsExceeded`, `ToolError`, `ModelEndpointError`.
- On any error: `print(pnotp.help.toby(str(err)))`.

## Quickstart
```python
import pnotp
px = pnotp.Client()                                   # PNOTP_API_KEY
out = px.chat("Summarize this clause: ...", model="gemini-3.1-flash-lite")
out["completion"], out["receipt"]                     # keep the receipt
```
- Models and prices (public): `GET https://api.pnotp.ai/v1/llm/pricing`.
- OpenAI SDK: `OpenAI(base_url="https://api.pnotp.ai/v1", api_key="pnotp_sk_...")`.
- Receipt verification: https://docs.pnotp.ai/receipts

## Neural networks (an extra)
```python
project = px.projects.create(name="X", task_type="binary_image_classification")
model = px.models.create(project["id"], name="cnn",
                         architecture=pnotp.architectures.image_classifier(num_classes=2))
px.train(model.id, dataset="train.zip", epochs=5).wait()
dep = px.deployments.upload(project["id"], name="prod", checkpoint="model.pt", compliant=True)
px.predict(dep["deployment"]["id"], "xray.jpg")
```
- `compliant=True` makes a deployed endpoint zero-retention (input never persisted,
  errors redacted, a `compliance` block per response). Raises `APIError` 409 if
  not enabled; probe with `px.deployments.compliance_available()`.

## Setup
- `pip install pnotp`
- `export PNOTP_API_KEY="pnotp_sk_..."` (mint at https://studio.pnotp.ai/api-keys)
- local backend: `export PNOTP_BASE_URL="http://localhost:8000/v1"`
- SDK agents with your own provider as the brain: also set that key, e.g.
  `export GEMINI_API_KEY="..."`
