Python connection issues with Mongo in Streamlit app

Hello! I’m having some issue with connecting my Streamlit-based app to my MongoDb database.

So what I tried so far:

  1. Tried certification with Certifi
  2. Fixed password by fixing special character encoding
  3. Added IP to list of alllowed IPs
  4. Downloaded Mongo Compass and verified my URI is correct and I can for example add a new document.

I spent some time on debugging and I think following example can give some clue:

import streamlit as st
import pymongo
import certifi

{connection_uri}

@st.cache_resource
def init_connection():
    return pymongo.MongoClient(uri, tlsCAFile=certifi.where())

client = init_connection()
db = client.langgym
items = db.sample_mflix.find()

st.write(items)

This does not fail (I’m shown with <pymongo.cursor.Cursor object at 0x000002BAB9F76120> message). But when I change the last line to:

st.write(list(items))

I get the error:

OperationFailure: bad auth : authentication failed, full error: {'ok': 0, 'errmsg': 'bad auth : authentication failed', 'code': 8000, 'codeName': 'AtlasError'}

Hi @mooorek - welcome to the community forums!

Great post - it’s really helpful that you’ve listed the things you’ve tried so far.

First I’m going to explain (some of) what’s going on, because it’s a common point of confusion. MongoClient only connects to your MongoDB cluster when you either write to a collection, or when you start looping through a cursor. This lazy behaviour means that sometimes a problem with your connection string shows up in the wrong place in your code:

client = pymongo.MongoClient(uri)          # Does nothing
database = client.get_database('mydb')     # Does nothing
collection = client.get_collection('coll') # Does nothing
cursor = collection.find()                 # Does nothing (returns a Cursor that wraps your query)!
results = list(cursor)                     # FINALLY connects to your cluster and executes the query (because it loops through the cursor to create the list)!

I think what st.write(items) is doing is that, because Streamlit doesn’t know what a Cursor object is, unlike a Dataframe or similar, it calls repr on the Cursor, which is why you see <pymongo.Cursor object ...> in Streamlit - it’s just a string. But in this whole code example, you’ve never connected to MongoDB. The Cursor is just a lazy object that has never been executed.

So that explains why your main block of code “works,” but it doesn’t when you wrap the Cursor with list. Phew.

What I’m left with is, unfortunately, that your username or password in the connection URI is almost certainly incorrect. That’s what the error means. I suspect it’s related to how the password has been encoded, and there may be a subtle difference to the way Compass (written in JavaScript) decodes URIs compared with Python/PyMongo.

At this point, what I would try would be to modify your user details in Atlas, and either enter an alpha-numeric password manually, or use the “random password” feature that will generate a password that doesn’t need any URL encoding.

Let me know how you get on!

1 Like

Hey @Mark_Smith - thanks a lot for so useful explanation, I had this intuition about lazy behavior, but thanks for wording that out, it will help me to communicate such issues in future better :slight_smile:

Actually it works now, so thanks a lot! So basically getting safe, but alphanumeric only password was the key here. Other thing I just realized is that I did a very newbie thing and messed up the app, database and collection names. What I was trying to do was:

  • connect to my Langgym database and sample_mflix collection

while what I should have done is:

  • connect to the Langgym app (as per URI), sample_mflix database and for example comments collection.

Turns out I messed some terms up, but eventually your post inspired me to double check that so thanks a bunch! Maybe this could serve as some useful example for entry, self-learning people for some docs.

Now I see in Streamlit I see correct outputs and am ready to explore the MongoDB in practice. Thank you once again for super quick response and have a good day :slight_smile:

Fantastic! Glad I could help :slight_smile:

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