1212from librespot .crypto import CipherPair , DiffieHellman , Packet
1313from librespot .mercury import MercuryClient , MercuryRequests , RawMercuryRequest
1414from librespot .metadata import AlbumId , ArtistId , EpisodeId , ShowId , TrackId
15- from librespot .proto import Authentication_pb2 as Authentication , Connect_pb2 as Connect , Keyexchange_pb2 as Keyexchange , Metadata_pb2 as Metadata
15+ from librespot .proto import Authentication_pb2 as Authentication , ClientToken_pb2 as ClientToken , Connect_pb2 as Connect , Connectivity_pb2 as Connectivity , Keyexchange_pb2 as Keyexchange , Metadata_pb2 as Metadata
1616from librespot .proto .ExplicitContentPubsub_pb2 import UserAttributesUpdate
1717from librespot .structure import Closeable , MessageListener , RequestListener , SubListener
1818import base64
3939class ApiClient (Closeable ):
4040 logger = logging .getLogger ("Librespot:ApiClient" )
4141 __base_url : str
42+ __client_token_str : str = None
4243 __session : Session
4344
4445 def __init__ (self , session : Session ):
@@ -49,6 +50,11 @@ def build_request(
4950 self , method : str , suffix : str ,
5051 headers : typing .Union [None , typing .Dict [str , str ]],
5152 body : typing .Union [None , bytes ]) -> requests .PreparedRequest :
53+ if self .__client_token_str is None :
54+ resp = self .__client_token ()
55+ self .__client_token_str = resp .granted_token .token
56+ self .logger .debug ("Updated client token: {}" .format (self .__client_token_str ))
57+
5258 request = requests .PreparedRequest ()
5359 request .method = method
5460 request .data = body
@@ -147,6 +153,45 @@ def get_metadata_4_show(self, show: ShowId) -> Metadata.Show:
147153 proto .ParseFromString (body )
148154 return proto
149155
156+ def set_client_token (self , client_token ):
157+ self .__client_token_str = client_token
158+
159+ def __client_token (self ):
160+ proto_req = ClientToken .ClientTokenRequest (
161+ request_type = ClientToken .ClientTokenRequestType .REQUEST_CLIENT_DATA_REQUEST ,
162+ client_data = ClientToken .ClientDataRequest (
163+ client_id = MercuryRequests .keymaster_client_id ,
164+ client_version = Version .version_name ,
165+ connectivity_sdk_data = Connectivity .ConnectivitySdkData (
166+ device_id = self .__session .device_id (),
167+ platform_specific_data = Connectivity .PlatformSpecificData (
168+ windows = Connectivity .NativeWindowsData (
169+ something1 = 10 ,
170+ something3 = 21370 ,
171+ something4 = 2 ,
172+ something6 = 9 ,
173+ something7 = 332 ,
174+ something8 = 33404 ,
175+ something10 = True ,
176+ ),
177+ ),
178+ ),
179+ ),
180+ )
181+
182+ resp = requests .post ("https://clienttoken.spotify.com/v1/clienttoken" ,
183+ proto_req .SerializeToString (),
184+ headers = {
185+ "Accept" : "application/x-protobuf" ,
186+ "Content-Encoding" : "" ,
187+ })
188+
189+ ApiClient .StatusCodeException .check_status (resp )
190+
191+ proto_resp = ClientToken .ClientTokenResponse ()
192+ proto_resp .ParseFromString (resp .content )
193+ return proto_resp
194+
150195 class StatusCodeException (IOError ):
151196 code : int
152197
0 commit comments