anchor.diff:  
   This page contains the information you need to connect the Client with {es}.
   
  +[discrete]
  +[[connect-ec]]
  +=== Connecting to Elastic Cloud
  +
  +https://www.elastic.co/guide/en/cloud/current/ec-getting-started.html[Elastic Cloud] is the easiest way to get started with Elasticsearch. When connecting to Elastic Cloud with the Python Elasticsearch client you should always use the `cloud_id` parameter to connect. You can find this value within the "Manage Deployment" page after you've created a cluster (look in the top-left if you're in Kibana).
  +
  +We recommend using a Cloud ID whenever possible because your client will be automatically configured for optimal use with Elastic Cloud including HTTPS and HTTP compression.
  +
  +[source,python]
  +----
  +from elasticsearch import Elasticsearch
  +
  +# Password for the 'elastic' user generated by Elasticsearch
  +ELASTIC_PASSWORD = "<password>"
  +
  +# Found in the 'Manage Deployment' page
  +CLOUD_ID = "deployment-name:dXMtZWFzdDQuZ2Nw..."
  +
  +# Create the client instance
  +client = Elasticsearch(
  +    cloud_id=CLOUD_ID,
  +    basic_auth=("elastic", ELASTIC_PASSWORD)
  +)
  +
  +# Successful response!
  +client.info()
  +# {'name': 'instance-0000000000', 'cluster_name': ...}
  +----
  +
  +[discrete]
  +[[connect-self-managed-new]]
  +=== Connecting to a self-managed cluster
  +
  +By default Elasticsearch will start with security features like authentication and TLS enabled. To connect to the Elasticsearch cluster you'll need to configure the Python Elasticsearch client to use HTTPS with the generated CA certificate in order to make requests successfully.
  +
  +If you're just getting started with Elasticsearch we recommend reading the documentation on https://www.elastic.co/guide/en/elasticsearch/reference/current/settings.html[configuring] and https://www.elastic.co/guide/en/elasticsearch/reference/current/starting-elasticsearch.html[starting Elasticsearch] to ensure your cluster is running as expected.
  +
  +When you start Elasticsearch for the first time you'll see a distinct block like the one below in the output from Elasticsearch (you may have to scroll up if it's been a while):
  +
  +[source,sh]
  +----
  +----------------------------------------------------------------------
  +-> Elasticsearch security features have been automatically configured!
  +-> Authentication is enabled and cluster connections are encrypted.
  +
  +->  Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
  +  lhQpLELkjkrawaBoaz0Q
  +
  +->  HTTP CA certificate SHA-256 fingerprint:
  +  a52dd93511e8c6045e21f16654b77c9ee0f34aea26d9f40320b531c474676228
  +...
  +----------------------------------------------------------------------
  +----
  +
  +Note down the `elastic` user password and HTTP CA fingerprint for the next sections. In the examples below they will be stored in the variables `ELASTIC_PASSWORD` and `CERT_FINGERPRINT` respectively.
  +
  +Depending on the circumstances there are two options for verifying the HTTPS connection, either verifying with the CA certificate itself or via the HTTP CA certificate fingerprint.
  +
  +[discrete]
  +==== Verifying HTTPS with CA certificates
  +
  +Using the `ca_certs` option is the default way the Python Elasticsearch client verifies an HTTPS connection.
  +
  +The generated root CA certificate can be found in the `certs` directory in your Elasticsearch config location (`$ES_CONF_PATH/certs/http_ca.crt`). If you're running Elasticsearch in Docker there is https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html[additional documentation for retrieving the CA certificate].
  +
  +Once you have the `http_ca.crt` file somewhere accessible pass the path to the client via `ca_certs`:
  +
  +[source,python]
  +----
  +from elasticsearch import Elasticsearch
  +
  +# Password for the 'elastic' user generated by Elasticsearch
  +ELASTIC_PASSWORD = "<password>"
  +
  +# Create the client instance
  +client = Elasticsearch(
  +    "https://localhost:9200",
  +    ca_certs="/path/to/http_ca.crt",
  +    basic_auth=("elastic", ELASTIC_PASSWORD)
  +)
  +
  +# Successful response!
  +client.info()
  +# {'name': 'instance-0000000000', 'cluster_name': ...}
  +----
  +
  +NOTE: If you don't specify `ca_certs` or `ssl_assert_fingerprint` then the https://certifiio.readthedocs.io[certifi package] will be used for `ca_certs` by default if available.
  +
  +[discrete]
  +==== Verifying HTTPS with certificate fingerprints (Python 3.10 or later)
  +
  +NOTE: Using this method **requires using Python 3.10 or later** and isn't available when using the `aiohttp` HTTP client library so can't be used with `AsyncElasticsearch`.
  +
  +This method of verifying the HTTPS connection takes advantage of the certificate fingerprint value noted down earlier. Take this SHA256 fingerprint value and pass it to the Python Elasticsearch client via `ssl_assert_fingerprint`:
  +
  +[source,python]
  +----
  +from elasticsearch import Elasticsearch
  +
  +# Fingerprint either from Elasticsearch startup or above script.
  +# Colons and uppercase/lowercase don't matter when using
  +# the 'ssl_assert_fingerprint' parameter
  +CERT_FINGERPRINT = "A5:2D:D9:35:11:E8:C6:04:5E:21:F1:66:54:B7:7C:9E:E0:F3:4A:EA:26:D9:F4:03:20:B5:31:C4:74:67:62:28"
  +
  +# Password for the 'elastic' user generated by Elasticsearch
  +ELASTIC_PASSWORD = "<password>"
  +
  +client = Elasticsearch(
  +    "https://localhost:9200",
  +    ssl_assert_fingerprint=CERT_FINGERPRINT,
  +    basic_auth=("elastic", ELASTIC_PASSWORD)
  +)
  +
  +# Successful response!
  +client.info()
  +# {'name': 'instance-0000000000', 'cluster_name': ...}
  +----
  +
  +The certificate fingerprint can be calculated using `openssl x509` with the certificate file:
  +
  +[source,sh]
  +----
  +openssl x509 -fingerprint -sha256 -noout -in /path/to/http_ca.crt
  +----
  +
  +If you don't have access to the generated CA file from Elasticsearch you can use the following script to output the root CA fingerprint of the Elasticsearch instance with `openssl s_client`:
  +
  +[source,sh]
  +----
  +# Replace the values of 'localhost' and '9200' to the
  +# corresponding host and port values for the cluster.
  +openssl s_client -connect localhost:9200 -servername localhost -showcerts </dev/null 2>/dev/null \
  +  | openssl x509 -fingerprint -sha256 -noout -in /dev/stdin
  +----
  +
  +The output of `openssl x509` will look something like this:
  +
  +[source,sh]
  +----
  +SHA256 Fingerprint=A5:2D:D9:35:11:E8:C6:04:5E:21:F1:66:54:B7:7C:9E:E0:F3:4A:EA:26:D9:F4:03:20:B5:31:C4:74:67:62:28
  +----
  +
  +
  +[discrete]
  +[[connect-no-security]]
  +=== Connecting without security enabled
  +
  +WARNING: Running Elasticsearch without security enabled is not recommended.
  +
  +If your cluster is configured with https://www.elastic.co/guide/en/elasticsearch/reference/current/security-settings.html[security explicitly disabled] then you can connect via HTTP:
  +
  +[source,python]
  +----
  +from elasticsearch import Elasticsearch
  +
  +# Create the client instance
  +client = Elasticsearch("http://localhost:9200")
  +
  +# Successful response!
  +client.info()
  +# {'name': 'instance-0000000000', 'cluster_name': ...}
  +----
   
   [discrete]
   [[connect-url]]
  -==== Connecting with URLs
  -
  -A single node can be specified via a `scheme`, `host`, `port`, and optional `path_prefix`. These values can either be specified manually via a URL in a string, dictionary, `NodeConfig`, or a list of these values. You must specify at least `scheme`, `host` and `port` for each node. All of the following are valid configurations:
  -
  -[source,python]
  -----------------------------
  -from elasticsearch import Elasticsearch
  -
  -# Single node via URL
  -es = Elasticsearch("http://localhost:9200")
  -
  -# Multiple nodes via URL
  -es = Elasticsearch([
  -    "http://localhost:9200",
  -    "http://localhost:9201",
  -    "http://localhost:9202"
  -])
  -
  -# Single node via dictionary
  -es = Elasticsearch({"scheme": "http", "host": "localhost", "port": 9200})
  -
  -# Multiple nodes via dictionary
  -es = Elasticsearch([
  -    {"scheme": "http", "host": "localhost", "port": 9200},
  -    {"scheme": "http", "host": "localhost", "port": 9201},
  -])
  -----------------------------
  -
  -[discrete]
  -[[connect-ec]]
  -==== Connecting to Elastic Cloud
  -
  -Cloud ID is an easy way to configure your client to work with your Elastic Cloud 
  -deployment. Combine the `cloud_id` with either `basic_auth` or `api_key` to 
  -authenticate with your Elastic Cloud deployment.
  -
  -Using `cloud_id` enables TLS verification and HTTP compression by default and 
  -sets the port to 443 unless otherwise overwritten via the port parameter or the 
  -port value encoded within `cloud_id`. Using Cloud ID also disables sniffing as
  -a proxy is in use.
  -
  -[source,python]
  -----------------------------
  -from elasticsearch import Elasticsearch
  -
  -es = Elasticsearch(
  -    cloud_id="cluster-1:dXMa5Fx..."
  -)
  -----------------------------
  +=== Connecting to multiple nodes
  +
  +The Python Elasticsearch client supports sending API requests to multiple nodes in the cluster. This means that work will be more evenly spread across the cluster instead of hammering the same node over and over with requests. To configure the client with multiple nodes you can pass a list of URLs, each URL will be used as a separate node in the pool.
  +
  +[source,python]
  +----
  +from elasticsearch import Elasticsearch
  +
  +# List of nodes to connect use with different hosts and ports.
  +NODES = [
  +    "https://localhost:9200",
  +    "https://localhost:9201",
  +    "https://localhost:9202",
  +]
  +
  +# Password for the 'elastic' user generated by Elasticsearch
  +ELASTIC_PASSWORD = "<password>"
  +
  +client = Elasticsearch(
  +    NODES,
  +    ca_certs="/path/to/http_ca.crt",
  +    basic_auth=("elastic", ELASTIC_PASSWORD)
  +)
  +----
  +
  +By default nodes are selected using round-robin, but alternate node selection strategies can be configured with `node_selector_class` parameter.
  +
  +NOTE: If your Elasticsearch cluster is behind a load balancer like when using Elastic Cloud you won't need to configure multiple nodes. Instead use the load balancer host and port.
   
   
   [discrete]
  
