Connecting to Atlas with pymongo v4.0.2

Hello folks,

I have a cluster to which I have no clue how to connect using Python. I want to mention right at the outset that I HAVE added my IP to the whitelist.

My cluster is a UUID based cluster: cdf46a6c-6797-40e1-a655-96b6b5291e2b

Previously when I had tried to connect to this cluster using mongo shell v4.2, I had gotten this URL to connect to from the Atlas “Connect” section, AND IT WORKS:

OLD STRING
mongo "mongodb+srv://<username>:<password>@cdf46a6c-6797-40e1-a655.35m0c.mongodb.net"

Now when I go to the Atlas interface to get my connection string, it gives me this command:

NEW STRING
mongo "mongodb+srv://<username>:<password>@cdf46a6c-6797-40e1-a655-**pri.**35m0c.mongodb.net"

Notice the extra “pri”??

In short, I’m wondering which connection string am I supposed to rely on? If I use connection string OLD STRING, both mongo shell and Python program works. If I use NEW STRING, I see the following errors:

Traceback (most recent call last):
  File "mongo.py", line 40, in <module>
    my_driver = initialise_mongo_client()
  File "mongo.py", line 37, in initialise_mongo_client
    print(client.get_database('abs_data').list_collection_names())
  File "/usr/local/lib64/python3.6/site-packages/pymongo/database.py", line 880, in list_collection_names
    for result in self.list_collections(session=session, **kwargs)]
  File "/usr/local/lib64/python3.6/site-packages/pymongo/database.py", line 843, in list_collections
    _cmd, read_pref, session)
  File "/usr/local/lib64/python3.6/site-packages/pymongo/mongo_client.py", line 1515, in _retryable_read
    read_pref, session, address=address)
  File "/usr/local/lib64/python3.6/site-packages/pymongo/mongo_client.py", line 1346, in _select_server
    server = topology.select_server(server_selector)
  File "/usr/local/lib64/python3.6/site-packages/pymongo/topology.py", line 246, in select_server
    address))
  File "/usr/local/lib64/python3.6/site-packages/pymongo/topology.py", line 203, in select_servers
    selector, server_timeout, address)
  File "/usr/local/lib64/python3.6/site-packages/pymongo/topology.py", line 220, in _select_servers_loop
    (self._error_message(selector), timeout, self.description))
pymongo.errors.ServerSelectionTimeoutError: cdf46a6c-6797-40e1-a655-shard-00-01-pri.35m0c.mongodb.net:27017: timed out,cdf46a6c-6797-40e1-a655-shard-00-00-pri.35m0c.mongodb.net:27017: timed out,cdf46a6c-6797-40e1-a655-shard-00-02-pri.35m0c.mongodb.net:27017: timed out, Timeout: 30s, Topology Description: <TopologyDescription id: 6234ce37bc72a6a821d90859, topology_type: ReplicaSetNoPrimary, servers: [<ServerDescription ('cdf46a6c-6797-40e1-a655-shard-00-00-pri.35m0c.mongodb.net', 27017) server_type: Unknown, rtt: None, error=NetworkTimeout('cdf46a6c-6797-40e1-a655-shard-00-00-pri.35m0c.mongodb.net:27017: timed out',)>, <ServerDescription ('cdf46a6c-6797-40e1-a655-shard-00-01-pri.35m0c.mongodb.net', 27017) server_type: Unknown, rtt: None, error=NetworkTimeout('cdf46a6c-6797-40e1-a655-shard-00-01-pri.35m0c.mongodb.net:27017: timed out',)>, <ServerDescription ('cdf46a6c-6797-40e1-a655-shard-00-02-pri.35m0c.mongodb.net', 27017) server_type: Unknown, rtt: None, error=NetworkTimeout('cdf46a6c-6797-40e1-a655-shard-00-02-pri.35m0c.mongodb.net:27017: timed out',)>]>

Somebody please help!

Here’s the python code I’m using for reference:

def initialise_mongo_client() -> pymongo.MongoClient:
    atlas_password = '<thepassword>'
    atlas_user = '<theuser>'
    #bad_atlas_uri = "mongodb+srv://cdf46a6c-6797-40e1-a655.35m0c.mongodb.net"
    #good_atlas_uri = "mongodb+srv://%s:%s@cdf46a6c-6797-40e1-a655.35m0c.mongodb.net" % (quote_plus(atlas_user), quote_plus(atlas_password))
    atlas_uri = "mongodb+srv://%s:%s@cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net/admin?retryWrites=true&w=majority" % (quote_plus(atlas_user), quote_plus(atlas_password))
    print(atlas_uri)
    client = pymongo.MongoClient(atlas_uri, tls=True, tlsAllowInvalidCertificates=True)
    #client = pymongo.MongoClient(atlas_uri, username=quote_plus(atlas_user), password=quote_plus(atlas_password),
    #                             tls=True, tlsAllowInvalidCertificates=True, authSource='admin')
    # client = pymongo.MongoClient(uri)

    print(client.get_database('abs_data').list_collection_names())
    return client

my_driver = initialise_mongo_client()

