Skip to content

Commit

Permalink
refactor session
Browse files Browse the repository at this point in the history
  • Loading branch information
Graeme22 committed Jan 13, 2025
1 parent df9a9f9 commit 2488ac6
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ A simple, reverse-engineered SDK for Tastytrade built on their (now mostly publi

```console
$ pip install tastytrade
```
```

## Creating a session

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ readme = "README.md"
requires-python = ">=3.9"
license = {file = "LICENSE"}
authors = [
{name = "Graeme Holliday", email = "graeme[email protected]"},
{name = "Graeme Holliday", email = "graeme@tastyware.dev"},
]
dependencies = [
"httpx>=0.27.2",
Expand Down
34 changes: 16 additions & 18 deletions tastytrade/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
from typing import Any, Optional, Union
from typing_extensions import Self

import httpx
import json
from httpx import AsyncClient, Client

from tastytrade import API_URL, CERT_URL
from tastytrade.utils import TastytradeError, TastytradeJsonDataclass, validate_response
from tastytrade.utils import (
TastytradeError,
TastytradeJsonDataclass,
_validate_and_parse,
validate_response,
)


class Address(TastytradeJsonDataclass):
Expand Down Expand Up @@ -316,15 +320,13 @@ def __init__(
)
else:
response = self.sync_client.post("/sessions", json=body)
validate_response(response) # throws exception if not 200

json = response.json()
data = _validate_and_parse(response)
#: The user dict returned by the API; contains basic user information
self.user = User(**json["data"]["user"])
self.user = User(**data["user"])
#: The session token used to authenticate requests
self.session_token = json["data"]["session-token"]
self.session_token = data["session-token"]
#: A single-use token which can be used to login without a password
self.remember_token = json["data"].get("remember-token")
self.remember_token = data.get("remember-token")
self.sync_client.headers.update({"Authorization": self.session_token})
#: httpx client for async requests
self.async_client = AsyncClient(
Expand All @@ -345,11 +347,11 @@ def __init__(

async def _a_get(self, url, **kwargs) -> dict[str, Any]:
response = await self.async_client.get(url, timeout=30, **kwargs)
return self._validate_and_parse(response)
return _validate_and_parse(response)

def _get(self, url, **kwargs) -> dict[str, Any]:
response = self.sync_client.get(url, timeout=30, **kwargs)
return self._validate_and_parse(response)
return _validate_and_parse(response)

async def _a_delete(self, url, **kwargs) -> None:
response = await self.async_client.delete(url, **kwargs)
Expand All @@ -361,23 +363,19 @@ def _delete(self, url, **kwargs) -> None:

async def _a_post(self, url, **kwargs) -> dict[str, Any]:
response = await self.async_client.post(url, **kwargs)
return self._validate_and_parse(response)
return _validate_and_parse(response)

def _post(self, url, **kwargs) -> dict[str, Any]:
response = self.sync_client.post(url, **kwargs)
return self._validate_and_parse(response)
return _validate_and_parse(response)

async def _a_put(self, url, **kwargs) -> dict[str, Any]:
response = await self.async_client.put(url, **kwargs)
return self._validate_and_parse(response)
return _validate_and_parse(response)

def _put(self, url, **kwargs) -> dict[str, Any]:
response = self.sync_client.put(url, **kwargs)
return self._validate_and_parse(response)

def _validate_and_parse(self, response: httpx._models.Response) -> dict[str, Any]:
validate_response(response)
return response.json()["data"]
return _validate_and_parse(response)

async def a_validate(self) -> bool:
"""
Expand Down
7 changes: 6 additions & 1 deletion tastytrade/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def get_future_index_monthly(day: Optional[date] = None) -> date:

class TastytradeError(Exception):
"""
An internal error raised by the Tastytrade API.
An internal error raised by the Tastytrade SDK.
"""

pass
Expand Down Expand Up @@ -269,6 +269,11 @@ def validate_response(response: Response) -> None:
raise TastytradeError(error_message)


def _validate_and_parse(response: Response) -> dict[str, Any]:
validate_response(response)
return response.json()["data"]


def _get_sign(value: Optional[Decimal]) -> Optional[PriceEffect]:
if not value:
return None
Expand Down

0 comments on commit 2488ac6

Please sign in to comment.