robinhood-unofficial / pyrh

Python Framework to make trades with the unofficial Robinhood API
https://pyrh.readthedocs.io/en/latest/
MIT License
1.78k stars 604 forks source link

AuthenticationError: Update to the newest version of Robinhood to access this feature. #319

Open Andersacc9 opened 2 weeks ago

Andersacc9 commented 2 weeks ago

Checklist

Description

Crashes when running from pyrh import Robinhood rh = Robinhood(username="email", password="password") This error shows up when you login with correct credentials, however it doesn't ask 2FA.

Steps/Code to Reproduce

Run the program with successful credentials

A different error will pop up if you provide the wrong credential as usual saying that the password or email is incorrect, meaning the connection between the api and robinhood still works.

Results

File "/home/runner/HeftyRedundantElement/main.py", line 4, in <module> rh.login() File "/home/runner/HeftyRedundantElement/.pythonlibs/lib/python3.10/site-packages/pyrh/models/sessionmanager.py", line 162, in login self._login_oauth2() File "/home/runner/HeftyRedundantElement/.pythonlibs/lib/python3.10/site-packages/pyrh/models/sessionmanager.py", line 453, in _login_oauth2 raise AuthenticationError(msg) pyrh.exceptions.AuthenticationError: Update to the newest version of Robinhood to access this feature.

Versions

Linux-6.2.16-x86_64-with-glibc2.39 Python 3.10.14 (main, Mar 19 2024, 21:46:16) [GCC 13.3.0] pyrh 2.1.2

cejohnson commented 5 days ago

I took a look at what requests the website front end was sending, and saw they're currently sending this version header:

X-Robinhood-API-Version: 1.431.4

whereas pyrh is sending version 1.0.0 by default.

https://github.com/robinhood-unofficial/pyrh/blob/e301e8018abc1f8afe5d7aeaebdfa188783a4772/pyrh/models/sessionmanager.py#L42

Setting headers = {"X-Robinhood-API-Version": "1.431.4"} and passing that into the constructor fixed it for me, but I fully expect this to crop up again at some point.

patrocinio commented 4 days ago

Hey @cejohnson, how are you setting the header? Thanks!

cejohnson commented 4 days ago

You can pass them in as a kwarg to the constructor:

headers = {"X-Robinhood-API-Version": "1.431.4"}
rh = Robinhood(username=args["username"], password=args["password"], mfa=args["mfa"], headers=headers)
rh.login()

I assumed the headers passed in here would be merged with the default headers, and the SessionManager docstring seems to support that, but I'm not seeing this actually happen in the code so it may be a full replacement. However, the above is working for me.

adithyabsk commented 3 days ago

You can pass them in as a kwarg to the constructor:

headers = {"X-Robinhood-API-Version": "1.431.4"}
rh = Robinhood(username=args["username"], password=args["password"], mfa=args["mfa"], headers=headers)
rh.login()

I assumed the headers passed in here would be merged with the default headers, and the SessionManager docstring seems to support that, but I'm not seeing this actually happen in the code so it may be a full replacement. However, the above is working for me.

https://github.com/robinhood-unofficial/pyrh/blob/e301e8018abc1f8afe5d7aeaebdfa188783a4772/pyrh/models/sessionmanager.py#L105

Actually, it replaces--if you put up a PR. I can cut a release. We may actually want a better solution here, where users can change the API version on the fly.

cejohnson commented 3 days ago

PR created.

I thought about adding an api_version kwarg to the __init__ but figured that could introduce ambiguity and complexity around whether that argument or headers took precedence... so instead I just bumped the version to keep things simple.