Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an oauth request token from etrade in Python

I'm trying to get an oauth request token from the etrade api (sandbox) in Python with this thing:

import requests
from oauthlib.oauth1 import Client

consumer_key = 'foo'     # actual key used
consumer_secret = 'bar'  # actual secret used
request_url = 'https://etwssandbox.etrade.com/oauth/sandbox/request_token'

client = Client(consumer_key, client_secret = consumer_secret)
uri, headers, body = client.sign(request_url)
add_params = ', realm="", oauth_token= "", oauth_callback="oob"'
headers['Authorization'] += add_params

r = requests.get(url = uri, headers = headers)
print(r.text) # abbreviated resp: " . . . .auth_problem=consumer_key_rejected,oauth_problem_advice=The oauth_consumer_key foo can be used only in SANDBOX environment . . . 

The header generated is:

{'Authorization': 'OAuth oauth_nonce="99985873301258063061424248905", oauth_timestamp="1424248905", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="foo", oauth_signature="A7ZY91UyZz6NfSGmMA5YWGnVM%2FQ%3D", realm="", oauth_token= "", oauth_callback="oob"'}

I have also tried the url: 'https://etwssandbox.etrade.com/oauth/sandbox/rest/request_token'

And I have tried the header without the add_params (it seems to need the blank oauth_token?)

Note: Confusingly, the response periodically comes back: "Http/1.1 400 Bad Request" with exactly the same url/header.

Any idea what I'm doing wrong?

like image 732
ethann Avatar asked Feb 18 '15 08:02

ethann


2 Answers

A helpful person at etrade clarified for the doc-challenged that all oauth api requests (whether you are working in the sandbox or not) need to be sent to the main api url: 'https://etws.etrade.com/oauth/{api}'.

It is only after authenticating a session that the sandbox urls should be used: 'https://etwssandbox.etrade.com/{non-oauth-module}/sandbox/rest/{api}'.

In case others are having problems authenticating a session with etrade in python3, this works in the sandbox at least:

from rauth import OAuth1Service
import webbrowser 

def getSession():
    # Create a session
    # Use actual consumer secret and key in place of 'foo' and 'bar'
    service = OAuth1Service(
              name = 'etrade',
              consumer_key = 'foo',
              consumer_secret = 'bar',
              request_token_url = 'https://etws.etrade.com/oauth/request_token',
              access_token_url = 'https://etws.etrade.com/oauth/access_token',
              authorize_url = 'https://us.etrade.com/e/t/etws/authorize?key={}&token={}',
              base_url = 'https://etws.etrade.com')

    # Get request token and secret    
    oauth_token, oauth_token_secret = service.get_request_token(params = 
                                  {'oauth_callback': 'oob', 
                                   'format': 'json'})

    auth_url = service.authorize_url.format(consumer_key, oauth_token)

    # Get verifier (direct input in console, still working on callback)
    webbrowser.open(auth_url)
    verifier = input('Please input the verifier: ')

    return service.get_auth_session(oauth_token, oauth_token_secret, params = {'oauth_verifier': verifier})

# Create a session
session = getSession()

# After authenticating a session, use sandbox urls
url = 'https://etwssandbox.etrade.com/accounts/sandbox/rest/accountlist.json'

resp = session.get(url, params = {'format': 'json'})

print(resp)
like image 129
ethann Avatar answered Nov 22 '22 10:11

ethann


Thanks @ethann - this actually still works as of 6/17/2020 with changed urls.

from rauth import OAuth1Service
import webbrowser 

service = OAuth1Service(
          name = 'etrade',
          consumer_key = 'foo',
          consumer_secret = 'bar',
          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')

oauth_token, oauth_token_secret = service.get_request_token(params =
       {'oauth_callback': 'oob', 
        'format': 'json'})

auth_url = service.authorize_url.format('foo again', oauth_token)
webbrowser.open(auth_url)
verifier = input('Please input the verifier: ')
session = service.get_auth_session(oauth_token, oauth_token_secret, params = {'oauth_verifier': verifier})

url = 'https://apisb.etrade.com/v1/accounts/list'
resp = session.get(url, params = {'format': 'json'})

print(resp.text)
like image 38
cswiger Avatar answered Nov 22 '22 10:11

cswiger