1
1
import requests
2
- from requests import auth
2
+ import pickle
3
+ import os
3
4
4
5
AUTH_URI = "https://www.googleapis.com/oauth2/v4/token"
5
6
DEFAULT_BASE_URI = "https://smartdevicemanagement.googleapis.com/v1"
6
7
DEFAULT_REDIRECT_URI = "https://www.google.com"
8
+ DEVICES_URI = (
9
+ "https://smartdevicemanagement.googleapis.com/v1/enterprises/{project_id}/devices"
10
+ )
7
11
8
12
9
13
class ArgumentsMissingError (Exception ):
@@ -14,45 +18,139 @@ class AuthorizationError(Exception):
14
18
pass
15
19
16
20
17
- class NestDeviceAccessAuth (auth .AuthBase ):
18
- def __init__ (self , auth_callback , client_id , client_secret , code , session = None , redirect_uri = DEFAULT_REDIRECT_URI ):
19
- if not client_id or client_secret or not code or client_id == "" or client_secret == "" or code == "" :
21
+ class NestDeviceAccessAuth (requests .auth .AuthBase ):
22
+ def __init__ (
23
+ self ,
24
+ project_id ,
25
+ client_id ,
26
+ client_secret ,
27
+ code ,
28
+ session = None ,
29
+ redirect_uri = DEFAULT_REDIRECT_URI ,
30
+ ):
31
+ if client_id == "" or client_secret == "" or project_id == "" :
20
32
raise ArgumentsMissingError ()
21
- self ._res = {}
33
+
34
+ self .project_id = project_id
22
35
self .client_id = client_id
23
36
self .client_secret = client_secret
37
+
38
+ if not code or code == "" :
39
+ self .invalid_token ()
40
+ raise ArgumentsMissingError ()
41
+
24
42
self .code = code
43
+
44
+ self ._res = {}
45
+ self .access_token = None
46
+ self .refresh_token = None
25
47
self .redirect_uri = redirect_uri
26
48
self ._session = session
27
- self .auth_callback = auth_callback
28
-
29
- def login (self , headers = None ):
30
- data = {'client_id' : self .client_id ,
31
- 'client_secret' : self .client_secret ,
32
- 'code' : self .code ,
33
- 'grant_type' : 'authorization_code' ,
34
- 'redirect_uri' : self .redirect_uri }
35
- post = requests .post
36
- response = post (AUTH_URI , params = data , headers = headers )
49
+
50
+ def login (self ):
51
+ if os .path .exists ("auth.bak" ):
52
+ with open ("auth.bak" , "rb" ) as token :
53
+ creds = pickle .load (token )
54
+ self .access_token = creds ["access" ]
55
+ self .refresh_token = creds ["refresh" ]
56
+ return
57
+
58
+ data = {
59
+ "client_id" : self .client_id ,
60
+ "client_secret" : self .client_secret ,
61
+ "code" : self .code ,
62
+ "grant_type" : "authorization_code" ,
63
+ "redirect_uri" : self .redirect_uri ,
64
+ }
65
+ response = requests .post (AUTH_URI , params = data )
37
66
if response .status_code != 200 :
38
- print (response .content )
67
+ if response .status_code == 400 :
68
+ self .invalid_token ()
39
69
raise AuthorizationError (response )
40
70
self ._res = response .json ()
41
- self .auth_callback (self ._res )
71
+ self .access_token = self ._res ["access_token" ]
72
+ self .refresh_token = self ._res ["refresh_token" ]
73
+
74
+ with open ("auth.bak" , "wb" ) as token :
75
+ pickle .dump (
76
+ {"access" : self .access_token , "refresh" : self .refresh_token }, token
77
+ )
78
+
79
+ def __call__ (self , r ):
80
+ if self .access_token is not None :
81
+ r .headers ["authorization" ] = "Bearer " + self .access_token
82
+ return r
83
+ else :
84
+ self .login ()
85
+ r .headers ["authorization" ] = "Bearer " + self .access_token
86
+ return r
87
+
88
+ def invalid_token (self ):
89
+ print (
90
+ f"Go to this link to get OAuth token: https://nestservices.google.com/partnerconnections/{ self .project_id } "
91
+ f"/auth?redirect_uri=https://www.google.com&access_type=offline&prompt=consent&client_id={ self .client_id } "
92
+ f"&response_type=code&scope=https://www.googleapis.com/auth/sdm.service"
93
+ )
94
+
95
+
96
+ class Device (object ):
97
+ def __init__ (self , dict ):
98
+ self .name = dict ["name" ]
99
+ self .type = dict ["type" ]
100
+ self .traits = dict ["traits" ]
42
101
43
102
44
103
class NestDeviceAccess (object ):
45
- def __init__ (self , client_id , client_secret , code , redirect_uri = DEFAULT_REDIRECT_URI ):
46
- auth = NestDeviceAccessAuth (client_id , client_secret , code , self .login_callback , redirect_uri )
47
- self ._session = requests .Session ()
48
- self ._session .auth = auth
104
+ def __init__ (
105
+ self ,
106
+ project_id ,
107
+ client_id ,
108
+ client_secret ,
109
+ code ,
110
+ redirect_uri = DEFAULT_REDIRECT_URI ,
111
+ ):
112
+ self .auth = NestDeviceAccessAuth (
113
+ project_id , client_id , client_secret , code , redirect_uri
114
+ )
115
+ self .access_token = None
116
+ self .refresh_token = None
49
117
50
- def login_callback (self , res ):
51
- print (res )
118
+ self .project_id = project_id
119
+ self .client_id = client_id
120
+ self .client_secret = client_secret
52
121
53
122
def login (self ):
54
- self ._session .auth .login ()
123
+ try :
124
+ self .auth .login ()
125
+ except AuthorizationError :
126
+ print ("Authorization Error" )
127
+ pass
128
+
129
+ def devices (self ):
130
+ if not self .auth .access_token :
131
+ raise AuthorizationError ()
132
+
133
+ response = requests .get (
134
+ DEVICES_URI .format (project_id = self .project_id ), auth = self .auth
135
+ )
136
+ if response .status_code != 200 :
137
+ if response .status_code == 400 :
138
+ raise AuthorizationError (response )
139
+ devices_dict = response .json ()
140
+
141
+ devices = []
142
+ for device in devices_dict ["devices" ]:
143
+ devices .append (Device (device ))
144
+ return devices
55
145
56
146
57
- #nda = NestDeviceAccess(client_id="484808906646-a9tche4b03q56u47fiojh04tbf7r56m8.apps.googleusercontent.com", client_secret="uS-rH6Fqcr_d_vsTHpZOZd6l", code="4/5AE-0v8n60-tkng0pcvVhgviF1i77yUfpseFxiURRzPi_vdlHDRCe2KL8nOnUa0AcDF4a2aKHarqChm6SQC4FoQ")
58
- #nda.login()
147
+ if __name__ == "__main__" :
148
+ nda = NestDeviceAccess (
149
+ project_id = "2a7ad63f-af0f-414a-b218-23dd6b39d0c5" ,
150
+ client_id = "484808906646-a9tche4b03q56u47fiojh04tbf7r56m8.apps.googleusercontent.com" ,
151
+ client_secret = "uS-rH6Fqcr_d_vsTHpZOZd6l" ,
152
+ code = "4/0AY0e-g6INJsCbfeHVxZV_Eg1jSEdWaxI22DgTfxUFTbPSBMXAEexjT_4VY9Rf1H5jht-hQ" ,
153
+ )
154
+ nda .login ()
155
+ for device in nda .devices ():
156
+ print (device .name )
0 commit comments