GoodMem
ReferenceClient SDKsPython SDK

Python SDK

Python client SDK for GoodMem with PyPI support and streaming capabilities

PyPI version

Python client for GoodMem - a vector-based memory storage and retrieval service. Provides APIs for creating memory spaces, storing memories with vector embeddings, and performing semantic search with streaming retrieval. Supports multiple embedding providers and advanced metadata handling.

This Python package is automatically generated by the OpenAPI Generator project:

  • API version: v1
  • Package version: 1.5.10
  • Generator version: 7.13.0
  • Build package: org.openapitools.codegen.languages.PythonClientCodegen For more information, please visit https://goodmem.io/support

Server Compatibility

This client version is generated with GoodMem server v1.0.224.

Requirements.

Python 3.9+

Installation & Usage

pip install

You can install the package directly from PyPI:

pip install goodmem-client

If you prefer uv:

uv pip install goodmem-client

Then import the package:

import goodmem_client

Setuptools

Install via Setuptools.

python setup.py install --user

(or sudo python setup.py install to install the package for all users)

Then import the package:

import goodmem_client

Tests

Execute pytest to run the tests.

Getting Started

Please follow the installation procedure and then run the following:


## Import required modules
from goodmem_client.api import APIKeysApi, SpacesApi
from goodmem_client.configuration import Configuration
from goodmem_client.api_client import ApiClient
from goodmem_client.models import CreateApiKeyRequest
from goodmem_client.streaming import MemoryStreamClient
from goodmem_client.rest import ApiException
from pprint import pprint

## Configure the API client
configuration = Configuration()
configuration.host = "http://localhost:8080"  # Use your server URL

## Set authentication
configuration.api_key = {"ApiKeyAuth": "your-api-key"}

## Create API client
api_client = ApiClient(configuration=configuration)  # Your API key here

## Create an instance of the API class
api_instance = APIKeysApi(api_client=api_client)

## Prepare a create request with labels
create_request = CreateApiKeyRequest(
    labels={
        "environment": "development",
        "service": "chat-ui"
    }
)

try:
    # Create a new API key
    api_response = api_instance.create_api_key(create_api_key_request=create_request)
    print("API Key created successfully:")
    print(f"API Key ID: {api_response.api_key_metadata.api_key_id}")
    print(f"Raw API Key: {api_response.raw_api_key}")
except ApiException as e:
    print(f"Exception when calling APIKeysApi->create_api_key: {e}")

Streaming Memory Retrieval

For memory retrieval operations, use the streaming client which is the primary way to search and retrieve memories:

from goodmem_client.api import SpacesApi
from goodmem_client.streaming import MemoryStreamClient
from goodmem_client.configuration import Configuration
from goodmem_client.api_client import ApiClient

## Configure client
configuration = Configuration()
configuration.host = "http://localhost:8080"
configuration.api_key = {"ApiKeyAuth": "your-api-key"}

api_client = ApiClient(configuration=configuration)

## Create streaming client
spaces_api = SpacesApi(api_client=api_client)
stream_client = MemoryStreamClient(api_client)

## Get space ID (first available space)
spaces = spaces_api.list_spaces()
space_id = spaces.spaces[0].space_id if spaces.spaces else None

## Stream memory retrieval using advanced POST endpoint with custom post-processor
for event in stream_client.retrieve_memory_stream(
    message="your search query",
    space_ids=[space_id] if space_id else None,
    requested_size=5,
    fetch_memory=True,
    fetch_memory_content=False,
    format="ndjson",
    post_processor_name="com.goodmem.retrieval.postprocess.ChatPostProcessorFactory",
    post_processor_config={
        "llm_id": "your-llm-uuid",
        "reranker_id": "your-reranker-uuid",
        "relevance_threshold": 0.5,
        "max_results": 10
    }
):
    if event.abstract_reply:
        print(f"Abstract: {event.abstract_reply.text}")
    elif event.retrieved_item and event.retrieved_item.memory:
        memory = event.retrieved_item.memory
        print(f"Memory: {memory.get('memoryId')}")
        if 'metadata' in memory:
            print(f"Metadata: {memory['metadata']}")

## Alternative: Use convenience method for ChatPostProcessor with simple parameters
for event in stream_client.retrieve_memory_stream_chat(
    message="your search query",
    space_ids=[space_id] if space_id else None,
    requested_size=5,
    fetch_memory=True,
    format="ndjson",
    pp_llm_id="your-llm-uuid",
    pp_reranker_id="your-reranker-uuid",
    pp_relevance_threshold=0.5,
    pp_max_results=10
):
    if event.abstract_reply:
        print(f"Abstract: {event.abstract_reply.text}")

