Elasticsearch Python Client
Official Python client for Elasticsearch. Current version: 9.3.0 (Mar 2026). v8.0 was a major breaking change from v7.x: 'body' parameter removed in favor of named keyword arguments, doc_type removed, transport layer rewritten. Client version must match Elasticsearch server major version. Multiple packages on PyPI: elasticsearch (latest), elasticsearch8, elasticsearch7 for pinning to specific major versions.
Warnings
- breaking 'body' parameter removed in v8.0. es.search(body={...}) and es.index(body={...}) raise TypeError. The most common pattern in all pre-2022 tutorials and LLM-generated code.
- breaking doc_type parameter removed in v8.0. Elasticsearch dropped mapping types — there is no more _doc or custom type. Raises TypeError.
- breaking Client major version must match Elasticsearch server major version. v9 client against v8 server (or v8 client against v7 server) raises UnsupportedProductError.
- breaking Authentication changed in v8. Old: Elasticsearch(http_auth=('user', 'pass')). New: Elasticsearch(basic_auth=('user', 'pass')) or api_key='...'.
- gotcha Three packages on PyPI: elasticsearch (latest), elasticsearch8, elasticsearch7. 'pip install elasticsearch' always installs latest major. If your server is v8, 'pip install elasticsearch' will install v9 and break.
- gotcha Response is now ObjectApiResponse — dict-like but not a plain dict. Most code works but isinstance(resp, dict) is False.
- gotcha Elastic Cloud connections use cloud_id + api_key — not a URL. Using a URL for Elastic Cloud works but is not recommended.
Install
-
pip install elasticsearch -
pip install elasticsearch8 -
pip install elasticsearch7
Imports
- Elasticsearch index/search (v8+ style)
from elasticsearch import Elasticsearch es = Elasticsearch( 'https://localhost:9200', basic_auth=('user', 'password'), ca_certs='/path/to/ca.crt' ) # Index — use 'document=' not 'body=' es.index( index='my-index', id='1', document={'name': 'Alice', 'age': 30} ) # Search — use 'query=' not 'body=' resp = es.search( index='my-index', query={'match': {'name': 'Alice'}} ) print(resp['hits']['hits']) - AsyncElasticsearch
from elasticsearch import AsyncElasticsearch import asyncio async def main(): es = AsyncElasticsearch( 'https://localhost:9200', basic_auth=('user', 'password') ) resp = await es.search( index='my-index', query={'match_all': {}} ) print(resp['hits']['hits']) await es.close() asyncio.run(main())
Quickstart
# pip install elasticsearch
from elasticsearch import Elasticsearch
# Elastic Cloud
es = Elasticsearch(
cloud_id='my-deployment:dXMtZ...',
api_key='my-api-key'
)
# Self-hosted
es = Elasticsearch(
'https://localhost:9200',
basic_auth=('elastic', 'password'),
verify_certs=False # dev only
)
# Index a document — no body=, no doc_type
es.index(index='products', id='1', document={
'name': 'Widget',
'price': 9.99
})
# Search
resp = es.search(
index='products',
query={'match': {'name': 'Widget'}}
)
for hit in resp['hits']['hits']:
print(hit['_source'])
es.close()