Skip to content

Commit fe0b6b2

Browse files
committed
fix #291
1 parent 16c754d commit fe0b6b2

File tree

5 files changed

+15
-153
lines changed

5 files changed

+15
-153
lines changed

docs/sessions.rst

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,6 @@ Generating an initial refresh token
1313

1414
In order to generate an initial refresh token, you have two options. The easiest way is to simply generate one from Tastytrade's website: go to OAuth Applications > Manage > Create Grant to get a new refresh token, **which you should also save**.
1515

16-
The other option (which is actually the only option for sandbox accounts) is to run this helper code:
17-
18-
.. code-block:: python
19-
20-
from tastytrade.oauth import login
21-
login(is_test=True)
22-
23-
This will open up a web interface in your browser where you'll be prompted to paste your client ID and client secret. These credentials will then be used to connect your application to Tastytrade. After following the steps in your browser, you should see your new refresh token in the browser and in the console.
24-
2516
At this point, OAuth is now setup correctly! Doing these steps once is sufficient for **indefinite usage** of ``Session`` for authentication to the API, since refresh tokens never expire. From now on you can simply authenticate with your client secret and refresh token.
2617

2718
Creating a session

tastytrade/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
API_VERSION = "20251101"
55
CERT_URL = "https://api.cert.tastyworks.com"
66
VAST_URL = "https://vast.tastyworks.com"
7-
VERSION = "11.0.3"
7+
VERSION = "11.0.4"
88

99
__version__ = VERSION
1010
version_str: str = f"tastyware/tastytrade:v{VERSION}"

tastytrade/oauth.py

Lines changed: 0 additions & 129 deletions
This file was deleted.

tastytrade/session.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010
from tastytrade import API_URL, API_VERSION, CERT_URL, logger
1111
from tastytrade.utils import (
12-
TZ,
1312
TastytradeData,
13+
now_in_new_york,
1414
validate_and_parse,
1515
validate_response,
1616
)
@@ -274,11 +274,9 @@ def __init__(
274274
#: Refresh token for the user
275275
self.refresh_token = refresh_token
276276
# The headers to use for API requests
277-
headers = {
278-
"Accept": "application/json",
279-
"Accept-Version": API_VERSION,
280-
"Content-Type": "application/json",
281-
}
277+
headers = {"Accept": "application/json", "Content-Type": "application/json"}
278+
if not is_test: # not accepted in sandbox
279+
headers["Accept-Version"] = API_VERSION
282280
#: httpx client for sync requests
283281
self.sync_client = Client(
284282
base_url=(CERT_URL if is_test else API_URL), headers=headers, proxy=proxy
@@ -288,7 +286,7 @@ def __init__(
288286
base_url=self.sync_client.base_url, headers=headers, proxy=proxy
289287
)
290288
#: expiration for streamer token
291-
self.streamer_expiration = datetime.now(TZ)
289+
self.streamer_expiration = now_in_new_york()
292290
self.refresh()
293291

294292
def _streamer_refresh(self) -> None:
@@ -325,14 +323,14 @@ def refresh(self) -> None:
325323
self.session_token = data["access_token"]
326324
token_lifetime: int = data.get("expires_in", 900)
327325
#: expiration for session token
328-
self.session_expiration = datetime.now(TZ) + timedelta(seconds=token_lifetime)
326+
self.session_expiration = now_in_new_york() + timedelta(seconds=token_lifetime)
329327
logger.debug(f"Refreshed token, expires in {token_lifetime}ms")
330328
auth_headers = {"Authorization": f"Bearer {self.session_token}"}
331329
# update the httpx clients with the new token
332330
self.sync_client.headers.update(auth_headers)
333331
self.async_client.headers.update(auth_headers)
334332
# update the streamer token if necessary
335-
if self.streamer_expiration < self.session_expiration:
333+
if not self.is_test and self.streamer_expiration < self.session_expiration:
336334
self._streamer_refresh()
337335

338336
async def a_refresh(self) -> None:
@@ -357,14 +355,14 @@ async def a_refresh(self) -> None:
357355
# update the relevant tokens
358356
self.session_token = data["access_token"]
359357
token_lifetime: int = data.get("expires_in", 900)
360-
self.session_expiration = datetime.now(TZ) + timedelta(token_lifetime)
358+
self.session_expiration = now_in_new_york() + timedelta(token_lifetime)
361359
logger.debug(f"Refreshed token, expires in {token_lifetime}ms")
362360
auth_headers = {"Authorization": f"Bearer {self.session_token}"}
363361
# update the httpx clients with the new token
364362
self.sync_client.headers.update(auth_headers)
365363
self.async_client.headers.update(auth_headers)
366364
# update the streamer token if necessary
367-
if self.streamer_expiration < self.session_expiration:
365+
if not self.is_test and self.streamer_expiration < self.session_expiration:
368366
# Pull streamer tokens and urls
369367
data = await self._a_get("/api-quote-tokens")
370368
# Auth token for dxfeed websocket

uv.lock

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)