Metadata-Version: 2.4
Name: goodmem
Version: 0.1.7
Summary: GoodMem's Convenient SDK for Python
Author-email: Forrest Bao <forrest@pairsys.ai>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/PAIR-Systems-Inc/goodmem
Project-URL: Repository, https://github.com/PAIR-Systems-Inc/goodmem
Project-URL: Documentation, https://docs.goodmem.ai
Keywords: goodmem,memory,vector,embeddings,RAG,AI,Agents,LLMs,Rerankers,Embedders
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
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: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2
Requires-Dist: python-dateutil>=2.8.2
Requires-Dist: typing-extensions>=4.7.1
Provides-Extra: dev
Requires-Dist: pytest>=7.2.1; extra == "dev"
Requires-Dist: pytest-cov>=2.8.1; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: mypy>=1.5; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: griffe>=1.0; extra == "dev"
Requires-Dist: fpdf2>=2.7; extra == "dev"

# GoodMem Python SDK

A Python SDK designed to be easy to use and easy to maintain. OpenAI-style API 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.

## Installation

```bash
pip install goodmem
```

## Usage

```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}")
```

## 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
```

For architecture details, see [docs/sdk_gen.md](docs/sdk_gen.md).

## Development commands

```bash
# SDK generation (compile server → Tier-1 models → Tier-2 bases → tests)
./sdk_gen.sh
./sdk_gen.sh --check           # drift detection only (no file changes)

# Documentation generation (doc_gen.sh runs all three + validation)
./doc_gen.sh                   # ref pages + tutorial sync + skill ref + tests
./doc_gen.sh --ref-only        # SDK reference pages only
./doc_gen.sh --sync-only       # tutorial snippet sync only

# 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

# Reset live test server (deletes ALL resources — never use on production)
./goodmem-reset.sh             # interactive (prompts for confirmation)
./goodmem-reset.sh -y          # unattended (CI, scripts)

# Tests
python -m pytest tests/ -v     # unit + validation (integration auto-skips without server)
```

> **Warning:** When `GOODMEM_BASE_URL` is set, `sdk_gen.sh`, `vibe/sdk2rest.sh`, and CI all run `goodmem-reset.sh` which **deletes ALL resources** on the target server before integration tests. Never point `GOODMEM_BASE_URL` at a production server.

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.

## Claude Code integration

The SDK ships with a [Claude Code skill](https://code.claude.com/docs/en/skills) so Claude can operate GoodMem on your behalf via natural language.

```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.

## 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 CI/CD pipeline to publish to PyPI. Integrate into ../build_all.sh and build_client.sh.
2. Add CI/CD pipeline to trigger SDK regeneration when server's OpenAPI spec changes.
3. How do we integrate the CI/CD for python2/ SDK with the pan-language SDK build system? `build_all.sh` and `build_client.sh`.
4. Add `gemini-embedding-001` to embedder registry once backend adds `OPENAI_COMPATIBLE` to `ProviderType`.
5. Add Anthropic, Google, Cohere, and Mistral LLMs to registry once backend adds matching `LLMProviderType` values.
6. ~~Support `GET /v1/memories/{id}/pages` and `GET /v1/memories/{id}/pages/{pageIndex}/image` endpoints.~~ Done — paginator emitter now handles non-list paginators with standard `path_query` input.
