MongoDB Atlas authentication failed on Python - python

I have deployed this Python app on Heroku and i want it to connect to a MongoDB Atlas cluster. I used my string to connect to the cluster, but for some reason i keep getting raise OperationFailure(msg % errmsg, code, response)
pymongo.errors.OperationFailure: bad auth Authentication failed. I checked twice and both the user and the password are correct. Any idea on why this is happening?
from pymongo import MongoClient
import time
import random
import time
import datetime
client = MongoClient('mongodb+srv://USER:<MYPASSWORD>#test-2liju.mongodb.net/test?retryWrites=true')
db = client.one
mycol = client["tst"]
while True:
test = int(random.randrange(-99999990,90000000,1))
dic = {"num": test}
result = db.tst.insert_one(dic)
print(test)
time.sleep(5)

Stupid error, i had to type MYPASSWORD instead of <MYPASSWORD>, without the <>

Don't use any special char in password, like '+' or '='.
I use OpenSSL to generate a password like u4wY9AOwnOLMY+h9EQ==. Came across bad auth Authentication failed.
After using MongoDB Compass it told me don't use special char, so I remove those and use like 'u4wY9AOwnOLMYh9EQ'.
Then it works.

check the compatibility of the version of the Python driver you choose from the Mongodb Atlas Connections. versions above 3.4 are not supported by mongoengine flask

Related

AWS RDS Proxy error (postgres) - RDS Proxy currently doesn’t support command-line options

I try to read or write from/to an AWS RDS Proxy with a postgres RDS as the endpoint.
The operation works with psql but fails on the same client with pg8000 or psycopg2 as client libraries in Python.
The operation works with with pg8000 and psycopg2 if I use the RDS directly as endpoint (without the RDS proxy).
sqlaclchemy/psycopg2 error message:
Feature not supported: RDS Proxy currently doesn’t support command-line options.
A minimal version of the code I use:
from sqlalchemy import create_engine
import os
from dotenv import load_dotenv
load_dotenv()
login_string = os.environ['login_string_proxy']
engine = create_engine(login_string, client_encoding="utf8", echo=True, connect_args={'options': '-csearch_path={}'.format("testing")})
engine.execute(f"INSERT INTO testing.mytable (product) VALUES ('123')")
pg8000: the place it stops / waits for something is in core.py:
def sock_read(b):
try:
return self._sock.read(b)
except OSError as e:
raise InterfaceError("network error on read") from e
A minimal version of the code I use:
import pg8000
import os
from dotenv import load_dotenv
load_dotenv()
db_connection = pg8000.connect(database=os.environ['database'], host=os.environ['host'], port=os.environ['port'], user=os.environ['user'], password=os.environ['password'])
db_connection.run(f"INSERT INTO mytable (data) VALUES ('data')")
db_connection.commit()
db_connection.close()
The logs in the RDS Proxy looks always normal for all the examples I mentioned - e.g.:
A new client connected from ...:60614.
Received Startup Message: [username="", database="", protocolMajorVersion=3, protocolMinorVersion=0, sslEnabled=false]
Proxy authentication with PostgreSQL native password authentication succeeded for user "" with TLS off.
A TCP connection was established from the proxy at ...:42795 to the database at ...:5432.
The new database connection successfully authenticated with TLS off.
I opened up all ports via security groups on the RDS and the RDS proxy and I used an EC2 inside the VPC.
I tried with autocommit on and off.
The 'command-line option" being referred to is the -csearch_path={}.
Remove that, and then once the connection is established execute set search_path = whatever as your first query.
This is a known issue that pg8000 can't connect to AWS RDS proxy (postgres). I did a PR https://github.com/tlocke/pg8000/pull/72 let see if Tony Locke (the father of pg8000) approves the change. ( if not you have to change the lines of the core.py https://github.com/tlocke/pg8000/pull/72/files )
self._write(FLUSH_MSG)
if (code != PASSWORD):
self._write(FLUSH_MSG)

PyMongo's insert_one() method not working using PyCharm IDE

