jessecooper / pyetrade

Python E-Trade API Wrapper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

User Login via Selenium

PaulNobrega opened this issue · comments

Good library. I would suggest a modification to your ETradeOAuth class to support automated login. Below is a working test script to benefit others if you decided to not add the feature.

from rauth import OAuth1Service
import undetected_chromedriver.v2 as uc
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time
import xmltodict
import json


class AutomatedLogin():
    def __init__(self, consumer_key, consumer_secret, web_username, web_password):
        self.consumer_key = consumer_key
        self.consumer_secret = consumer_secret
        self.web_username = web_username
        self.web_password = web_password
        self.service = OAuth1Service(
                  name='etrade',
                  consumer_key=consumer_key,
                  consumer_secret=consumer_secret,
                  request_token_url='https://apisb.etrade.com/oauth/request_token',
                  access_token_url='https://apisb.etrade.com/oauth/access_token',
                  authorize_url='https://us.etrade.com/e/t/etws/authorize?key={}&token={}',
                  base_url='https://apisb.etrade.com')
        self.oauth_token, self.oauth_token_secret = self.service.get_request_token(params={'oauth_callback': 'oob', 'format': 'json'})
        self.auth_url = self.service.authorize_url.format(consumer_key, self.oauth_token)
        self.verifier = self.__get_verifier(headless=True, action_delay_sec=2)
        if self.verifier:
            self.session = self.service.get_auth_session(self.oauth_token, self.oauth_token_secret, params={'oauth_verifier': self.verifier})

    def __get_verifier(self, headless=True, action_delay_sec=2):
        if headless:
            options = uc.ChromeOptions()
            options.headless = True
            options.add_argument('--headless')
            driver = uc.Chrome(options=options)
            print(f'Headless web login with action_delay set to: {action_delay_sec} seconds')
        else:
            driver = uc.Chrome()
        web_action = ActionChains(driver)

        try:
            with driver:
                driver.get(self.auth_url)
                # log in
                username = driver.find_element_by_name("USER")
                password = driver.find_element_by_name("PASSWORD")
                username.send_keys(web_username)
                password.send_keys(web_password)
                driver.find_element_by_id("logon_button").click()
                time.sleep(action_delay_sec)
                web_action.send_keys(Keys.TAB).send_keys(Keys.RETURN).perform()
                return driver.find_element_by_tag_name("input").get_attribute("value")
        except Exception as e:
            print(str(e))
            return

# User Parameters
consumer_key = 'dxxx...xxx007'
consumer_secret = 'e7xxx...xxxa4e8'
web_username = 'user_name'
web_password = 'password'

# Automated Login
login = AutomatedLogin(consumer_key, consumer_secret, web_username, web_password)

# Test Session
url = 'https://apisb.etrade.com/v1/accounts/list'
resp = login.session.get(url, params={'format': 'json'})
resp_json = json.dumps(xmltodict.parse(resp.text))
print(resp_json)

Thanks for the example. As @1rocketdude said this has been talked about in the past and is something the application leveraging pyetrade should implement. There has been a suggestion to create a discussion board around pyetrade for topics like this. I am going to look into this and any suggestions around this are appreciated.