11from datetime import date , datetime
22from typing import Any , Optional , Union
3+ from typing_extensions import Self
34
45import httpx
6+ import json
7+ from httpx import AsyncClient , Client
58
69from tastytrade import API_URL , CERT_URL
710from tastytrade .utils import TastytradeError , TastytradeJsonDataclass , validate_response
@@ -302,7 +305,7 @@ def __init__(
302305 "Content-Type" : "application/json" ,
303306 }
304307 #: httpx client for sync requests
305- self .sync_client = httpx . Client (
308+ self .sync_client = Client (
306309 base_url = (CERT_URL if is_test else API_URL ), headers = headers
307310 )
308311 if two_factor_authentication is not None :
@@ -323,9 +326,8 @@ def __init__(
323326 #: A single-use token which can be used to login without a password
324327 self .remember_token = json ["data" ].get ("remember-token" )
325328 self .sync_client .headers .update ({"Authorization" : self .session_token })
326- self .validate ()
327329 #: httpx client for async requests
328- self .async_client = httpx . AsyncClient (
330+ self .async_client = AsyncClient (
329331 base_url = self .sync_client .base_url , headers = self .sync_client .headers .copy ()
330332 )
331333
@@ -440,3 +442,34 @@ def get_2fa_info(self) -> TwoFactorInfo:
440442 """
441443 data = self ._get ("/users/me/two-factor-method" )
442444 return TwoFactorInfo (** data )
445+
446+ def serialize (self ) -> str :
447+ """
448+ Serializes the session to a string, useful for storing
449+ a session for later use.
450+ Could be used with pickle, Redis, etc.
451+ """
452+ attrs = self .__dict__ .copy ()
453+ del attrs ["async_client" ]
454+ del attrs ["sync_client" ]
455+ attrs ["user" ] = attrs ["user" ].model_dump ()
456+ return json .dumps (attrs )
457+
458+ @classmethod
459+ def deserialize (cls , serialized : str ) -> Self :
460+ """
461+ Create a new Session object from a serialized string.
462+ """
463+ deserialized = json .loads (serialized )
464+ deserialized ["user" ] = User (** deserialized ["user" ])
465+ self = cls .__new__ (cls )
466+ self .__dict__ = deserialized
467+ base_url = CERT_URL if self .is_test else API_URL
468+ headers = {
469+ "Accept" : "application/json" ,
470+ "Content-Type" : "application/json" ,
471+ "Authorization" : self .session_token ,
472+ }
473+ self .sync_client = Client (base_url = base_url , headers = headers )
474+ self .async_client = AsyncClient (base_url = base_url , headers = headers )
475+ return self
0 commit comments