Open-source project
elastic/elasticsearch-py avatar
elastic/elasticsearch-py

elasticsearch-py 9.5: What the Official Python Client Actually Does for You

elasticsearch-py is the official Python client for Elasticsearch, providing typed query construction, index and document lifecycle APIs, bulk operations, async compatibility, and version-aware client behavior.

4,386 stars1,221 forksPythonApache-2.0

At a glance

What is it?
A look at the official Python client for Elasticsearch, covering its version-aware design, connection handling, and helper functions, plus the real trade-offs you face when adopting it.
Who is it for?
Adopt elasticsearch-py if you need a maintained, version-aware client for Elasticsearch 8.x or 9.x and want to avoid writing raw HTTP calls. Skip it if you only query Elasticsearch occasionally or need full feature parity with a newer server version.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The Problem: Speaking Elasticsearch's REST API in Python

Elasticsearch exposes a JSON-over-HTTP API that is powerful but verbose. Every index creation, document write, and search query requires building the right URL, method, headers, and body. Doing that by hand with requests or urllib is error-prone and repetitive. elasticsearch-py exists to translate Python data types to and from JSON, manage connections, and provide typed methods for each API endpoint. It is for teams that build applications against Elasticsearch and want a client that tracks the server's evolving API without them reimplementing the protocol each time.

Version-Aware Design: Forward and Backward Compatibility

The client follows a specific compatibility rule: each client version works with equivalent and later minor versions of Elasticsearch without breaking. That means an 8.12 client works with an 8.13 server, but it does not support new 8.13 features. Full feature parity only exists when the client version matches the server version. The README makes this explicit: upgrade the server first, then upgrade the client. This is a sensible policy, but it has a real cost: if you run a mixed-version environment or lag behind on client upgrades, you will not see new server capabilities. The compatibility table shows that the 8.x branch also serves as a fallback for 9.x servers, which is useful if you are not ready to move to the 9.x client. Older clients are released under separate package names, elasticsearch7 and elasticsearch8, so you can pin to a major version without breaking your dependency resolution.

Connection Handling and Node Discovery

The client does more than wrap API calls. It manages persistent connections, which avoids the overhead of opening a new TCP connection for every request. It also supports automatic discovery of cluster nodes, so when the cluster topology changes, the client can find new nodes without manual reconfiguration. Load balancing across nodes uses a pluggable selection strategy, meaning you can swap in your own logic if the default does not fit your traffic pattern. Failed connections are penalized on a time basis: a failed node is not retried until a timeout expires. This is a practical mechanism for dealing with transient failures, but it also means that a node that comes back quickly might still be ignored until the penalty window passes. The README lists thread safety across requests as a feature, which is important for concurrent workloads, but it does not explain how that thread safety is achieved, so you should verify it against your own concurrency model.

Getting Started: Commands and Configuration

The README does not include a full installation command, but it points to the getting-started documentation for installation and connection details. The one concrete command it gives is for running Elasticsearch and Kibana locally: curl -fsSL https://elastic.co/start-local | sh. That command starts Elasticsearch on localhost:9200 and Kibana on localhost:5601. For the client itself, you would typically install it from PyPI with pip install elasticsearch, though the README does not state that exact command. The usage examples link to documentation for creating an index, indexing a document, getting documents, searching, updating, and deleting. Those links are the authoritative source for actual code, because the README itself does not show a single code snippet. That is a gap: a developer evaluating the client cannot see a minimal example without clicking through. The configuration keys for connection settings, such as hosts, authentication, or TLS, are also not shown in the README, so you must consult the full docs to know what options exist.

Helpers and Pluggable Architecture

The README mentions helper functions for idiomatically using APIs together. These helpers are the part that saves you from writing boilerplate for common patterns like bulk indexing or scrolling through large result sets. The exact helper names are not listed in the README, but the feature list makes clear they exist. The pluggable architecture extends beyond load balancing: you can customize parts of the client's behavior, though the README does not specify which parts. This is a trade-off. Pluggability gives you flexibility, but it also means you need to understand the extension points before you can use them effectively. For a simple use case, the default behavior is probably fine. For a complex deployment with custom retry logic or node selection, you will need to read the source or the full documentation to know where to hook in.

A Real Limitation: Feature Parity Lag and Upgrade Order

The most concrete limitation is the feature parity lag. If you run a 9.5 client against a 9.5 server, you get full support. If you run a 9.4 client against a 9.5 server, you get compatibility but not new features. That means you must plan upgrades carefully. The README advises upgrading the server first, then the client. This is a clear sequence, but it can be a problem in environments where the server is managed by a separate team or where you cannot control the upgrade schedule. In those cases, you might be stuck on an older client and miss out on new query types or API parameters. Another limitation is that compatibility does not imply full feature parity, so even within the same major version, you need to check the release notes for the specific feature you want. The README is honest about this, but it is a real operational constraint.

Alternatives: Raw HTTP and Other Clients

The obvious alternative is to skip a dedicated client and use requests or httpx directly against the Elasticsearch REST API. That approach gives you full control over every request and avoids the dependency, but you lose the JSON translation, connection pooling, node discovery, and helper functions. You also have to handle retries, error parsing, and version-specific URL changes yourself. Another alternative is the elasticsearch-dsl library, which builds on elasticsearch-py and provides a higher-level query DSL. It is not mentioned in the README, but it is a known companion. The key difference is that elasticsearch-dsl adds a layer of abstraction for building queries in Python, while elasticsearch-py stays closer to the raw API. If you want concise query construction, elasticsearch-dsl is worth evaluating, but it adds its own learning curve and dependency. For most projects, starting with elasticsearch-py and only adding the DSL if you find yourself writing repetitive query code is a reasonable path.

Maintenance and License Considerations

The repository is actively maintained, with a recent release in August 2026 and a CI workflow that runs on GitHub Actions. The integration tests run on Buildkite, which suggests a serious testing pipeline. The license is Apache-2.0, which is permissive for commercial use, but it does not grant any rights to Elasticsearch itself, which has its own license. You should check the Elasticsearch server license separately if you are deploying it. The client is released under Apache-2.0, so you can modify and redistribute it, but you must retain the license and NOTICE files. The maintenance cost for you is low if you keep the client version in sync with the server version, because the client is designed to be backward compatible across minor versions. However, you must plan for major version upgrades, which will require code changes if the API surface changes. The README does not detail what changes between major versions, so you should review the release notes before upgrading.

Editorial conclusion

Adopt elasticsearch-py if you need a maintained, version-aware client for Elasticsearch 8.x or 9.x and want to avoid writing raw HTTP calls. Skip it if you only query Elasticsearch occasionally or need full feature parity with a newer server version. Before upgrading to a new major version, upgrade your Elasticsearch cluster first, then upgrade the client, and verify that the specific APIs you use are supported in the client version you target.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Community notes

Community notes