I cannot understand how to properly use the query parameters using Etrade's production API. Regardless of the query parameter used, the response is always unauthorized. Here's the documentation relevant to this example. Most of the code is taken from the Python example on this page.
I receive a 200 response without the parameter and 401 when adding the parameter sortOrder=ASC
.
import configparser
from rauth import OAuth1Service
import webbrowser
# loading configuration file
config = configparser.ConfigParser()
config.read("etrade_python_client/config.ini")
etrade = OAuth1Service(
name="etrade",
consumer_key=config["DEFAULT"]["PROD_KEY"],
consumer_secret=config["DEFAULT"]["PROD_SECRET"],
request_token_url="https://api.etrade.com/oauth/request_token",
access_token_url="https://api.etrade.com/oauth/access_token",
authorize_url="https://us.etrade.com/e/t/etws/authorize?key={}&token={}",
base_url="https://api.etrade.com")
request_token, request_token_secret = etrade.get_request_token(params={"oauth_callback": "oob", "format": "json"})
authorize_url = etrade.authorize_url.format(etrade.consumer_key, request_token)
webbrowser.open(authorize_url)
The previous line opens a web browser which I navigate to and copy the code and store it as text_code
.
text_code = "<copy-code-from-web-browser>"
session = etrade.get_auth_session(request_token, request_token_secret, params={"oauth_verifier": text_code})
# get account info
url_account = "https://api.etrade.com/v1/accounts/list.json"
data_account = session.get(url_account, header_auth=True).json()
# store account id key
account_id_key = res["AccountListResponse"]["Accounts"]["Account"][0]["accountIdKey"]
# get portfolio and specify sortOrder
url_portfolio = "https://api.etrade.com/v1/accounts/{}/portfolio?sortOrder=ASC".format(account_id_key)
data_portfolio = session.get(url_portfolio, header_auth=True)
print(data_portfolio)
>>> <Response [401]>
# get portfolio and do not specify sort order
url_portfolio = "https://api.etrade.com/v1/accounts/{}/portfolio".format(account_id_key)
data_portfolio = session.get(url_portfolio, header_auth=True)
print(data_portfolio)
>>> <Response [200]>
Has anyone else ran into this issue? I'm thinking I must not be passing the query parameters correctly.
The documentation on their site seems to not tell how to do that, but they provide an example python script which I hoped would include hints. And it kind of does, but I can't verify them as I don't have such an account. Please let us know, if either suggestion worked or you found another solution.
While the example for a get to the portfolio endpoint they give looks like:
def portfolio(self):
# URL for the API endpoint
url =self.base_url + "/v1/accounts/" + self.account["accountIdKey"] + "/portfolio.json"
# Make API call for GET request
response = self.session.get(url, header_auth=True)
There are other examples such as a get to balance, which might be relevant to your question:
def balance(self):
# URL for the API endpoint
url = self.base_url + "/v1/accounts/" + self.account["accountIdKey"] + "/balance.json"
# Add parameters and header information
params = {"instType": self.account["institutionType"], "realTimeNAV": "true"}
headers = {"consumerkey": config["DEFAULT"]["CONSUMER_KEY"]}
# Make API call for GET request
response = self.session.get(url, header_auth=True, params=params, headers=headers)
Here we can see that params=params
would be accept.
So what I'd try would be something like this for your request:
# get portfolio and specify sortOrder
url_portfolio = "https://api.etrade.com/v1/account/{}/portfolio".format(account_id_key)
params = {'sortOrder':'ASC'}
data_portfolio = session.get(url_portfolio, params=params, header_auth=True)
print(data_portfolio)
Also, I'd consider the possibility that for sortOrder
to be used correctly, you may need to provide a param for sortBy
as well (acceptable values are in the doc you linked).