I'm trying to use mongodb but for some reason i cant put data into a collection.
Here's my code:
import pymongo
from pymongo import MongoClient
mongo_url = "mongodb+srv://<User>:<Password>#cluster0.yozx6.mongodb.net/<dbname>?retryWrites=true&w=majority"
cluster = MongoClient(mongo_url)
db = cluster["TestDatabse"]
collection = db["TestCollection"]
post = {"number": 7}
collection.insert_one(post)
for some reason the data the collection.insert_one line isn't working and it isn't giving an error message either. The program seems to get stuck on it. Can somebody please tell me what I'm doing wrong and how I can fix it.
There are different things to verify for you.
Version compatibility:
First of all insertOne was introduced inmongoDB 3.2, so make sure that you are connecting to a newer pymongo version, and also that the version of pymongo is compatible with your version
Network connection:
Make sure you have a stable connection to your DB if it is remote.
Then use:
result = cluster.admin.command("ismaster")
to check if the db is accesible, if this throws a ConnectionError there is a problem with the connection.
User permissions
Check if the user and password you are using has permissions to insert documents to the given collection.
On the mongo shell:
db.getRoles(
{
rolesInfo: 1,
showPrivileges:true,
showBuiltinRoles: true
}
)
should show:
roles: [
{
role: "readWrite",
db: "TestDatabse"
}
]
for the user User.
Result of insert
Check the result. insert_one returns inserted_id and acknowledged.
res = collection.insert_one(post)
res.acknowledged # should be True
res.inserted_id
Logs
Check your logs, you can find the log path for your server by running:
cat /etc/mongod.conf | grep log

Configuring sqlalchemy engine with user containing ":"

I am trying to configure an engine in sqlalchemy to connect with temporary credentials from an AWS IAM role using get_cluster_credentials api.
When I do so this is the user I get 'IAM:user_rw'. Problem comes when I configure the engine string as
engine_string = "postgresql+pygresql://{user}:{password}#{endpoint}:{port}/{dbname}".format(
user=cluster_creds['DbUser'],
password=cluster_creds['DbPassword'],
endpoint='big endpointstring',
port=8192,
dbname='small dbname')
I create the engine without errors but when running any query I get: FATAL: password authentication failed for user "IAM"
Tested the user and pass in DataGrip it works so it seems evident sqlalchemy is getting the user just as "IAM" instead of 'IAM:user_rw'.
Do you know how can I force sqlalchemy to get the correct user?
I managed to solve the issue using urllib parse_quote in a similar fashion to what Gord is pointing. Final code
from urllib.parse import quote_plus
engine_string = "postgresql+pygresql://%s:%s#%s:%d/%s" % (
quote_plus(user),
quote_plus(passw),
endpoint,
port,
dbname,
)

ServerSelectionTimeoutError errno 11001 getaddrinfo failed python

mongodb_uri = "mongodb://[username:password#]XX.XX.XX.XX"
client = MongoClient(mongodb_uri)
db = client['database']
print(db)
collection_taxonomy = db['collection']
doc = collection_taxonomy.find()
pprint.pprint(doc)
for each_doc in doc:
pprint.pprint(each_doc)
I am getting time out error as I try to print each document of the collection. However, I do not get time out error when I try to connect to localhost.
Tried connecting with connect=False
client = MongoClient(mongodb_uri,connect=False)
Still I get time out error while i print each document.
What could be wrong? Appreciate if someone can help me .
I am using Python 3.5 and Pymongo 3.5.1
Thanks,
-Roopa
is "mongodb://[username:password#]XX.XX.XX.XX" the actual value of mongodb_uri or have you substituted that for the value in your actual application?
The "getaddrinfo failed" message indicates that the hostname you put in mongodb_uri is invalid.
Removed square brackets([]) after substituting values in actual application.
"mongodb://username:password#XX.XX.XX.XX"
Works like a charm.!
Thanks a ton.
Roopa
I got the same error when i had a restricted rights on the user account which was trying to connect, so please try changing the user access rights or use a different account with higher privileges
user with the below rights failed
readWrite#dbname.colname
user with the below rights worked (note this is the user created for Atlas application)
atlasAdmin#admin
The URI should be like "mongodb://username:password#host", where the host is the hostname or IP.
This happened to me when I was connecting with the name, but the host name changed, so I changed the URI to connect via the machine's IP.

Basic authentication with jira-python

