2
2
3
3
import re
4
4
import uuid
5
- from typing import Dict , List , Optional
5
+ from typing import Dict , Optional
6
6
from uuid import UUID
7
7
8
8
from fastapi import (
18
18
from fastapi .openapi .models import APIKey
19
19
from fastapi .responses import ORJSONResponse
20
20
from pydantic import ValidationError
21
+ from starlette .status import HTTP_400_BAD_REQUEST
22
+
21
23
22
24
from app .crud import datamart as datamart_crud
23
25
from app .errors import RecordNotFoundError
33
35
AreaOfInterest ,
34
36
GeostoreAreaOfInterest ,
35
37
AdminAreaOfInterest ,
38
+ Global ,
36
39
)
37
40
from app .settings .globals import API_URL
38
41
from app .tasks .datamart .land import (
45
48
46
49
router = APIRouter ()
47
50
51
+
48
52
def _parse_dataset_versions (request : Request ) -> Dict [str , str ]:
49
53
dataset_versions = {}
50
54
errors = []
@@ -83,6 +87,9 @@ def _parse_area_of_interest(request: Request) -> AreaOfInterest:
83
87
version = params .get ('aoi[version]' , None ),
84
88
)
85
89
90
+ if aoi_type == "global" :
91
+ return Global ()
92
+
86
93
# If neither type is provided, raise an error
87
94
raise HTTPException (status_code = 422 , detail = "Invalid Area of Interest parameters" )
88
95
except ValidationError as e :
@@ -111,6 +118,7 @@ def _parse_area_of_interest(request: Request) -> AreaOfInterest:
111
118
"oneOf" : [
112
119
{"$ref" : "#/components/schemas/GeostoreAreaOfInterest" },
113
120
{"$ref" : "#/components/schemas/AdminAreaOfInterest" },
121
+ {"$ref" : "#/components/schemas/Global" },
114
122
]
115
123
}
116
124
},
@@ -129,7 +137,7 @@ def _parse_area_of_interest(request: Request) -> AreaOfInterest:
129
137
"tsc_tree_cover_loss_drivers" : "v2023" ,
130
138
},
131
139
"description" : (
132
- "Pass dataset version overrides as bracketed query parameters." ,
140
+ "Pass dataset version overrides as bracketed query parameters." ,
133
141
)
134
142
}
135
143
]
@@ -143,9 +151,9 @@ async def tree_cover_loss_by_driver_search(
143
151
api_key : APIKey = Depends (get_api_key ),
144
152
):
145
153
"""Search if a resource exists for a given geostore and canopy cover."""
146
- geostore_id = await aoi .get_geostore_id ()
154
+ area_id = "global" if aoi . type == "global" else await aoi .get_geostore_id ()
147
155
resource_id = _get_resource_id (
148
- "tree_cover_loss_by_driver" , geostore_id , canopy_cover , dataset_versions
156
+ "tree_cover_loss_by_driver" , area_id , canopy_cover , dataset_versions
149
157
)
150
158
151
159
# check if it exists
@@ -198,41 +206,53 @@ async def tree_cover_loss_by_driver_post(
198
206
):
199
207
"""Create new tree cover loss by drivers resource for a given geostore and
200
208
canopy cover."""
201
- geostore_id = await data .aoi .get_geostore_id ()
202
209
203
- # check geostore is valid
204
- try :
205
- await get_geostore (geostore_id , GeostoreOrigin .rw )
206
- except HTTPException :
207
- raise HTTPException (
208
- status_code = 422 ,
209
- detail = f"Geostore { geostore_id } can't be found or is not valid." ,
210
- )
210
+ area_id = "global" if data .aoi .type == "global" else await data .aoi .get_geostore_id ()
211
211
212
- # create initial Job item as pending
213
- # trigger background task to create item
214
- # return 202 accepted
215
212
dataset_version = DEFAULT_LAND_DATASET_VERSIONS | data .dataset_version
216
213
resource_id = _get_resource_id (
217
214
"tree_cover_loss_by_driver" ,
218
- geostore_id ,
215
+ area_id ,
219
216
data .canopy_cover ,
220
217
dataset_version ,
221
218
)
222
219
220
+ link = DataMartResourceLink (
221
+ link = f"{ API_URL } /v0/land/tree_cover_loss_by_driver/{ resource_id } "
222
+ )
223
+ if data .aoi .type == "global" :
224
+ try :
225
+ _ = await _get_resource (resource_id )
226
+ except HTTPException :
227
+ raise HTTPException (
228
+ HTTP_400_BAD_REQUEST ,
229
+ detail = "Global computation not supported for this dataset and pre-computed results are not available."
230
+ )
231
+
232
+ return DataMartResourceLinkResponse (data = link )
233
+
234
+ # check geostore is valid
235
+ try :
236
+ await get_geostore (area_id , GeostoreOrigin .rw )
237
+ except HTTPException :
238
+ raise HTTPException (
239
+ status_code = 422 ,
240
+ detail = f"Geostore { area_id } can't be found or is not valid." ,
241
+ )
242
+
243
+ # create initial Job item as pending
223
244
await _save_pending_resource (resource_id , request .url .path , api_key )
224
245
246
+ # trigger background task to create item
247
+ # return 202 accepted
225
248
background_tasks .add_task (
226
249
compute_tree_cover_loss_by_driver ,
227
250
resource_id ,
228
- geostore_id ,
251
+ area_id ,
229
252
data .canopy_cover ,
230
253
dataset_version ,
231
254
)
232
255
233
- link = DataMartResourceLink (
234
- link = f"{ API_URL } /v0/land/tree_cover_loss_by_driver/{ resource_id } "
235
- )
236
256
return DataMartResourceLinkResponse (data = link )
237
257
238
258
0 commit comments