1
1
from __future__ import annotations
2
2
3
- from dataclasses import asdict
4
3
import datetime
5
4
import logging
5
+ from dataclasses import asdict
6
6
from typing import (
7
7
TYPE_CHECKING ,
8
8
Any ,
33
33
from saic_ismart_client_ng .listener import SaicApiListener
34
34
from saic_ismart_client_ng .model import SaicApiConfiguration
35
35
36
+
36
37
class IsDataclass (Protocol ):
37
38
# as already noted in comments, checking for this attribute is currently
38
39
# the most reliable way to ascertain that something is a dataclass
39
40
__dataclass_fields__ : ClassVar [dict [str , Any ]]
40
41
42
+
41
43
T = TypeVar ("T" , bound = IsDataclass )
42
44
43
45
logger = logging .getLogger (__name__ )
44
46
45
47
46
48
class AbstractSaicApi :
47
49
def __init__ (
48
- self ,
49
- configuration : SaicApiConfiguration ,
50
- listener : SaicApiListener | None = None ,
50
+ self ,
51
+ configuration : SaicApiConfiguration ,
52
+ listener : SaicApiListener | None = None ,
51
53
) -> None :
52
54
self .__configuration = configuration
53
55
self .__api_client = SaicApiClient (configuration , listener = listener )
@@ -59,16 +61,16 @@ async def login(self) -> LoginResp:
59
61
"Accept" : "application/json" ,
60
62
"Authorization" : "Basic c3dvcmQ6c3dvcmRfc2VjcmV0" ,
61
63
}
62
- firebase_device_id = "cqSHOMG1SmK4k-fzAeK6hr:APA91bGtGihOG5SEQ9hPx3Dtr9o9mQguNiKZrQzboa-1C_UBlRZYdFcMmdfLvh9Q_xA8A0dGFIjkMhZbdIXOYnKfHCeWafAfLXOrxBS3N18T4Slr-x9qpV6FHLMhE9s7I6s89k9lU7DD"
64
+ firebase_device_id = "simulator*********************************************" + str ( int ( datetime . datetime . now (). timestamp ()))
63
65
form_body = {
64
66
"grant_type" : "password" ,
65
67
"username" : self .__configuration .username ,
66
68
"password" : sha1_hex_digest (self .__configuration .password ),
67
69
"scope" : "all" ,
68
- "deviceId" : f"{ firebase_device_id } ###europecar" ,
69
- "deviceType" : "1 " , # 2 for huawei
70
+ "deviceId" : f"{ firebase_device_id } ###com.saicmotor. europecar" ,
71
+ "deviceType" : "0 " , # 2 for huawei
70
72
"loginType" : "2" if self .__configuration .username_is_email else "1" ,
71
- "countryCode " : ""
73
+ "language " : "EN "
72
74
if self .__configuration .username_is_email
73
75
else self .__configuration .phone_country_code ,
74
76
}
@@ -82,7 +84,7 @@ async def login(self) -> LoginResp:
82
84
)
83
85
# Update the user token
84
86
if not (access_token := result .access_token ) or not (
85
- expiration := result .expires_in
87
+ expiration := result .expires_in
86
88
):
87
89
raise SaicApiException (
88
90
"Failed to get an access token, please check your credentials"
@@ -95,16 +97,16 @@ async def login(self) -> LoginResp:
95
97
return result
96
98
97
99
async def execute_api_call (
98
- self ,
99
- method : str ,
100
- path : str ,
101
- * ,
102
- body : Any | None = None ,
103
- form_body : Any | None = None ,
104
- out_type : type [T ],
105
- params : QueryParamTypes | None = None ,
106
- headers : HeaderTypes | None = None ,
107
- allow_null_body : bool = False ,
100
+ self ,
101
+ method : str ,
102
+ path : str ,
103
+ * ,
104
+ body : Any | None = None ,
105
+ form_body : Any | None = None ,
106
+ out_type : type [T ],
107
+ params : QueryParamTypes | None = None ,
108
+ headers : HeaderTypes | None = None ,
109
+ allow_null_body : bool = False ,
108
110
) -> T :
109
111
result = await self .__execute_api_call (
110
112
method ,
@@ -122,15 +124,15 @@ async def execute_api_call(
122
124
return result
123
125
124
126
async def execute_api_call_no_result (
125
- self ,
126
- method : str ,
127
- path : str ,
128
- * ,
129
- body : Any | None = None ,
130
- form_body : Any | None = None ,
131
- params : QueryParamTypes | None = None ,
132
- headers : HeaderTypes | None = None ,
133
- allow_null_body : bool = False ,
127
+ self ,
128
+ method : str ,
129
+ path : str ,
130
+ * ,
131
+ body : Any | None = None ,
132
+ form_body : Any | None = None ,
133
+ params : QueryParamTypes | None = None ,
134
+ headers : HeaderTypes | None = None ,
135
+ allow_null_body : bool = False ,
134
136
) -> None :
135
137
await self .__execute_api_call (
136
138
method ,
@@ -143,16 +145,16 @@ async def execute_api_call_no_result(
143
145
)
144
146
145
147
async def __execute_api_call (
146
- self ,
147
- method : str ,
148
- path : str ,
149
- * ,
150
- body : Any | None = None ,
151
- form_body : Any | None = None ,
152
- out_type : type [T ] | None = None ,
153
- params : QueryParamTypes | None = None ,
154
- headers : HeaderTypes | None = None ,
155
- allow_null_body : bool = False ,
148
+ self ,
149
+ method : str ,
150
+ path : str ,
151
+ * ,
152
+ body : Any | None = None ,
153
+ form_body : Any | None = None ,
154
+ out_type : type [T ] | None = None ,
155
+ params : QueryParamTypes | None = None ,
156
+ headers : HeaderTypes | None = None ,
157
+ allow_null_body : bool = False ,
156
158
) -> T | None :
157
159
try :
158
160
url = f"{ self .__configuration .base_uri } { path .removeprefix ('/' )} "
@@ -174,15 +176,15 @@ async def __execute_api_call(
174
176
raise SaicApiException (msg , return_code = 500 ) from e
175
177
176
178
async def execute_api_call_with_event_id (
177
- self ,
178
- method : str ,
179
- path : str ,
180
- * ,
181
- body : Any | None = None ,
182
- out_type : type [T ],
183
- params : QueryParamTypes | None = None ,
184
- headers : MutableMapping [str , str ] | None = None ,
185
- delay : tenacity .wait .WaitBaseT | None = None ,
179
+ self ,
180
+ method : str ,
181
+ path : str ,
182
+ * ,
183
+ body : Any | None = None ,
184
+ out_type : type [T ],
185
+ params : QueryParamTypes | None = None ,
186
+ headers : MutableMapping [str , str ] | None = None ,
187
+ delay : tenacity .wait .WaitBaseT | None = None ,
186
188
) -> T :
187
189
result = await self .__execute_api_call_with_event_id (
188
190
method ,
@@ -199,14 +201,14 @@ async def execute_api_call_with_event_id(
199
201
return result
200
202
201
203
async def execute_api_call_with_event_id_no_result (
202
- self ,
203
- method : str ,
204
- path : str ,
205
- * ,
206
- body : Any | None = None ,
207
- params : QueryParamTypes | None = None ,
208
- headers : MutableMapping [str , str ] | None = None ,
209
- delay : tenacity .wait .WaitBaseT | None = None ,
204
+ self ,
205
+ method : str ,
206
+ path : str ,
207
+ * ,
208
+ body : Any | None = None ,
209
+ params : QueryParamTypes | None = None ,
210
+ headers : MutableMapping [str , str ] | None = None ,
211
+ delay : tenacity .wait .WaitBaseT | None = None ,
210
212
) -> None :
211
213
await self .__execute_api_call_with_event_id (
212
214
method ,
@@ -218,15 +220,15 @@ async def execute_api_call_with_event_id_no_result(
218
220
)
219
221
220
222
async def __execute_api_call_with_event_id (
221
- self ,
222
- method : str ,
223
- path : str ,
224
- * ,
225
- body : Any | None = None ,
226
- out_type : type [T ] | None = None ,
227
- params : QueryParamTypes | None = None ,
228
- headers : MutableMapping [str , str ] | None = None ,
229
- delay : tenacity .wait .WaitBaseT | None = None ,
223
+ self ,
224
+ method : str ,
225
+ path : str ,
226
+ * ,
227
+ body : Any | None = None ,
228
+ out_type : type [T ] | None = None ,
229
+ params : QueryParamTypes | None = None ,
230
+ headers : MutableMapping [str , str ] | None = None ,
231
+ delay : tenacity .wait .WaitBaseT | None = None ,
230
232
) -> T | None :
231
233
@tenacity .retry (
232
234
stop = tenacity .stop_after_delay (30 ),
@@ -251,11 +253,11 @@ async def execute_api_call_with_event_id_inner(*, event_id: str) -> T | None:
251
253
252
254
# pylint: disable=too-many-branches
253
255
async def __deserialize (
254
- self ,
255
- request : httpx .Request ,
256
- response : httpx .Response ,
257
- data_class : type [T ] | None ,
258
- allow_null_body : bool ,
256
+ self ,
257
+ request : httpx .Request ,
258
+ response : httpx .Response ,
259
+ data_class : type [T ] | None ,
260
+ allow_null_body : bool ,
259
261
) -> T | None :
260
262
try :
261
263
request_event_id = request .headers .get ("event-id" )
@@ -348,9 +350,9 @@ def logout(self) -> None:
348
350
@property
349
351
def is_logged_in (self ) -> bool :
350
352
return (
351
- self .__api_client .user_token is not None
352
- and self .__token_expiration is not None
353
- and self .__token_expiration > datetime .datetime .now ()
353
+ self .__api_client .user_token is not None
354
+ and self .__token_expiration is not None
355
+ and self .__token_expiration > datetime .datetime .now ()
354
356
)
355
357
356
358
@property
0 commit comments