jshen
jshen

Reputation: 11907

How do I use pymongo from an Azure function to connect to Cosmos DB

I'd like to create an azure function with an HTTP trigger, then use pymongo to interact with a Cosmos DB database. This works fine when I run it on my local computer, but fails when running from azure. I'm guessing that I need to grant cosmos db access to the function app, but I have no idea how to do that.

import logging

import azure.functions as func

import pymongo

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
    else:
        uri = "uri provided by cosmos"
        client = pymongo.MongoClient(uri)

        db = client.test
        collection = db.test
        o = collection.find_one()
        return func.HttpResponse(
             f"name is {o['name']}",
             status_code=200
        )

And here is the error

Exception while executing function: Functions.ycwn Result: Failure
Exception: ServerSelectionTimeoutError: connection closed
Stack:   File "/azure-functions-host/workers/python/3.7/LINUX/X64/azure_functions_worker/dispatcher.py", line 315, in _handle__invocation_request
    self.__run_sync_func, invocation_id, fi.func, args)
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/azure-functions-host/workers/python/3.7/LINUX/X64/azure_functions_worker/dispatcher.py", line 434, in __run_sync_func
    return func(**params)
  File "/home/site/wwwroot/ycwn/__init__.py", line 27, in main
    o = collection.find_one()
  File "/home/site/wwwroot/.python_packages/lib/site-packages/pymongo/collection.py", line 1273, in find_one
    for result in cursor.limit(-1):
  File "/home/site/wwwroot/.python_packages/lib/site-packages/pymongo/cursor.py", line 1156, in next
    if len(self.__data) or self._refresh():
  File "/home/site/wwwroot/.python_packages/lib/site-packages/pymongo/cursor.py", line 1050, in _refresh
    self.__session = self.__collection.database.client._ensure_session()
  File "/home/site/wwwroot/.python_packages/lib/site-packages/pymongo/mongo_client.py", line 1810, in _ensure_session
    return self.__start_session(True, causal_consistency=False)
  File "/home/site/wwwroot/.python_packages/lib/site-packages/pymongo/mongo_client.py", line 1763, in __start_session
    server_session = self._get_server_session()
  File "/home/site/wwwroot/.python_packages/lib/site-packages/pymongo/mongo_client.py", line 1796, in _get_server_session
    return self._topology.get_server_session()
  File "/home/site/wwwroot/.python_packages/lib/site-packages/pymongo/topology.py", line 490, in get_server_session
    None)
  File "/home/site/wwwroot/.python_packages/lib/site-packages/pymongo/topology.py", line 209, in _select_servers_loop
    self._error_message(selector))

Upvotes: 1

Views: 1483

Answers (1)

jshen
jshen

Reputation: 11907

Figured this out. I needed to check "Allow connections from within public Azure datacenters".

cosmosdb setting

Upvotes: 1

Related Questions