Meilisearch Python Client
Official Python client for Meilisearch — open source typo-tolerant search engine. Current version: 0.40.0 (Jan 2026). Still pre-1.0. Official 'meilisearch' package is SYNC ONLY. For async use the community 'meilisearch-python-sdk' package instead. Two different packages, two different imports. add_documents() is non-blocking — returns a Task object, not a confirmation. Must poll task status to confirm indexing completed. Compatible with Meilisearch server v1.2+.
Warnings
- breaking Official 'meilisearch' package is sync-only. No async support. For FastAPI/asyncio use 'meilisearch-python-sdk' (community package) which provides AsyncClient.
- gotcha add_documents() is non-blocking — returns a Task object with task_uid. Documents are NOT immediately searchable. Searching immediately after add_documents may return empty results.
- gotcha Updating filterableAttributes or sortableAttributes triggers a full index rebuild. On large datasets this can take minutes. Index is still searchable during rebuild but with old settings.
- gotcha Every document must have a primary key field. Default is 'id'. If no 'id' field exists and no primary key is specified, indexing fails silently or raises MeilisearchApiError.
- gotcha client.index('name') does NOT create the index — it returns an index reference object. Index is created on first add_documents() call or explicitly with client.create_index().
- gotcha Still pre-1.0 (0.40.x). API may change across minor versions. Compatible with Meilisearch server v1.2+ only.
Install
-
pip install meilisearch -
pip install meilisearch-python-sdk
Imports
- Client (official sync)
import meilisearch client = meilisearch.Client('http://127.0.0.1:7700', 'masterKey') # Index reference (creates if not exists on first add_documents) index = client.index('movies') # Add documents — returns Task, not confirmation task = index.add_documents([ {'id': 1, 'title': 'Carol', 'genres': ['Romance', 'Drama']}, {'id': 2, 'title': 'Wonder Woman', 'genres': ['Action']}, ]) print(task.task_uid) # poll this to confirm indexing # Search result = index.search('wonder') print(result['hits']) - AsyncClient (meilisearch-python-sdk)
from meilisearch_python_sdk import AsyncClient import asyncio async def main(): async with AsyncClient('http://127.0.0.1:7700', 'masterKey') as client: index = client.index('movies') task = await index.add_documents([ {'id': 1, 'title': 'Carol'} ]) # Wait for indexing to complete await client.wait_for_task(task.task_uid) result = await index.search('carol') print(result.hits) asyncio.run(main())
Quickstart
# pip install meilisearch
import meilisearch
import time
client = meilisearch.Client('http://127.0.0.1:7700', 'masterKey')
index = client.index('products')
# Add documents (non-blocking)
task = index.add_documents([
{'id': '1', 'name': 'Widget', 'price': 9.99},
{'id': '2', 'name': 'Gadget', 'price': 24.99},
])
# Wait for indexing (dev only — use task polling in production)
client.wait_for_task(task.task_uid)
# Configure filterable attributes (triggers re-index)
index.update_filterable_attributes(['price'])
# Search
result = index.search('widget')
for hit in result['hits']:
print(hit['name'])
# Search with filter
result = index.search('', {'filter': 'price < 15'})
print(result['hits'])