For comprehensive examples, see the samples directory:

  • apikey_sample.py - API key CRUD operations
  • streaming_sample.py - Memory retrieval with streaming
  • reproduce_issue_71.py - Memory creation with metadata

Using Filter Expressions

Filter expressions allow you to pre-filter memories based on metadata before semantic search. This enables more precise retrieval by combining metadata filtering with vector similarity.

from goodmem_client.streaming import MemoryStreamClient
from goodmem_client.models.space_key import SpaceKey
from goodmem_client.configuration import Configuration
from goodmem_client.api_client import ApiClient

## Configure client
configuration = Configuration()
configuration.host = "http://localhost:8080"
configuration.api_key = {"ApiKeyAuth": "your-api-key"}

api_client = ApiClient(configuration=configuration)
stream_client = MemoryStreamClient(api_client)

## Example 1: Filter by category
space_key = SpaceKey(
    space_id="your-space-id",
    filter="CAST(val('$.category') AS TEXT) = 'technology'"
)

for event in stream_client.retrieve_memory_stream(
    message="artificial intelligence",
    space_keys=[space_key],
    requested_size=5
):
    if event.retrieved_item and event.retrieved_item.chunk:
        chunk = event.retrieved_item.chunk
        print(f"Chunk: {chunk.chunk.get('chunkText', '')[:100]}...")

## Example 2: Filter by time range
space_key = SpaceKey(
    space_id="your-space-id",
    filter="CAST(val('$.created_at') AS TEXT) >= '2025-01-01T00:00:00Z'"
)

for event in stream_client.retrieve_memory_stream(
    message="recent developments",
    space_keys=[space_key],
    requested_size=5
):
    if event.retrieved_item and event.retrieved_item.chunk:
        chunk = event.retrieved_item.chunk
        print(f"Relevance: {chunk.relevance_score:.4f}")
        print(f"Text: {chunk.chunk.get('chunkText', '')[:80]}...")

## Example 3: Complex filter with multiple conditions
space_key = SpaceKey(
    space_id="your-space-id",
    filter="""
        CAST(val('$.priority') AS TEXT) = 'high'
        AND CAST(val('$.status') AS TEXT) = 'active'
        AND CAST(val('$.score') AS INTEGER) >= 80
    """
)

for event in stream_client.retrieve_memory_stream(
    message="important tasks",
    space_keys=[space_key],
    requested_size=10
):
    if event.retrieved_item and event.retrieved_item.chunk:
        print(f"Found matching chunk")

## Example 4: Different filters for different spaces
space_keys = [
    SpaceKey(
        space_id="space-1-id",
        filter="CAST(val('$.category') AS TEXT) = 'research'"
    ),
    SpaceKey(
        space_id="space-2-id",
        filter="CAST(val('$.category') AS TEXT) = 'documentation'"
    )
]

for event in stream_client.retrieve_memory_stream(
    message="machine learning concepts",
    space_keys=space_keys,
    requested_size=10
):
    if event.memory_definition:
        space_id = event.memory_definition.get('spaceId')
        metadata = event.memory_definition.get('metadata', {})
        print(f"Memory from space: {space_id}, category: {metadata.get('category')}")

## Example 5: Mix filtered and unfiltered spaces
space_keys = [
    SpaceKey(
        space_id="space-1-id",
        filter="CAST(val('$.source') AS TEXT) = 'trusted_source'"
    ),
    SpaceKey(
        space_id="space-2-id"  # No filter - all memories from this space
    )
]

for event in stream_client.retrieve_memory_stream(
    message="information query",
    space_keys=space_keys,
    requested_size=10
):
    if event.retrieved_item and event.retrieved_item.chunk:
        print(f"Relevance: {event.retrieved_item.chunk.relevance_score:.4f}")

Filter Expression Syntax:

  • Extract field: val('$.field_name')
  • Extract array: vals('$.array_field[*]')
  • Check field exists: exists('$.field_name')
  • String comparison: CAST(val('$.category') AS TEXT) = 'technology'
  • Numeric comparison: CAST(val('$.score') AS INTEGER) >= 80
  • Date comparison: CAST(val('$.created_at') AS DATE) >= CAST('2025-01-01' AS DATE)
  • String pattern: CAST(val('$.title') AS TEXT) LIKE '%AI%'
  • Case-insensitive pattern: CAST(val('$.title') AS TEXT) ILIKE '%ai%'
  • Array membership: 'tag1' IN vals('$.tags')
  • Multiple conditions: Use AND, OR, NOT operators