I'm new to Python, new to the jira-python library, and new to network programming, though I do have quite a bit of experience with application and integration programming and database queries (though it's been a while).
Using Python 2.7 and requests 1.0.3
I'm trying to use this library - http://jira-python.readthedocs.org/en/latest/ to query Jira 5.1 using Python. I successfully connected using an unauthenticated query, though I had to make a change to a line in client.py, changing
I changed
self._session = requests.session(verify=verify, hooks={'args': self._add_content_type})
to
self._session = requests.session()
I didn't know what I was doing exactly but before the change I got an error and after the change I got a successful list of project names returned.
Then I tried basic authentication so I can take advantage of my Jira permissions and do reporting. That failed initially too. And I made the same change to
def _create_http_basic_session
in client.py , but now I just get another error. So problem not solved. Now I get a different error:
HTTP Status 415 - Unsupported Media Type
type Status report
message Unsupported Media Type
description The server refused this request because the request entity is in
a format not` `supported by the requested resource for the requested method
(Unsupported Media Type).
So then I decided to do a super simple test just using the requests module, which I believe is being used by the jira-python module and this code seemed to log me in. I got a good response:
import requests
r = requests.get(the_url, auth=(my username , password))
print r.text
Any suggestions?
Here's how I use the jira module with authentication in a Python script:
from jira.client import JIRA
import logging
# Defines a function for connecting to Jira
def connect_jira(log, jira_server, jira_user, jira_password):
'''
Connect to JIRA. Return None on error
'''
try:
log.info("Connecting to JIRA: %s" % jira_server)
jira_options = {'server': jira_server}
jira = JIRA(options=jira_options, basic_auth=(jira_user, jira_password))
# ^--- Note the tuple
return jira
except Exception,e:
log.error("Failed to connect to JIRA: %s" % e)
return None
# create logger
log = logging.getLogger(__name__)
# NOTE: You put your login details in the function call connect_jira(..) below!
# create a connection object, jc
jc = connect_jira(log, "https://myjira.mydom.com", "myusername", "mypassword")
# print names of all projects
projects = jc.projects()
for v in projects:
print v
Below Python script connects to Jira and does basic authentication and lists all projects.
from jira.client import JIRA
options = {'server': 'Jira-URL'}
jira = JIRA(options, basic_auth=('username', 'password'))
projects = jira.projects()
for v in projects:
print v
It prints a list of all the project's available within your instance of Jira.
Problem:
As of June 2019, Atlassian Cloud users who are using a REST endpoint in Jira or Confluence Cloud with basic or cookie-based authentication will need to update their app or integration processes to use an API token, OAuth, or Atlassian Connect.
After June 5th, 2019 attempts to authenticate via basic auth with an Atlassian account password will return an invalid credentials error.
Reference: Deprecation of basic authentication with passwords for Jira and Confluence APIs
Solution to the Above-mentioned Problem:
You can use an API token to authenticate a script or other process with an Atlassian cloud product. You generate the token from your Atlassian account, then copy and paste it to the script.
If you use two-step verification to authenticate, your script will need to use a REST API token to authenticate.
Steps to Create an API Token from your Atlassian Account:
Log in to https://id.atlassian.com/manage/api-tokens
Click Create API token.
From the dialog that appears, enter a memorable and concise Label for your token and click Create.
Click Copy to clipboard, then paste the token to your script.
Reference: API tokens
Python 3.8 Code Reference
from jira.client import JIRA
jira_client = JIRA(options={'server': JIRA_URL}, basic_auth=(JIRA_USERNAME, JIRA_TOKEN))
issue = jira_client.issue('PLAT-8742')
print(issue.fields.summary)
Don't change the library, instead put your credentials inside the ~/.netrc file.
If you put them there you will also be able to test your calls using curl or wget.
I am not sure anymore about compatibility with Jira 5.x, only 7.x and 6.4 are currently tested. If you setup an instance for testing I could modify the integration tests to run against it, too.
My lucky guess is that you broke it with that change.
As of 2019 Atlassian has deprecated authorizing with passwords.
You can easily replace the password with an API Token created here.
Here's a minimalistic example:
pip install jira
from jira import JIRA
jira = JIRA("YOUR-JIRA-URL", basic_auth=("YOUR-EMAIL", "YOUR-API-TOKEN"))
issue = jira.issue("YOUR-ISSUE-KEY (e.g. ABC-13)")
print(issue.fields.summary)
I recommend storing your API Token as an environment variable and accessing it with os.environ[key].

Categories