Repository: alexgolec/tda-api

Issue:
Auto token-refresh not working any more
**Description of Bug**
The login flow that's supposed to do an auto-refresh of the token loaded from disk doesn't work any more. I traced it to the parameter passing in `client_from_access_functions` to the `authlib` functions. `authlib`'s `OAuth2Client` expects the URL in `kwargs` with key `token_endpoint`, but instead `auto_refresh_url` key is passed.

This issue was introduced when moving from `request_oauthlib` to `authlib` around the bigger changes to support async operation, commit f667554248f17ee990691b81ba0e76a868cbd606, #99. `authlib` expects different parameters than the prior library.

**Code to Reproduce**
(Note: I ran this in a Colab notebook.)
```python
!pip install git+https://github.com/alexgolec/tda-api.git@master

import tda
import json

token_path = "/content/drive/MyDrive/Colab Notebooks/tdameritrade_tokens.json"
api_key_path = "/content/drive/MyDrive/Colab Notebooks/tdameritrade_api_key.key"
redirect_uri = "https://127.0.0.1"
with open(api_key_path) as f:
  api_key = f.read()

client = tda.auth.client_from_token_file(token_path, api_key)

tsla_tick_data = client.get_price_history('TSLA',
                                          period_type=tda.client.Client.PriceHistory.PeriodType.MONTH,
                                          period=tda.client.Client.PriceHistory.Period.ONE_MONTH,
                                          frequency_type=tda.client.Client.PriceHistory.FrequencyType.DAILY,
                                          frequency=tda.client.Client.PriceHistory.Frequency.DAILY)
```

**Expected Behavior**
The call to `get_price_history` should succeed, and the token should have been refreshed.

**Actual Behavior**
The call to `get_price_history` throws the following exception:
```
---------------------------------------------------------------------------
InvalidTokenError                         Traceback (most recent call last)
<ipython-input-5-18c975b65f80> in <module>()
      3                                           period=tda.client.Client.PriceHistory.Period.ONE_MONTH,
      4                                           frequency_type=tda.client.Client.PriceHistory.FrequencyType.DAILY,
----> 5                                           frequency=tda.client.Client.PriceHistory.Frequency.DAILY)

4 frames
/usr/local/lib/python3.6/dist-packages/authlib/integrations/httpx_client/oauth2_client.py in ensure_active_token(self)
    212                 self.update_token(token, access_token=access_token)
    213         else:
--> 214             raise InvalidTokenError()

InvalidTokenError: token_invalid: 
```

**Error/Exception Log, If Applicable**
(Note: When trying to capture the debug log per the instructions at https://tda-api.readthedocs.io/en/latest/help.html, I stumbled upon an issue with `enable_bug_report_logging` for which I've submitted #126 and relatedly #127.)

```
DEBUG:tda.debug:tda-api version 0.7.1
INFO:tda.auth:Loading token from file /content/drive/MyDrive/Colab Notebooks/tdameritrade_tokens.json
INFO:tda.auth:Appending @AMER.OAUTHAP to API key
DEBUG:tda.client.base:Req 1: GET to https://api.tdameritrade.com/v1/marketdata/TSLA/pricehistory, params={
    "apikey": "<redacted>@AMER.OAUTHAP",
    "periodType": "month",
    "period": 1,
    "frequencyType": "daily",
    "frequency": 1
}
```


Discussion:
wolframarnold: Test are failing because of an issue with the environment setup that's no longer supported by Github. Please merge #127 first, then these tests should go green.

Patch:
diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml
index 2820fe4..f482edc 100644
--- a/.github/workflows/python.yml
+++ b/.github/workflows/python.yml
@@ -22,7 +22,7 @@ jobs:
     steps:
     - uses: actions/checkout@v2
     - name: Set up Python ${{ matrix.python.version }}
-      uses: actions/setup-python@v1.1.1
+      uses: actions/setup-python@v2
       with:
         python-version: ${{ matrix.python.version }}
 
@@ -57,7 +57,7 @@ jobs:
     steps:
     - uses: actions/checkout@v2
     - name: Set up Python ${{ matrix.python.version }}
-      uses: actions/setup-python@v1.1.1
+      uses: actions/setup-python@v2
       with:
         python-version: 3.8
     - name: Install dependencies
diff --git a/tda/auth.py b/tda/auth.py
index 5187f14..4ec47c9 100644
--- a/tda/auth.py
+++ b/tda/auth.py
@@ -263,9 +263,8 @@ def client_from_access_functions(api_key, token_read_func,
     api_key = __normalize_api_key(api_key)
 
     session_kwargs = {
-            'token': token,
-            'auto_refresh_url': 'https://api.tdameritrade.com/v1/oauth2/token',
-            'auto_refresh_kwargs': {'client_id': api_key},
+        'token': token,
+        'token_endpoint': 'https://api.tdameritrade.com/v1/oauth2/token',
     }
 
     if token_write_func is not None:


Test patch:
diff --git a/tests/test_auth.py b/tests/test_auth.py
index a39b05a..be6ea4b 100644
--- a/tests/test_auth.py
+++ b/tests/test_auth.py
@@ -46,8 +46,7 @@ class ClientFromTokenFileTest(unittest.TestCase):
         session.assert_called_once_with(
             API_KEY,
             token=self.token,
-            auto_refresh_url=_,
-            auto_refresh_kwargs=_,
+            token_endpoint=_,
             update_token=_)
 
     @no_duplicates
@@ -64,8 +63,7 @@ class ClientFromTokenFileTest(unittest.TestCase):
         session.assert_called_once_with(
             API_KEY,
             token=self.token,
-            auto_refresh_url=_,
-            auto_refresh_kwargs=_,
+            token_endpoint=_,
             update_token=_)
 
     @no_duplicates
@@ -100,8 +98,7 @@ class ClientFromTokenFileTest(unittest.TestCase):
         session.assert_called_once_with(
             'API_KEY@AMER.OAUTHAP',
             token=self.token,
-            auto_refresh_url=_,
-            auto_refresh_kwargs=_,
+            token_endpoint=_,
             update_token=_)
 
 
@@ -128,8 +125,7 @@ class ClientFromAccessFunctionsTest(unittest.TestCase):
         session.assert_called_once_with(
             'API_KEY@AMER.OAUTHAP',
             token=token,
-            auto_refresh_url=_,
-            auto_refresh_kwargs=_,
+            token_endpoint=_,
             update_token=_)
         token_read_func.assert_called_once()
 
@@ -159,8 +155,7 @@ class ClientFromAccessFunctionsTest(unittest.TestCase):
         session.assert_called_once_with(
             'API_KEY@AMER.OAUTHAP',
             token=token,
-            auto_refresh_url=_,
-            auto_refresh_kwargs=_)
+            token_endpoint=_)
         token_read_func.assert_called_once()