{"id":169,"library":"opensearch-py","title":"OpenSearch Python Client","description":"Official Python client for OpenSearch — AWS's Apache 2.0 fork of Elasticsearch 7.10. Current version: 3.1.0 (Mar 2026). API is nearly identical to elasticsearch-py v7 but NOT interchangeable — different package, different import. OpenSearch 1.x deprecated May 2025. v3.0 client released alongside OpenSearch 3.0. Major footgun: developers import elasticsearch instead of opensearch_py by mistake. Also compatible with Amazon OpenSearch Service (AWS managed).","status":"active","version":"3.1.0","language":"python","source_language":"en","source_url":"https://github.com/opensearch-project/opensearch-py","tags":["opensearch","python","search","aws","elasticsearch-fork"],"install":[{"cmd":"pip install opensearch-py","lang":"bash","label":"Python (sync + async)"}],"dependencies":[{"reason":"Required. Installed automatically.","package":"urllib3","optional":false}],"imports":[{"note":"Import is 'from opensearchpy import OpenSearch' — not 'from elasticsearch import Elasticsearch'. Despite near-identical APIs, they are different packages with different auth and SSL handling.","wrong":"from elasticsearch import Elasticsearch  # wrong package\nclient = Elasticsearch(hosts=['localhost:9200'])\n# opensearch-py and elasticsearch-py are different packages","symbol":"OpenSearch","correct":"from opensearchpy import OpenSearch\n\nclient = OpenSearch(\n    hosts=[{'host': 'localhost', 'port': 9200}],\n    http_auth=('admin', 'admin'),\n    use_ssl=True,\n    verify_certs=False,  # dev only\n    ssl_show_warn=False\n)\n\n# Index — same pattern as elasticsearch-py v7\nclient.index(\n    index='my-index',\n    body={'name': 'Alice', 'age': 30},\n    id='1'\n)\n\n# Search\nresp = client.search(\n    index='my-index',\n    body={'query': {'match': {'name': 'Alice'}}}\n)"},{"note":"AsyncOpenSearch is the async counterpart — same API as sync but all methods are coroutines. Must call await client.close() to prevent connection leaks.","wrong":"","symbol":"AsyncOpenSearch","correct":"from opensearchpy import AsyncOpenSearch\nimport asyncio\n\nasync def main():\n    client = AsyncOpenSearch(\n        hosts=[{'host': 'localhost', 'port': 9200}],\n        http_auth=('admin', 'admin'),\n        use_ssl=False\n    )\n    resp = await client.search(\n        index='my-index',\n        body={'query': {'match_all': {}}}\n    )\n    await client.close()\n\nasyncio.run(main())"}],"quickstart":{"code":"# pip install opensearch-py\nfrom opensearchpy import OpenSearch\n\nclient = OpenSearch(\n    hosts=[{'host': 'localhost', 'port': 9200}],\n    http_auth=('admin', 'admin'),\n    use_ssl=False\n)\n\n# Create index\nclient.indices.create(\n    index='products',\n    body={\n        'mappings': {\n            'properties': {\n                'name': {'type': 'text'},\n                'price': {'type': 'float'}\n            }\n        }\n    }\n)\n\n# Index document\nclient.index(index='products', id='1', body={'name': 'Widget', 'price': 9.99})\n\n# Search\nresp = client.search(\n    index='products',\n    body={'query': {'match': {'name': 'Widget'}}}\n)\nfor hit in resp['hits']['hits']:\n    print(hit['_source'])","lang":"python","description":"Minimal opensearch-py connection and CRUD."},"warnings":[{"fix":"pip install opensearch-py; from opensearchpy import OpenSearch","message":"Package name is 'opensearch-py' but import is 'from opensearchpy import OpenSearch' (no hyphen). pip install opensearch-py; import opensearchpy.","severity":"breaking","affected_versions":"all"},{"fix":"Use opensearch-py for OpenSearch/Amazon OpenSearch Service. Use elasticsearch for Elasticsearch.","message":"opensearch-py and elasticsearch-py have near-identical APIs but are NOT interchangeable. Different packages, different auth patterns, different SSL defaults. Cannot swap imports.","severity":"gotcha","affected_versions":"all"},{"fix":"from requests_aws4auth import AWS4Auth; client = OpenSearch(http_auth=AWS4Auth(...))","message":"Amazon OpenSearch Service (AWS managed) requires AWS SigV4 auth — not basic_auth. Use opensearch-py with requests-aws4auth or boto3 credentials.","severity":"gotcha","affected_versions":"all"},{"fix":"Target OpenSearch 2.x or 3.x for new projects.","message":"OpenSearch 1.x deprecated May 2025. Amazon OpenSearch Service still supports 1.x and 2.x but new projects should target 2.x+.","severity":"gotcha","affected_versions":"all"},{"fix":"client.search(index='my-index', body={'query': {...}}) — body= is correct for opensearch-py.","message":"Unlike elasticsearch-py v8+, opensearch-py still uses the body= parameter pattern (elasticsearch v7 style). Don't apply elasticsearch v8 named-param migration to opensearch-py.","severity":"gotcha","affected_versions":"all"},{"fix":"Verify that your OpenSearch instance is running and listening on the correct host and port. Check network connectivity, host address, port number, and any firewall rules that might be blocking the connection from the client to the OpenSearch server.","message":"ConnectionRefusedError: OpenSearch client failed to connect to the server. This indicates that the OpenSearch instance is not running, is not accessible at the specified host/port, or a firewall is blocking the connection.","severity":"breaking","affected_versions":"all"},{"fix":"Verify that the OpenSearch service is running on the specified host and port. Check your client configuration for the correct host and port. Ensure no firewall rules or network configurations are blocking the connection.","message":"Connection refused: The OpenSearch service is not running or is not accessible at the specified host and port (e.g., `localhost:9200`). Ensure the OpenSearch cluster is running and network accessible from where the client is executed.","severity":"breaking","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T09:13:47.138Z","next_check":"2026-06-24T00:00:00.000Z","problems":[{"fix":"Install the library using `pip install opensearch-py` and ensure the import statement is `from opensearchpy import OpenSearch`.","cause":"The `opensearch-py` library is either not installed in your environment, or the import statement uses an incorrect module name.","error":"ModuleNotFoundError: No module named 'opensearchpy'"},{"fix":"Verify that the OpenSearch cluster is running and accessible from where the client code is executed. Double-check the `host` and `port` parameters in the `OpenSearch` client constructor.","cause":"The Python client cannot establish a connection to the OpenSearch cluster, often due to the cluster being down, incorrect host/port in the client configuration, or network/firewall issues.","error":"ConnectionError: ConnectionError(...) caused by: NewConnectionError(...): Failed to establish a new connection: [Errno 111] Connection refused"},{"fix":"Provide valid `http_auth` credentials or properly configure `AWSV4SignerAuth` when connecting to a secured OpenSearch cluster or Amazon OpenSearch Service.","cause":"The client attempted to connect to OpenSearch with invalid or insufficient authentication credentials (e.g., incorrect username/password, missing IAM role, or incorrect AWSV4SignerAuth configuration).","error":"AuthenticationException(401, 'Unauthorized', 'Unauthorized')"},{"fix":"Ensure that the `host` parameter in the `OpenSearch` client constructor does not end with a trailing slash.","cause":"The client is sending a malformed request, often due to an extra slash at the end of the host URL in the `OpenSearch` client configuration, leading to an incorrect URI being constructed.","error":"RequestError(400, 'no handler found for uri ...')"},{"fix":"Update method calls to use keyword arguments, for example, change `client.indices.refresh(index_name)` to `client.indices.refresh(index=index_name)`.","cause":"The `IndicesClient.refresh()` method (and potentially others) in `opensearch-py` version 3.0.0 and later requires keyword arguments, but it is being called with positional arguments.","error":"TypeError: IndicesClient.refresh() takes 1 positional argument but 2 positional arguments (and 2 keyword-only arguments) were given"}],"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.78,"mem_mb":15.3,"disk_size":"49.3M"},{"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.55,"mem_mb":15.3,"disk_size":"47M"},{"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.02,"mem_mb":17.3,"disk_size":"52.7M"},{"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":0.82,"mem_mb":17.3,"disk_size":"51M"},{"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.13,"mem_mb":17.3,"disk_size":"44.3M"},{"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.12,"mem_mb":17.3,"disk_size":"42M"},{"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.13,"mem_mb":18.2,"disk_size":"43.8M"},{"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.08,"mem_mb":18.1,"disk_size":"42M"},{"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.68,"mem_mb":15.2,"disk_size":"25.9M"},{"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.59,"mem_mb":15.2,"disk_size":"26M"}]},"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}]}}