positive.code:         index="example-index",
          document={"field": i}
      )
  ----------------------------
  
  
  [discrete]
  
negative.code: ==== GCP Cloud Functions
  
  [source,python]
  ----
  from elasticsearch import Elasticsearch
  
  # Client initialization
  client = Elasticsearch(
      cloud_id="deployment-name:ABCD...",
      api_key=...
  )
  
  def main(request):
      # Use the client
      client.search(index=..., query={"match_all": {}})
  
  ----
  
  [discrete]
  [[connecting-faas-aws]]
  ==== AWS Lambda
  
  [source,python]
  ----
  from elasticsearch import Elasticsearch
  
  # Client initialization
  client = Elasticsearch(
      cloud_id="deployment-name:ABCD...",
      api_key=...
  )
  
  def main(event, context):
      # Use the client
      client.search(index=..., query={"match_all": {}})
  
  ----
  
  [discrete]
  [[connecting-faas-azure]]
  ==== Azure Functions
  
  [source,python]
  ----
  import azure.functions as func
  from elasticsearch import Elasticsearch
  
  # Client initialization
  client = Elasticsearch(
      cloud_id="deployment-name:ABCD...",
      api_key=...
  )
  
  def main(request: func.HttpRequest) -> func.HttpResponse:
      # Use the client
      client.search(index=..., query={"match_all": {}})
  
  ----
  
  Resources used to assess these recommendations:
  
  