{"id":171,"library":"meilisearch","title":"Meilisearch Python Client","description":"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+.","status":"active","version":"0.40.0","language":"python","source_language":"en","source_url":"https://github.com/meilisearch/meilisearch-python","tags":["meilisearch","search","python","fulltext","typo-tolerant","algolia-alternative"],"install":[{"cmd":"pip install meilisearch","lang":"bash","label":"Python (official — sync only)"},{"cmd":"pip install meilisearch-python-sdk","lang":"bash","label":"Python (community — sync + async)"}],"dependencies":[{"reason":"Required by official meilisearch package. Installed automatically.","package":"requests","optional":false}],"imports":[{"note":"add_documents() is non-blocking. Meilisearch queues the task — documents are not immediately searchable. Must wait for task to succeed before searching.","wrong":"import meilisearch\n\n# Wrong: treating add_documents as synchronous confirmation\nclient = meilisearch.Client('http://127.0.0.1:7700', 'masterKey')\nindex = client.index('movies')\nindex.add_documents(docs)\n# immediately searching — docs may not be indexed yet\nresult = index.search('wonder')  # may return empty","symbol":"Client (official sync)","correct":"import meilisearch\n\nclient = meilisearch.Client('http://127.0.0.1:7700', 'masterKey')\n\n# Index reference (creates if not exists on first add_documents)\nindex = client.index('movies')\n\n# Add documents — returns Task, not confirmation\ntask = index.add_documents([\n    {'id': 1, 'title': 'Carol', 'genres': ['Romance', 'Drama']},\n    {'id': 2, 'title': 'Wonder Woman', 'genres': ['Action']},\n])\nprint(task.task_uid)  # poll this to confirm indexing\n\n# Search\nresult = index.search('wonder')\nprint(result['hits'])"},{"note":"Official 'meilisearch' package has no async support. For FastAPI/asyncio use 'meilisearch-python-sdk' which has AsyncClient.","wrong":"# Using official meilisearch package in async context\nimport meilisearch\nasync def main():\n    client = meilisearch.Client('http://127.0.0.1:7700', 'masterKey')\n    # This blocks the event loop — no async support in official package","symbol":"AsyncClient (meilisearch-python-sdk)","correct":"from meilisearch_python_sdk import AsyncClient\nimport asyncio\n\nasync def main():\n    async with AsyncClient('http://127.0.0.1:7700', 'masterKey') as client:\n        index = client.index('movies')\n        task = await index.add_documents([\n            {'id': 1, 'title': 'Carol'}\n        ])\n        # Wait for indexing to complete\n        await client.wait_for_task(task.task_uid)\n        result = await index.search('carol')\n        print(result.hits)\n\nasyncio.run(main())"}],"quickstart":{"code":"# pip install meilisearch\nimport meilisearch\nimport time\n\nclient = meilisearch.Client('http://127.0.0.1:7700', 'masterKey')\nindex = client.index('products')\n\n# Add documents (non-blocking)\ntask = index.add_documents([\n    {'id': '1', 'name': 'Widget', 'price': 9.99},\n    {'id': '2', 'name': 'Gadget', 'price': 24.99},\n])\n\n# Wait for indexing (dev only — use task polling in production)\nclient.wait_for_task(task.task_uid)\n\n# Configure filterable attributes (triggers re-index)\nindex.update_filterable_attributes(['price'])\n\n# Search\nresult = index.search('widget')\nfor hit in result['hits']:\n    print(hit['name'])\n\n# Search with filter\nresult = index.search('', {'filter': 'price < 15'})\nprint(result['hits'])","lang":"python","description":"Meilisearch Python client — indexing, waiting for task, and search."},"warnings":[{"fix":"pip install meilisearch-python-sdk; from meilisearch_python_sdk import AsyncClient","message":"Official 'meilisearch' package is sync-only. No async support. For FastAPI/asyncio use 'meilisearch-python-sdk' (community package) which provides AsyncClient.","severity":"breaking","affected_versions":"all"},{"fix":"Call client.wait_for_task(task.task_uid) after indexing to wait for completion. In production use task polling instead.","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Set filterableAttributes and sortableAttributes once at index creation time. Track the returned task and wait before querying with new filters.","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Always include 'id' field in documents, or specify primary_key when creating index: client.create_index('movies', {'primaryKey': 'movie_id'})","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Use client.get_index('name') to get an existing index (raises if not found). Use client.index('name') as a reference that auto-creates on first write.","message":"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().","severity":"gotcha","affected_versions":"all"},{"fix":"Pin version: pip install meilisearch==0.40.0. Check server compatibility at github.com/meilisearch/meilisearch-python.","message":"Still pre-1.0 (0.40.x). API may change across minor versions. Compatible with Meilisearch server v1.2+ only.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure the Meilisearch server is running and accessible. If it's on a different host or port, initialize the client with `Client('http://your-meilisearch-host:port', 'your-master-key')`.","message":"Meilisearch client failed to connect to the server (Connection refused). This typically means the Meilisearch server is not running or is not accessible at the specified host and port (default 127.0.0.1:7700).","severity":"breaking","affected_versions":"all"},{"fix":"Ensure the Meilisearch server is running and accessible before initializing the client or making API calls. Check the server's listening address and port, and configure your Meilisearch client accordingly if it differs from the default.","message":"Failed to connect to Meilisearch server. A ConnectionRefusedError typically means the Meilisearch server process is not running, or it's not accessible at the configured host and port (default 127.0.0.1:7700).","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T09:15:10.161Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"Ensure the correct package is installed using `pip install meilisearch` for the sync client, or `pip install meilisearch-python-sdk` for the async client. Then, verify the import statement, e.g., `import meilisearch` or `from meilisearch_python_sdk import Client as AsyncClient`.","cause":"The 'meilisearch' package is not installed in the Python environment, or there is a typo in the import statement, or the wrong package name is used (e.g., trying to import 'meilisearch' when 'meilisearch-python-sdk' was intended and installed).","error":"ModuleNotFoundError: No module named 'meilisearch'"},{"fix":"Verify that your Meilisearch server instance is running and accessible at the specified URL and port (default is `http://localhost:7700`). Ensure the URL includes `http://` or `https://`. Example: `client = meilisearch.Client('http://127.0.0.1:7700', 'YOUR_MASTER_KEY')`.","cause":"The Python client failed to establish a connection with the Meilisearch server. This often happens if the server is not running, is running on a different URL or port than specified, or a firewall is blocking the connection. This can also manifest as `ConnectionError: Max retries exceeded` or `Connection refused` messages from the underlying requests library.","error":"meilisearch.errors.MeilisearchCommunicationError"},{"fix":"Ensure each document in your list has a unique 'id' field (or the field specified as `primary_key` when the index was created or updated). If 'id' is not desired, set a different `primary_key` when creating the index: `client.create_index('my_index', {'primaryKey': 'my_custom_id'})`.","cause":"When adding documents to a Meilisearch index, each document must contain a unique primary key. By default, Meilisearch looks for a field named 'id' (case-insensitive) to use as the primary key. If no 'id' field is present and a `primary_key` is not explicitly set for the index, this error occurs.","error":"MeilisearchApiError: Error code: invalid_document_uid. Error message: A document must have a 'id' field with a string or integer value."},{"fix":"If you intend to use asynchronous operations, install `meilisearch-python-sdk` (`pip install meilisearch-python-sdk`) and import `AsyncClient`: `from meilisearch_python_sdk import AsyncClient`. If you are using the `meilisearch` package, remove `await` keywords as its methods are blocking.","cause":"This error typically occurs when trying to use `await` with the synchronous `meilisearch` client's methods. The official `meilisearch` package is synchronous only. Asynchronous operations require the `meilisearch-python-sdk` package and its `AsyncClient`.","error":"TypeError: object NoneType can't be awaited"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.99,"mem_mb":16.7,"disk_size":"31.6M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.71,"mem_mb":16.7,"disk_size":"31M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.35,"mem_mb":18.4,"disk_size":"34.5M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.11,"mem_mb":18.4,"disk_size":"34M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.46,"mem_mb":18.3,"disk_size":"26.1M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.46,"mem_mb":18.3,"disk_size":"26M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.03,"mem_mb":17.3,"disk_size":"25.8M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":1.04,"mem_mb":17.3,"disk_size":"25M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.94,"mem_mb":16.5,"disk_size":"31.0M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.85,"mem_mb":16.5,"disk_size":"31M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":1,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":null,"mem_mb":null,"disk_size":null}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}