opensearch-py

repository·main·Indexed 19 days ago

https://github.com/opensearch-project/opensearch-py

A community-driven, open-source Python client for OpenSearch, forked from elasticsearch-py. It provides Pythonic interfaces to interact with OpenSearch clusters, featuring specialized clients for cluster management, indices, security, snapshots, and CAT operations. The library supports synchronous and asynchronous communication, AWS SigV4 authentication, and provides compatibility mappings for OpenSearch versions 1.0.0 through 3.x.

Tokens
36K
Snippets
157
Records
175
Agent score
67%

What's inside opensearch-py

  1. Overview of OpenSearch Python Clients

    main
    The opensearch-py library provides a suite of specialized clients to interact with different facets of an OpenSearch cluster. While the primary entry point is the OpenSearch client, the library includes specialized clients for specific administrative and functional tasks, such as managing indices, security, snapshots, and cluster state.
  2. Use the ML Commons Plugin for AI-powered search

    main
    The ML Commons Plugin allows you to manage machine learning models, agents, connectors, and memory within OpenSearch. It is designed to support AI-powered search features, including model lifecycle management, conversational AI agents, and memory management for chat applications. You can interact with these features via the ML Commons Plugin API.
  3. Automate index operations with the Index Management Plugin (ISM)

    main
    The Index Management Plugin (ISM) API allows you to programmatically automate periodic administrative operations on indexes. You can trigger actions based on changes in index age, index size, or the number of documents. This is useful for managing lifecycles, such as moving data from hot to warm storage or deleting old logs.
  4. How template priority works with multiple matching templates

    main

    If an index name matches multiple index templates, OpenSearch applies the template with the highest priority value. If no priority is specified, it defaults to 0.

    For example, if you have a template for books-* with priority: 0 and another for books-fiction-* with priority: 1, an index named books-fiction-romance will use the settings from the books-fiction-* template because its priority is higher.

    # Template with default priority
    client.indices.put_index_template(
      name='books',
      body={
        'index_patterns': ['books-*'],
        'priority': 0,
        'template': {
          'settings': {
            'index': {
              'number_of_shards': 3,
              'number_of_replicas': 0
            }
          }
        }
      }
    )
    
    # Template with higher priority
    client.indices.put_index_template(
      name='books-fiction',
      body={
        'index_patterns': ['books-fiction-*'],
        'priority': 1,
        'template': {
          'settings': {
            'index': {
              'number_of_shards': 1,
              'number_of_replicas': 1
            }
          }
        }
      }
    )
  5. Use a Data Generator with Bulk Helpers

    main

    To avoid loading massive datasets into memory as a single Python list, you can pass a generator function to helpers.bulk or helpers.parallel_bulk. This allows you to stream data into the bulk process efficiently. The generator should yield dictionaries containing the necessary metadata (like _index and _id) and the document body.

    def _generate_data():
        for i in range(100):
            yield {"_index": index_name, "_id": i, "value": i}
    
    succeeded = []
    failed = []
    for success, item in helpers.parallel_bulk(client, actions=_generate_data()):
        if success:
            succeeded.append(item)
        else:
            failed.append(item)
    
    if len(failed) > 0:
        print(f"There were {len(failed)} errors:")
        for item in failed:
            print(item["index"]["error"])
    
    if len(succeeded) > 0:
        print(f"Bulk-inserted {len(succeeded)} items (streaming_bulk).")
  6. Choose a Connection Class for OpenSearch Python

    main

    The OpenSearch Python client allows you to specify different connection classes depending on whether you are using the synchronous or asynchronous client, and which underlying HTTP library you prefer.

    • Synchronous Client: Supports Urllib3HttpConnection (the default, based on urllib3) and RequestsHttpConnection (based on requests). Use Urllib3HttpConnection unless your application is already standardized on requests.
    • Asynchronous Client: Uses AsyncHttpConnection (based on aiohttp) via the AsyncOpenSearch client.
  7. Access high-level DSL features via opensearchpy.helpers

    main

    In opensearch-py (version 2.2.0 and later), you can import high-level DSL functionalities directly from the opensearchpy.helpers module. This eliminates the requirement to import opensearch-dsl-py for the following feature sets:

    • aggs
    • analysis
    • document
    • faceted search
    • field
    • function
    • index
    • mapping
    • query
    • search
    • update by query
    • utils
    • wrappers
  8. Use Composable Index Templates

    main

    Composable index templates allow you to define reusable component_templates and then compose them into a final index template using the composed_of parameter. This is useful for sharing mappings or settings across multiple different index templates.

    1. Create a component template using client.cluster.put_component_template.
    2. Create an index template using client.indices.put_index_template and include the component name in the composed_of list.
    # 1. Create a component template
    client.cluster.put_component_template(
      name='books_mappings',
      body={
        'template': {
          'mappings': {
            'properties': {
              'title': { 'type': 'text' },
              'author': { 'type': 'text' },
              'published_on': { 'type': 'date' },
              'pages': { 'type': 'integer' }
            }
          }
        }
      }
    )
    
    # 2. Compose it into an index template
    client.indices.put_index_template(
      name='books',
      body={
        'index_patterns': ['books-*'],
        'composed_of': ['books_mappings'],
        'priority': 0,
        'template': {
          'settings': {
            'index': {
              'number_of_shards': 3,
              'number_of_replicas': 0
            }
          }
        }
      }
    )
  9. Initialize an OpenSearch client and prepare an index

    main

    To start using OpenSearch, you must first create a client instance using OpenSearch. You can then create indices using client.indices.create and populate them with documents using client.index. After adding documents, it is recommended to call client.indices.refresh to ensure the documents are immediately searchable.

    from opensearchpy import OpenSearch
    
    # create an OpenSearch client
    client = OpenSearch(hosts=['localhost'])
    
    # create an index
    client.indices.create(index='movies')
    
    # add a document
    client.index(
        index='movies',
        body={
            'title': 'The Godfather',
            'director': 'Francis Ford Coppola',
            'year': 1972
        }
    )
    
    # refresh the index to make the documents searchable
    client.indices.refresh(index='movies')
  10. Setup the OpenSearch client for Snapshot operations

    main

    To perform snapshot actions, you first need to initialize an OpenSearch client and create an index to back up. This example demonstrates connecting to a local instance and creating a movies index.

    from opensearchpy import OpenSearch
    
    host = 'localhost'
    port = 9200
    auth = ('admin', 'admin') # For testing only. Don't store credentials in code.
    
    client = OpenSearch(
        hosts = [{'host': host, 'port': port}],
        http_auth = auth,
        use_ssl = True,
        verify_certs = False,
        ssl_show_warn = False
    )
    
    print(client.info())  # Check server info and make sure the client is connected
    client.indices.create(index='movies')
  11. Index vectors in a k-NN index

    main

    You can index vectors using the bulk API. Ensure that the vector being indexed matches the dimension defined in the index mapping.

    vectors = []
    for i in range(10):
        vec = []
        for j in range(dimensions): 
            vec.append(round(random.uniform(0, 1), 2)) 
      
        vectors.append({
            "_index": index_name,
            "_id": i,
            "values": vec,
        })
    
    helpers.bulk(client, vectors)
    
    client.indices.refresh(index=index_name)
  12. Use Kerberos Authentication

    main

    To use Kerberos authentication, you can use third-party Python packages like requests-kerberos or requests-gssapi. Pass the appropriate authentication object to the http_auth parameter. Note that parameters like mutual_authentication may need to be adjusted based on your specific server configuration.

    from opensearchpy import OpenSearch, RequestsHttpConnection
    from requests_kerberos import HTTPKerberosAuth, OPTIONAL
    
    client = OpenSearch(
        ['https://...'],
        use_ssl=True,
        verify_certs=True,
        http_auth=HTTPKerberosAuth(mutual_authentication=OPTIONAL)
    )
    
    health = client.cluster.health()