# 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 [docs/sdk_gen.md](docs/sdk_gen.md) for the SDK generation details and [docs/doc_gen.md](docs/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/python2/
├── 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
│   ├── _schema_bridge.py           # Generated constants (credential builders, enums)
│   ├── _registries.py              # Generated model-registry loader
│   ├── api/                        # Tier-3: hand-written convenience overrides
│   │   ├── embedders.py            #   5 override classes (embedders, llms, rerankers,
│   │   ├── llms.py                 #     spaces, memories) call apply_convenience_transforms
│   │   ├── rerankers.py            #     then super()
│   │   ├── spaces.py               #   5 thin pass-throughs (apikeys, users, ocr,
│   │   ├── memories.py             #     system, admin) — just `pass`
│   │   └── ...
│   ├── registries/                 # Declarative config (no code generation)
│   │   ├── convenience.py          #   Source of truth for transforms, param descriptions,
│   │   │                           #     defaults, maps_to/replaces semantics
│   │   ├── embedders.json          #   29 embedder models (provider, dims, modalities)
│   │   ├── llms.json               #   34 LLM models
│   │   └── rerankers.json          #   16 reranker models
│   └── _generated/                 # Auto-generated — do not edit
│       ├── models/                 #   Tier-1: pydantic v2 models (openapi-generator)
│       └── api/                    #   Tier-2: structural API bases (_sdk_gen/ output)
│           ├── embedders_base.py
│           ├── memories_base.py
│           └── ...
├── _sdk_gen/                       # Tier-2 code generator (reads OpenAPI spec → emits bases)
│   ├── emitters.py                 #   Method emitters (input×output shape composition)
│   ├── spec.py                     #   Route classification, streaming/merge configs
│   ├── bridge.py                   #   Generates _schema_bridge.py + _registries.py
│   ├── docstrings.py               #   Docstring builder from OpenAPI summaries/params
│   ├── metadata.py                 #   REST metadata extraction (paths, models, params)
│   └── validate.py                 #   9 structural validation checks
├── tests/                          # Unit + validation tests (run without server)
│   ├── test_convenience_registry.py
│   ├── test_validate.py            #   Wraps _sdk_gen/validate.py checks as pytest
│   ├── test_*.py
│   └── integration/                # Live server tests (auto-skip without env vars)
│       ├── conftest.py
│       ├── test_full_flow.py
│       └── ...
├── docs/                           # Internal dev docs
│   ├── sdk_gen.md                  #   Architecture + regeneration guide
│   ├── doc_gen.md                  #   Doc generation + docstring authoring
│   └── ...
├── _doc_gen/                       # Doc generation scripts (called via doc_gen.sh)
│   ├── generate_ref.py             #   SDK ref doc generator (griffe + convenience registry → MDX)
│   ├── generate_skill.py           #   Claude Code skill reference generator → goodmem/skills/
│   └── sync_rag_snippets.py        #   Sync examples/basic_rag.py snippets → goodmem-docs tutorial
├── examples/
│   └── basic_rag.py                # End-to-end RAG example (source for basic RAG tutorial in goodmem-docs)
├── vibe/                           # Claude Code non-interactive prompts
│   ├── audit_ref_doc.sh            #   Audit generated MDX docs for accuracy
│   ├── audit_ref_doc.md            #   Audit prompt + known issues list
│   ├── sdk2rest.sh                 #   Generate REST equivalents from SDK test snippets
│   └── sdk2rest.md                 #   SDK→REST conversion prompt
├── sdk_gen.sh                      # SDK generation: compile server → Tier-1 → Tier-2 → tests
├── doc_gen.sh                      # Doc generation: ref pages + tutorial sync + skill ref + tests
├── goodmem-reset.sh                # Delete all resources on a GoodMem server (test cleanup)
└── pyproject.toml
```

## Development commands

```bash
# SDK generation (compile server → Tier-1 models → Tier-2 bases → unit & integration tests)
./sdk_gen.sh

# Documentation generation (ref pages + basic-rag tutorial sync + skill ref + tests)
./doc_gen.sh                   # ref pages + basic-rag tutorial sync + skill ref + tests
./doc_gen.sh --ref-only        # SDK reference pages only
./doc_gen.sh --sync-only       # sync only basic-rag tutorial code snippets

# 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 `sdk_gen.sh`, integration test is only activated when environment variables `GOODMEM_BASE_URL` and `GOODMEM_API_KEY` are set.

> **Warning:** Before the integration tests, `sdk_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 [docs/sdk_gen.md](docs/sdk_gen.md) for the full regeneration workflow and [docs/doc_gen.md](docs/doc_gen.md) for the doc and auditing pipelines.



## Documentation

* [SDK generation guide](docs/sdk_gen.md) — architecture, regeneration, testing, tier details
* [Doc generation guide](docs/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/python2) — 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. 
