itsjafer / schwab-api

A python library for placing trades on Charles Schwab
MIT License
201 stars 64 forks source link

Login issue #46

Closed 4rumprom closed 6 months ago

4rumprom commented 6 months ago

image

It seems the user-agent passed along with the playwright identification is causing this page to show up, which in turn causes the identification to fail as of this morning.

A quick fix would be to update the user-agent string, however, a more robust solution is needed.

4rumprom commented 6 months ago

I think the most robust fix is to change the user agent to firefox, which is actually the browser used with playwright and to update the version the one used by playwright. Hence, when playwright is outdated, the login will fail. Once playwright is updated, the USER_AGENT "constant" will update alongside.

MaxxRK commented 6 months ago

I agree with the above comment, but if the website does not want to load correctly in firefox for some reason the below library could be used to get a "popular" user agent each time it is called. This should accomplish the same thing.

https://pypi.org/project/fake-useragent/

4rumprom commented 6 months ago

Yes, that was my first thought. However, this schwab-API currently hardcoded firefox anyways. If anything else entered in SessionManager.browserType, it defaults to webkit, which actually doesn't work with Schwab. At least not on the two machines I tried it on. Additionally:

I've made a simple tweak to authenticate.py and tested it. I works now and I am about to create a pull request. Until this change is approved, I recommend adding the following line to your code right after the api call:

Initialize our schwab instance

api = Schwab()

version = api.browser.version usr_agent = f"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:{version}) Gecko/20100101 Firefox/{version}" api.page = api.browser.new_page( user_agent = usr_agent, viewport = { 'width': 1920, 'height': 1080 } )

MaxxRK commented 6 months ago

I believe your solution is best then for sure. Very simple. I just went into site packages and hardcoded a Firefox user agent to v123.00 and it worked fine for me as well. If it does not get approved, I will use the above.

itsjafer commented 6 months ago

Out on vacation, but I've approved the change. Will try to identify a more robust solution to this type of thing going forward

tristanpenman commented 6 months ago

Not sure if this is still relevant, but I had another workaround for this. This is what I implemented while experimenting with the Playwright async API:

try:
    async with self.page.expect_navigation():
        await self.page.frame(name=login_frame).press("[placeholder=\"Password\"]", "Enter")
except TimeoutError:
    raise Exception("Login was not successful; please check username and password")

# Handles out-of-date user agent
if await self.page.get_by_text("Time to Update Your Browser").is_visible():
    async with self.page.expect_navigation():
        await self.page.click("button:text(\"Continue\")")

if self.page.url != urls.trade_ticket():
    return False

await self.page.wait_for_selector("#_txtSymbol")

If you think something like this would be useful, and sufficiently robust, I can raise a PR once https://github.com/itsjafer/schwab-api/pull/51/files has been merged.