What has changed from the time it was working?
What is your cluster type?(M0,M5 etc).Asking this because pri in your string may referring to private end point?
Can you ping cdf46a6c-6797-40e1-a655-**pri.**35m0c.mongodb.net
Network error indicates it may not be the correct hostname
From Atlas get connect string did you use connect by shell or connect by app?

I am not sure what has changed. I am pretty sure I got both connection URLs from Atlas, so is Atlas somehow giving me the wrong URL?

My cluster is M40.

The surprising thing is, the Java driver works OK and connects using mongodb+srv://cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net. I am providing only basic connection parameters like username, password, SSL etc and no extra/different options to the Java driver, compared to the Python driver.

The Python driver fails to connect with mongodb+srv://cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net but it works well with cdf46a6c-6797-40e1-a655.35m0c.mongodb.net

Ping doesn’t work for either of the hostnames, see below:

msrao@msrao-r ~ [68]> ping cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net
ping: cannot resolve cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net: Unknown host
msrao@msrao-r ~ [68]> ping cdf46a6c-6797-40e1-a655.35m0c.mongodb.net
ping: cannot resolve cdf46a6c-6797-40e1-a655.35m0c.mongodb.net: Unknown host
msrao@msrao-r ~ [68]>

From Atlas interface, I have tried getting the connect string for mongo shell (mongosh and mongo older), Java Driver and Python driver. All of them return the URL with ‘pri’ in it.

Open questions

  1. Which is the right host to connect to, the one with pri or the one without?
  2. Why can Java driver connect to the host with ‘pri’ in it but Python driver cannot?

Hi @Muralidhar_Rao,

Welcome to the community.

Notice the extra “pri”??

The extra “pri” noted in your URI is associated with the private IP addresses of the Atlas nodes of that cluster which should be reachable within the peered network.

For demonstration purposes, using the two URI’s provided, you will see that that the hostnames resolved from the SRV record differ slightly with the additional “pri”:

/// Using dig to resolve the "pri" SRV record:
dig srv _mongodb._tcp.cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net

/// The answer section which includes the hostnames associated with the Private IP of the nodes within the cluster. Note the additional "pri" in these as well
;; ANSWER SECTION:
_mongodb._tcp.cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net. 60	IN SRV 0 0 27017 cdf46a6c-6797-40e1-a655-shard-00-00-pri.35m0c.mongodb.net.
_mongodb._tcp.cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net. 60	IN SRV 0 0 27017 cdf46a6c-6797-40e1-a655-shard-00-01-pri.35m0c.mongodb.net.
_mongodb._tcp.cdf46a6c-6797-40e1-a655-pri.35m0c.mongodb.net. 60	IN SRV 0 0 27017 cdf46a6c-6797-40e1-a655-shard-00-02-pri.35m0c.mongodb.net.
/// Using dig to resolve the non-"pri" SRV record:
dig srv _mongodb._tcp.cdf46a6c-6797-40e1-a655.35m0c.mongodb.net

/// The answer section which includes hostnames associated with the public IP of the nodes within the cluster. Note, there is no "pri" in these hostnames.
;; ANSWER SECTION:
_mongodb._tcp.cdf46a6c-6797-40e1-a655.35m0c.mongodb.net. 60 IN SRV 0 0 27017 cdf46a6c-6797-40e1-a655-shard-00-00.35m0c.mongodb.net.
_mongodb._tcp.cdf46a6c-6797-40e1-a655.35m0c.mongodb.net. 60 IN SRV 0 0 27017 cdf46a6c-6797-40e1-a655-shard-00-01.35m0c.mongodb.net.
_mongodb._tcp.cdf46a6c-6797-40e1-a655.35m0c.mongodb.net. 60 IN SRV 0 0 27017 cdf46a6c-6797-40e1-a655-shard-00-02.35m0c.mongodb.net.

You can read more information regarding the above here on the FAQ: Connection String Options documentation.

Ping doesn’t work for either of the hostnames, see below:

From the above dig results, the ping command and output did not succeed as you have attempted to ping the SRV record and not the hostnames. In the below ping example, the hostnames used were obtained from the dig outputs above.

From the python client that is failing to connect, please run the following commands and provide the output of each:

ping cdf46a6c-6797-40e1-a655-shard-00-00-pri.35m0c.mongodb.net
ping cdf46a6c-6797-40e1-a655-shard-00-00.35m0c.mongodb.net

I am not sure what has changed. I am pretty sure I got both connection URLs from Atlas, so is Atlas somehow giving me the wrong URL?

This is also detailed in the FAQ: Connection String Options documentation mentioned above, but the two strings you’ve obtained are from either of the following options when going through the connect modal:

  1. Which is the right host to connect to, the one with pri or the one without?

Generally, if you’re wanting to connect over the VPC peering connection, you should use the Private IP for Peering connection string. Otherwise, if you’re wanting to connect over the public internet to that specific cluster, you can use the standard connection string.

  1. Why can Java driver connect to the host with ‘pri’ in it but Python driver cannot?

Is the client performing this connection using the Java driver the same client as the one attempting connection using the python driver?

Regards,
Jason

3 Likes

Thanks for the reply Jason!

I was using the VPC peered URI for a standard connection. Once I used the right URI for the right client, everything worked fine.

2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.