# GoodMem Python SDK

An OpenAI-style API for Goodmem with auto-inference of model parameters, streaming retrieval, async support, and auto-pagination. The SDK stays in sync with the server's OpenAPI spec — except for hand-written convenience methods (model registry auto-inference, flat post-processor kwargs, etc.) that wrap the generated layer. Please see [../notes/client_gen.md](../notes/client_gen.md) for the SDK generation details and [../notes/doc_gen.md](../notes/doc_gen.md) for the doc generation details.

## Installation

```bash
pip install goodmem
```

## Usage

### The programmatic way

```python
from goodmem import Goodmem

client = Goodmem(
    base_url="http://localhost:8080",
    api_key="gm_..."
)

embedder = client.embedders.create(
    display_name="OpenAI Embedder",
    model_identifier="text-embedding-3-large",
    api_key="sk-your-openai-key",
)

print(f"Created: {embedder.embedder_id}")
```
### The Skill way 

```bash
# One-time setup — copy the skill into your Claude Code skills directory
cp -r $(python -c "import goodmem; print(goodmem.__path__[0])")/skills ~/.claude/skills/goodmem
```

Once installed, Claude Code automatically loads the GoodMem SDK reference when you ask it to create embedders, store memories, run retrieval, etc.

## Project structure

```
clients/v2/python/
├── goodmem/                        # Installable package
│   ├── client.py                   # Goodmem / AsyncGoodmem entry points
│   ├── errors.py                   # Typed exception hierarchy (APIError, NotFoundError, …)
│   ├── pagination.py               # Paginator / AsyncPaginator (auto next_token)
│   ├── streaming.py                # RetrieveMemoryStream (SSE → typed events)
│   ├── _base.py                    # CRUDNamespace / AsyncCRUDNamespace base classes
│   ├── _transforms.py              # Loads convenience.json, implements 7 transform primitives
│   ├── _overrides.py               # Complex domain logic (file upload, post-processor bypass)
│   ├── _schema_bridge.py           # [AUTO-GENERATED] Credential helpers, enum values
│   ├── _registries.py              # Model-registry loader
│   ├── convenience.json            # [edit] Declarative transforms — source of truth
│   ├── api/                        # Tier-3: convenience overrides
│   │   ├── embedders.py            #   5 override classes call apply_convenience_transforms
│   │   ├── llms.py                 #     then super()
│   │   ├── rerankers.py
│   │   ├── spaces.py               #   5 thin pass-throughs (apikeys, users, ocr,
│   │   ├── memories.py             #     system, admin) — just `pass`
│   │   └── ...
│   ├── registries/                 # Model data (no code generation)
│   │   ├── embedders.json          #   29 embedder models (provider, dims, modalities)
│   │   ├── llms.json               #   34 LLM models
│   │   └── rerankers.json          #   16 reranker models
│   ├── skills/                     # Claude Code skill (also distributed via PyPI)
│   ├── models/                     # [Tier 1] [AUTO-GENERATED] ~99 pydantic v2 models
│   ├── _api_base/                  # [Tier 2] [AUTO-GENERATED] Structural API base classes
│   └── api_ir.json                 # [AUTO-GENERATED] Universal API IR
├── tests/                          # Unit + validation tests (run without server)
│   ├── test_validate.py            #   Wraps _client_gen/validate.py checks as pytest
│   ├── test_*.py
│   └── integration/                # Live server tests (auto-skip without env vars)
├── examples/
│   └── basic_rag.py                # End-to-end RAG example
├── vibe/                           # Claude Code non-interactive prompts
│   ├── audit_ref_doc.sh            #   Audit generated MDX docs for accuracy
│   └── sdk2rest.sh                 #   Generate REST equivalents from SDK test snippets
├── release.sh                      # Build + publish to PyPI
├── goodmem-reset.sh                # Delete all resources on a GoodMem server (test cleanup)
└── pyproject.toml
```

Shared infrastructure lives at `clients/v2/` level (not inside `python/`):
- `_client_gen/` — code generation (spec parsing, emitters, MCP emitter, validation)
- `_doc_gen/` — doc generation (ref pages, skills, snippet sync)
- `agents/` — Claude Code plugin (git subtree → public repo)
- `notes/` — internal dev notes

## Development commands

```bash
# Generation (run from clients/v2/, not python/)
cd ..
./client_gen.sh                # compile server → IR → Python SDK → MCP → test
./doc_gen.sh                   # ref pages + skills + snippets

# Publishing (run from python/)
cd python
./release.sh build             # Build wheel + sdist
./release.sh publish           # Publish to PyPI

# Vibe auditing (Claude Code non-interactive)
./vibe/audit_ref_doc.sh        # audit generated MDX docs for accuracy
./vibe/sdk2rest.sh             # generate REST equivalents from SDK test snippets
```
In `client_gen.sh`, integration test is only activated when environment variables `GOODMEM_BASE_URL` and `GOODMEM_API_KEY` are set.

> **Warning:** Before the integration tests, `client_gen.sh`, `vibe/sdk2rest.sh`, and CI all run `goodmem-reset.sh` to **delete ALL resources** on the target server. Never point `GOODMEM_BASE_URL` at a production server. We have a dedicated test server on Fly.io for this purpose. See [ci/README.md](ci/README.md) for more details.

See [notes/client_gen.md](notes/client_gen.md) for the full regeneration workflow and [notes/doc_gen.md](notes/doc_gen.md) for the doc and auditing pipelines.



## Documentation

* [Code generation guide](../notes/client_gen.md) — architecture, regeneration, testing, tier details
* [Doc generation guide](../notes/doc_gen.md) — how ref docs are generated, docstring authoring
* [CI pipeline](../ci/README.md) — GitHub Actions workflow, secrets, Fly.io test server setup
* [API reference](https://docs.goodmem.ai/docs/reference/sdk/python) — published SDK docs

## TODO

1. Add `gemini-embedding-001` to embedder registry once backend adds `OPENAI_COMPATIBLE` to `ProviderType`.
2. Add Anthropic, Google, Cohere, and Mistral LLMs to registry once backend adds matching `LLMProviderType` values.
3. Automate model registry updates to add new models as they are released.
4. Generate SDK to an intermediate representation, then map that to cURL, HTTPie, HTTPX, Go, JavaScript, etc. 
