6

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?

ethann
  • 189
  • 2
  • 10
  • The error message is saying that that consumer key can only be used in the sandbox environment. I know it seems like you are using the sandbox url... ? But... are you sure you are? – aychedee Feb 18 '15 at 09:03
  • The url is straight from their docs: https://developer.etrade.com/ctnt/dev-portal/getContent?contentUri=V0_Documentation-DeveloperGuides-Sandbox – ethann Feb 18 '15 at 09:04
  • @aychedee your question was well asked. I had to contact etrade to find out that oauth, even in the sandbox, is handled through the main api. The error msg only propagates this confusion. – ethann Feb 23 '15 at 23:24
  • Confusing docs are confusing :-) – aychedee Feb 23 '15 at 23:52

2 Answers2

7

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)
ethann
  • 189
  • 2
  • 10
  • thanks. So after having done this, I'm having trouble getting the sandbox api to work. The auth is working. ```token = self.authy() ourParams = {"oauth_consumer_key":self.consumer_key,"oauth_token":token,"module":"ACCOUNTS"} response = requests.get("https://etwssandbox.etrade.com/accounts/sandbox/rest/alerts/",params = ourParams) print(response.status_code) responseJSON = response.text print(responseJSON) ``` – Tizzee Apr 12 '16 at 00:07
  • I'm getting a ` 999 Invalid Request.` in the response...which does have a 200 status code – Tizzee Apr 12 '16 at 00:09
  • @Tizzee This is still a sticking point for me too. I'll need to solve it eventually and will post on it if/when I do. – ethann Apr 13 '16 at 21:35
  • @Tizzee When I execute this, I'm getting a response 200 error as well. Is it because there are no accounts in the sandbox? – brianlen Sep 01 '18 at 03:11
1

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)
cswiger
  • 11
  • 1