terrakio-core 0.5.0__py3-none-any.whl → 0.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
terrakio_core/__init__.py CHANGED
@@ -8,7 +8,7 @@ Core components for Terrakio API clients.
8
8
  # Suppress ONNX Runtime GPU device discovery warnings - MUST BE FIRST!
9
9
  import os
10
10
  os.environ['ORT_LOGGING_LEVEL'] = '3'
11
- __version__ = "0.5.0"
11
+ __version__ = "0.5.1"
12
12
 
13
13
  from .async_client import AsyncClient
14
14
  from .sync_client import SyncClient as Client
@@ -0,0 +1,236 @@
1
+ import json
2
+ import os
3
+ from typing import Any, Dict
4
+
5
+ from ..exceptions import (
6
+ APIKeyError,
7
+ AuthenticationExpireError,
8
+ InvalidUsernamePasswordError,
9
+ LoginError,
10
+ QuotaError,
11
+ RefreshAPIKeyError,
12
+ ResetPasswordError,
13
+ SignupError,
14
+ UserInfoError,
15
+ InvalidEmailFormatError,
16
+ EmailAlreadyExistsError,
17
+ )
18
+ from ..helper.decorators import require_api_key, require_auth, require_token
19
+
20
+ class AuthClient:
21
+ def __init__(self, client):
22
+ self._client = client
23
+
24
+ async def signup(self, email: str, password: str) -> Dict[str, str]:
25
+ """
26
+ Signup a new user with email and password.
27
+
28
+ Args:
29
+ email: User's email address
30
+ password: User's password
31
+
32
+ Returns:
33
+ Dict containing the authentication token
34
+
35
+ Raises:
36
+ SignupError: If the signup request fails
37
+ """
38
+ payload = {
39
+ "email": email,
40
+ "password": password
41
+ }
42
+ response, status = await self._client._terrakio_request("POST", "/users/signup", json=payload)
43
+ if status != 200:
44
+ if status == 422:
45
+ raise InvalidEmailFormatError(f"Invalid email format: {response}", status_code=status)
46
+ elif status == 409:
47
+ raise EmailAlreadyExistsError(f"Email already exists: {response}", status_code=status)
48
+ raise SignupError(f"Signup request failed: {response}", status_code=status)
49
+ else:
50
+ return response
51
+
52
+ async def login(self, email: str, password: str) -> None:
53
+ """
54
+ Login a user with email and password.
55
+
56
+ Args:
57
+ email: User's email address
58
+ password: User's password
59
+
60
+ Returns:
61
+ None
62
+
63
+ Raises:
64
+ APIError: If the login request fails
65
+ """
66
+ payload = {
67
+ "email": email,
68
+ "password": password
69
+ }
70
+ response, status = await self._client._terrakio_request("POST", "/users/login", json=payload)
71
+ if status != 200:
72
+ if status == 401:
73
+ raise InvalidUsernamePasswordError(f"Invalid username or password: {response}", status_code=status)
74
+ else:
75
+ raise LoginError(f"Login request failed: {response}", status_code=status)
76
+ else:
77
+ token_response = response.get("token")
78
+
79
+ if token_response:
80
+ self._client.token = token_response
81
+
82
+ api_key_response = await self.view_api_key()
83
+ self._client.key = api_key_response
84
+
85
+ if not self._client.url:
86
+ self._client.url = "https://api.terrak.io"
87
+
88
+ self._save_config(email, token_response)
89
+
90
+ self._client.logger.info(f"Successfully authenticated as: {email}")
91
+ self._client.logger.info(f"Using Terrakio API at: {self._client.url}")
92
+
93
+
94
+ @require_token
95
+ async def view_api_key(self) -> str:
96
+ """
97
+ View the current API key for the authenticated user.
98
+
99
+ Returns:
100
+ str: The API key
101
+
102
+ Raises:
103
+ AuthenticationExpireError: If authentication expired
104
+ APIKeyError: If the API key request fails
105
+ """
106
+ response, status = await self._client._terrakio_request("GET", "/users/key")
107
+ api_key = response.get("apiKey")
108
+ if status != 200:
109
+ if status == 400 and response.get("detail")["message"] == "Not authenticated":
110
+ raise AuthenticationExpireError(f"Authentication expired, please login again: {response}")
111
+ else:
112
+ raise APIKeyError(f"Error fetching API key: {response}", status_code=status)
113
+ else:
114
+ return api_key
115
+
116
+ @require_api_key
117
+ @require_token
118
+ async def refresh_api_key(self) -> str:
119
+ """
120
+ Refresh the API key for the authenticated user.
121
+
122
+ Returns:
123
+ str: The new API key
124
+
125
+ Raises:
126
+ RefreshAPIKeyError: If the API key refresh request fails
127
+ """
128
+ response, status = await self._client._terrakio_request("POST", "/users/refresh_key")
129
+ self._client.key = response.get("apiKey")
130
+ if status != 200:
131
+ raise RefreshAPIKeyError(f"Error refreshing API key: {response}", status_code=status)
132
+ else:
133
+ self._update_config_key()
134
+ return self._client.key
135
+
136
+ @require_api_key
137
+ async def get_user_info(self) -> Dict[str, Any]:
138
+ """
139
+ Get information about the authenticated user.
140
+
141
+ Returns:
142
+ Dict[str, Any]: User information
143
+
144
+ Raises:
145
+ AuthenticationExpireError: If authentication expired
146
+ UserInfoError: If the user info request fails
147
+ """
148
+ response, status = await self._client._terrakio_request("GET", "/users/info")
149
+ if status != 200:
150
+ if status == 400 and response.get("detail")["message"] == "Not authenticated":
151
+ raise AuthenticationExpireError(f"Authentication expired, please login again: {response}", status_code=status)
152
+ else:
153
+ raise UserInfoError(f"Error fetching user info: {response}", status_code=status)
154
+ else:
155
+ return response
156
+
157
+ @require_api_key
158
+ async def reset_password(self, email : str) -> Dict[str, Any]:
159
+ """
160
+ Reset the password for a user by email.
161
+ """
162
+ response, status = await self._client._terrakio_request("GET", f"/users/reset-password?email={email}")
163
+ if status != 200:
164
+ raise ResetPasswordError(f"Error resetting password: {response}", status_code=status)
165
+ else:
166
+ return response['message']
167
+
168
+ @require_api_key
169
+ async def get_user_quota(self):
170
+ """
171
+ Get the user's quota.
172
+
173
+ Returns:
174
+ Dict: User's quota
175
+
176
+ Raises:
177
+ QuotaError: If the quota request fails
178
+ """
179
+ response, status = await self._client._terrakio_request("GET", "/users/quota")
180
+ if status != 200:
181
+ raise QuotaError(f"Error fetching quota: {response}", status_code = status)
182
+ else:
183
+ return response
184
+
185
+ def _save_config(self, email: str, token: str):
186
+ """
187
+ Helper method to save config file.
188
+
189
+ Args:
190
+ email: User's email address
191
+ token: Authentication token
192
+ """
193
+ config_path = os.path.join(os.environ.get("HOME", ""), ".tkio_config.json")
194
+
195
+ try:
196
+ config = {"EMAIL": email, "TERRAKIO_API_KEY": self._client.key}
197
+ if os.path.exists(config_path):
198
+ with open(config_path, 'r') as f:
199
+ config = json.load(f)
200
+
201
+ config["EMAIL"] = email
202
+ config["TERRAKIO_API_KEY"] = self._client.key
203
+ config["PERSONAL_TOKEN"] = token
204
+ os.makedirs(os.path.dirname(config_path), exist_ok=True)
205
+ with open(config_path, 'w') as f:
206
+ json.dump(config, f, indent=4)
207
+
208
+ self._client.logger.info(f"API key saved to {config_path}")
209
+
210
+ except Exception as e:
211
+ self._client.logger.info(f"Warning: Failed to update config file: {e}")
212
+
213
+ def _update_config_key(self):
214
+ """
215
+ Helper method to update just the API key in config.
216
+ """
217
+ config_path = os.path.join(os.environ.get("HOME", ""), ".tkio_config.json")
218
+
219
+ try:
220
+ config = {"EMAIL": "", "TERRAKIO_API_KEY": ""}
221
+
222
+ if os.path.exists(config_path):
223
+ with open(config_path, 'r') as f:
224
+ config = json.load(f)
225
+
226
+ config["TERRAKIO_API_KEY"] = self._client.key
227
+
228
+ os.makedirs(os.path.dirname(config_path), exist_ok=True)
229
+
230
+ with open(config_path, 'w') as f:
231
+ json.dump(config, f, indent=4)
232
+
233
+ self._client.logger.info(f"API key updated in {config_path}")
234
+
235
+ except Exception as e:
236
+ self._client.logger.info(f"Warning: Failed to update config file: {e}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: terrakio-core
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Core package for the terrakio-python-api
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: aiofiles>=24.1.0
@@ -1,4 +1,4 @@
1
- terrakio_core/__init__.py,sha256=WQb8zJ51wFWTjdeYE5ixvTzD49e4bEPMWdSao9VFuZc,391
1
+ terrakio_core/__init__.py,sha256=qD9OAwIU1zNjl4tLvOoHW8ifquSiWQzLxeRiB9M-0mM,391
2
2
  terrakio_core/accessors.py,sha256=UZIi9y4RpBxouSmKuwuNYLIYqDxD8BH-GnUzwJuc1JI,47570
3
3
  terrakio_core/async_client.py,sha256=aCLjiAmhRS20efrA11hhGUbtwsxapIBp4hBAwG79K6Y,9766
4
4
  terrakio_core/client.py,sha256=VXP7BtJWIfpPPZR7_yNdSTcGwNgTwhb7KorusqkQrzk,5603
@@ -8,6 +8,7 @@ terrakio_core/sync_client.py,sha256=m5ybuQdWmjg2lIjWZED91iBXE094lOPGn-S-01ee8w4,
8
8
  terrakio_core/convenience_functions/create_dataset_file.py,sha256=RDTAQnKUigyczv3EKhKrs34VMDZDCgL4iz0bge1d9e4,4774
9
9
  terrakio_core/convenience_functions/geoquries.py,sha256=7E3drOD5ffNk2-rKLbwKsNp3_Berq-S1lQk5wwHSuAo,3786
10
10
  terrakio_core/convenience_functions/zonal_stats.py,sha256=7PI--RI0hiF1pzZ7_7hqtyOMOyw607HvHedD8BnYuJo,26630
11
+ terrakio_core/endpoints/auth.py,sha256=5WvAO39aLsbJAVtxISwiOZseKr3B9I5tHjamPRehDBQ,8327
11
12
  terrakio_core/endpoints/dataset_management.py,sha256=jpwftiKOI59NhXXypqm6wtILIkfyjy9NfYifRIvhZS0,16791
12
13
  terrakio_core/endpoints/group_management.py,sha256=V0KOGTXwmePBFeym55G_m3ONR-jVj2IU4OVLiL5UKz4,15869
13
14
  terrakio_core/endpoints/mass_stats.py,sha256=KuUaqF9h2z__2UvrFwrVDVB3eXPGTvU8dHjy7NWll1g,42000
@@ -17,6 +18,6 @@ terrakio_core/endpoints/user_management.py,sha256=L_g4ysrh2xyz_JbObUU_tCxgHxisrD
17
18
  terrakio_core/helper/bounded_taskgroup.py,sha256=wiTH10jhKZgrsgrFUNG6gig8bFkUEPHkGRT2XY7Rgmo,677
18
19
  terrakio_core/helper/decorators.py,sha256=L6om7wmWNgCei3Wy5U0aZ-70OzsCwclkjIf7SfQuhCg,2289
19
20
  terrakio_core/helper/tiles.py,sha256=lcLCO6KiP05lCI9vngo3zCZJ6Z9C0pUxHSQS4H58EHc,2699
20
- terrakio_core-0.5.0.dist-info/METADATA,sha256=SJnsWRDoneA--DsWijuJ44dcvbpwNlH7gltmEkT_yiw,1179
21
- terrakio_core-0.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
22
- terrakio_core-0.5.0.dist-info/RECORD,,
21
+ terrakio_core-0.5.1.dist-info/METADATA,sha256=BN9srGf8MFyrJs-JW57Ikpckr417r73ZtkGhypIDFGw,1179
22
+ terrakio_core-0.5.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
+ terrakio_core-0.5.1.dist-info/RECORD,,