For more details on filter expressions, see the GoodMem filter documentation.

Documentation for API Endpoints

All URIs are relative to http://localhost:8080

ClassMethodHTTP requestDescription
APIKeysApicreate_api_keyPOST /v1/apikeysCreate a new API key
APIKeysApidelete_api_keyDELETE /v1/apikeys/{id}Delete an API key
APIKeysApilist_api_keysGET /v1/apikeysList API keys
APIKeysApiupdate_api_keyPUT /v1/apikeys/{id}Update an API key
AdministrationApidrain_serverPOST /v1/admin:drainRequest the server to enter drain mode
AdministrationApipurge_background_jobsPOST /v1/admin/background-jobs:purgePurge completed background jobs
AdministrationApireload_licensePOST /v1/admin/license:reloadReload the active license from disk
EmbeddersApicreate_embedderPOST /v1/embeddersCreate a new embedder
EmbeddersApidelete_embedderDELETE /v1/embedders/{id}Delete an embedder
EmbeddersApiget_embedderGET /v1/embedders/{id}Get an embedder by ID
EmbeddersApilist_embeddersGET /v1/embeddersList embedders
EmbeddersApiupdate_embedderPUT /v1/embedders/{id}Update an embedder
LLMsApicreate_llmPOST /v1/llmsCreate a new LLM
LLMsApidelete_llmDELETE /v1/llms/{id}Delete an LLM
LLMsApiget_llmGET /v1/llms/{id}Get an LLM by ID
LLMsApilist_llmsGET /v1/llmsList LLMs
LLMsApiupdate_llmPUT /v1/llms/{id}Update an LLM
MemoriesApibatch_create_memoryPOST /v1/memories:batchCreateCreate multiple memories in a batch
MemoriesApibatch_delete_memoryPOST /v1/memories:batchDeleteDelete multiple memories by ID
MemoriesApibatch_get_memoryPOST /v1/memories:batchGetGet multiple memories by ID
MemoriesApicreate_memoryPOST /v1/memoriesCreate a new memory
MemoriesApidelete_memoryDELETE /v1/memories/{id}Delete a memory
MemoriesApiget_memoryGET /v1/memories/{id}Get a memory by ID
MemoriesApiget_memory_contentGET /v1/memories/{id}/contentDownload memory content
MemoriesApilist_memoriesGET /v1/spaces/{spaceId}/memoriesList memories in a space
MemoriesApiretrieve_memoryGET /v1/memories:retrieveStream semantic memory retrieval
MemoriesApiretrieve_memory_advancedPOST /v1/memories:retrieveAdvanced semantic memory retrieval with JSON
OCRApiocr_documentPOST /v1/ocr:documentRun OCR on a document or image
RerankersApicreate_rerankerPOST /v1/rerankersCreate a new reranker
RerankersApidelete_rerankerDELETE /v1/rerankers/{id}Delete a reranker
RerankersApiget_rerankerGET /v1/rerankers/{id}Get a reranker by ID
RerankersApilist_rerankersGET /v1/rerankersList rerankers
RerankersApiupdate_rerankerPUT /v1/rerankers/{id}Update a reranker
SpacesApicreate_spacePOST /v1/spacesCreate a new Space
SpacesApidelete_spaceDELETE /v1/spaces/{id}Delete a space
SpacesApiget_spaceGET /v1/spaces/{id}Get a space by ID
SpacesApilist_spacesGET /v1/spacesList spaces
SpacesApiupdate_spacePUT /v1/spaces/{id}Update a space
SystemApiget_system_infoGET /v1/system/infoRetrieve server build metadata
SystemApiinitialize_systemPOST /v1/system/initInitialize the system
UsersApiget_current_userGET /v1/users/meGet current user profile
UsersApiget_userGET /v1/users/{id}Get a user by ID
UsersApiget_user_by_emailGET /v1/users/email/{email}Get user by email address

Documentation For Authorization

Authentication schemes defined for the API:

BearerAuth

  • Type: Bearer authentication

ApiKeyAuth

  • Type: API key
  • API key parameter name: x-api-key
  • Location: HTTP header

Contact & Support

For questions or issues with the Python client, please visit:

Author

[email protected]