python-3.xamazon-web-serviceselasticsearchopensearch

opensearch-py not accepting connection with AWS signer on async client


In the past, opensearch-py does not support signing AWS requests with AsyncOpenSearch client, but it seems to have been fixed in V2.01. Unfortunately, I still am unable to sign request using AsyncOpenSearch. I am using version 2.31. Here is my code:

from opensearchpy import AsyncOpenSearch, RequestsHttpConnection
from requests_aws4auth import AWS4Auth

auth =  AWS4Auth(aws_access_key, aws_secret_key, aws_region, "es")
es_client = AsyncOpenSearch(host, http_auth = auth, connection_class = RequestsHttpConnection, timeout=120)

asyncio.run(es_client.info())

Running this code gave me the following error.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\lightning_missile\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\lightning_missile\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lightning_missile\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\lightning_missile\AppData\Local\Programs\Python\Python311\Lib\site-packages\opensearchpy\_async\client\__init__.py", line 252, in info
    return await self.transport.perform_request(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\lightning_missile\AppData\Local\Programs\Python\Python311\Lib\site-packages\opensearchpy\_async\transport.py", line 374, in perform_request
    status, headers_response, data = await connection.perform_request(
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: object tuple can't be used in 'await' expression

I do not know what I am doing wrong and I cannot find anything in the docs that explain how to sign request in AsyncOpenSearch client. Can anyone help me?


Solution

  • Got it. It seems you need boto3 installed because you need an async version of AWSV4SignerAuth which needs boto3 credential objects.

    import boto3
    from opensearchpy import AsyncOpenSearch, AsyncHttpConnection, AWSV4SignerAsyncAuth
    
    credentials = boto3.Session(aws_access_key_id=aws_access_key, aws_secret_key_id=aws_secret_key).get_credentials()
    
    auth = AWSV4SignerAsyncAuth(credentials, region)
    es_client = AsyncOpenSearch(host, http_auth = auth, connection_class = AsyncHttpConnection, timeout=120)
    
    asyncio.run(es_client.info())
    

    This is enough for me, but if there is a better solution, feel free to comment or add another answer.