diff --git a/app/models/pydantic/datamart.py b/app/models/pydantic/datamart.py index caa96a44..dcf6db5b 100644 --- a/app/models/pydantic/datamart.py +++ b/app/models/pydantic/datamart.py @@ -5,4 +5,4 @@ class TreeCoverLossByDriverIn(StrictBaseModel): geostore_id: UUID - canopy_cover: int + canopy_cover: int = 30 diff --git a/app/routes/datamart/land.py b/app/routes/datamart/land.py index 0dee8f4a..0b030fa9 100644 --- a/app/routes/datamart/land.py +++ b/app/routes/datamart/land.py @@ -1,15 +1,16 @@ """Run analysis on registered datasets.""" +import os import random import uuid from uuid import UUID -from fastapi import APIRouter, Depends, Path, Query, Request -from fastapi.logger import logger +from fastapi import APIRouter, Depends, Path, Query from fastapi.openapi.models import APIKey from fastapi.responses import ORJSONResponse from app.models.pydantic.datamart import TreeCoverLossByDriverIn +from app.settings.globals import API_URL from ...authentication.api_keys import get_api_key from ...models.pydantic.responses import Response @@ -26,108 +27,100 @@ async def tree_cover_loss_by_driver_search( *, geostore_id: UUID = Query(..., title="Geostore ID"), - canopy_cover: int = Query(..., alias="canopy_cover", title="Canopy Cover Percent"), - request: Request, + canopy_cover: int = Query(30, alias="canopy_cover", title="Canopy Cover Percent"), api_key: APIKey = Depends(get_api_key), ): """Search if a resource exists for a given geostore and canopy cover.""" - # create mock_ids state if it doesn't exist - if not hasattr(request.app.state, "mock_ids"): - request.app.state.mock_ids = {} - try: - resource_id = request.app.state.mock_ids[f"{geostore_id}_{canopy_cover}"]["id"] + resource_id = _get_resource_id(geostore_id, canopy_cover) + + if os.path.exists(f"/tmp/{resource_id}"): return ORJSONResponse( status_code=200, content={ "status": "success", - "data": {"link": f"/v0/land/tree-cover-loss-by-driver/{resource_id}"}, - }, - ) - return - except KeyError: - return ORJSONResponse( - status_code=404, - content={ - "status": "failed", - "message": "Not Found", + "data": { + "link": f"{API_URL}/v0/land/tree-cover-loss-by-driver/{resource_id}" + }, }, ) + return ORJSONResponse( + status_code=404, + content={ + "status": "failed", + "message": "Not Found", + }, + ) + @router.get( - "/tree-cover-loss-by-driver/{uuid}", + "/tree-cover-loss-by-driver/{resource_id}", response_class=ORJSONResponse, response_model=Response, tags=["Land"], ) async def tree_cover_loss_by_driver_get( *, - uuid: UUID = Path(..., title="Tree cover loss by driver ID"), - request: Request, + resource_id: UUID = Path(..., title="Tree cover loss by driver ID"), api_key: APIKey = Depends(get_api_key), ): """Retrieve a tree cover loss by drivers resource.""" - # create mock_ids state if it doesn't exist - if not hasattr(request.app.state, "mock_ids"): - request.app.state.mock_ids = {} - - logger.info(request.app.state.mock_ids) - - resource = None - for mock_id in request.app.state.mock_ids.values(): - if mock_id["id"] == uuid: - resource = mock_id - - if resource is None: + try: + with open(f"/tmp/{resource_id}", "r") as f: + retries = int(f.read().strip()) + + if retries < 3: + retries += 1 + with open(f"/tmp/{resource_id}", "w") as f: + f.write(str(retries)) + + return ORJSONResponse( + status_code=200, + headers={"Retry-After": "1"}, + content={"data": {"status": "pending"}, "status": "success"}, + ) + else: + return ORJSONResponse( + status_code=200, + content={ + "data": { + "self": f"/v0/land/tree-cover-loss-by-driver/{resource_id}", + "treeCoverLossByDriver": { + "Permanent agriculture": 10, + "Hard commodities": 12, + "Shifting cultivation": 7, + "Forest management": 93.4, + "Wildfires": 42, + "Settlements and infrastructure": 13.562, + "Other natural disturbances": 6, + }, + "metadata": { + "sources": [ + {"dataset": "umd_tree_cover_loss", "version": "v1.11"}, + { + "dataset": "wri_google_tree_cover_loss_by_drivers", + "version": "v1.11", + }, + { + "dataset": "umd_tree_cover_density_2000", + "version": "v1.11", + }, + ] + }, + }, + "status": "success", + }, + ) + except FileNotFoundError: return ORJSONResponse( status_code=404, content={ - "status": "status", + "status": "failed", "message": "Not Found", }, ) - if resource["retries"] < 3: - resource["retries"] += 1 - return ORJSONResponse( - status_code=200, - headers={"Retry-After": "1"}, - content={"data": {"status": "pending"}, "status": "success"}, - ) - else: - return ORJSONResponse( - status_code=200, - content={ - "data": { - "self": f"/v0/land/tree-cover-loss-by-driver/{resource['id']}", - "treeCoverLossByDriver": { - "Permanent agriculture": 10, - "Hard commodities": 12, - "Shifting cultivation": 7, - "Forest management": 93.4, - "Wildfires": 42, - "Settlements and infrastructure": 13.562, - "Other natural disturbances": 6, - }, - "metadata": { - "sources": [ - {"dataset": "umd_tree_cover_loss", "version": "v1.11"}, - { - "dataset": "wri_google_tree_cover_loss_by_drivers", - "version": "v1.11", - }, - { - "dataset": "umd_tree_cover_density_2000", - "version": "v1.11", - }, - ] - }, - }, - "status": "success", - }, - ) - @router.post( "/tree-cover-loss-by-driver", @@ -138,7 +131,6 @@ async def tree_cover_loss_by_driver_get( ) async def tree_cover_loss_by_driver_post( data: TreeCoverLossByDriverIn, - request: Request, api_key: APIKey = Depends(get_api_key), ): """Create new tree cover loss by drivers resource for a given geostore and @@ -147,25 +139,23 @@ async def tree_cover_loss_by_driver_post( # create initial Job item as pending # trigger background task to create item # return 202 accepted - resource_id = uuid.uuid4() - - # create mock_ids state if it doesn't exist - if not hasattr(request.app.state, "mock_ids"): - request.app.state.mock_ids = {} + resource_id = _get_resource_id(data.geostore_id, data.canopy_cover) # mocks randomness of analysis time retries = random.randint(0, 3) - request.app.state.mock_ids[f"{data.geostore_id}_{data.canopy_cover}"] = { - "id": resource_id, - "retries": retries, - } + with open(f"/tmp/{resource_id}", "w") as f: + f.write(str(retries)) return ORJSONResponse( status_code=202, content={ "data": { - "link": f"/v0/land/tree-cover-loss-by-driver/{resource_id}", + "link": f"{API_URL}/v0/land/tree-cover-loss-by-driver/{resource_id}", }, "status": "success", }, ) + + +def _get_resource_id(geostore_id, canopy_cover): + return uuid.uuid5(uuid.NAMESPACE_OID, f"{geostore_id}_{canopy_cover}") diff --git a/tests_v2/unit/app/routes/datamart/test_land.py b/tests_v2/unit/app/routes/datamart/test_land.py index c064461c..ad2454a2 100644 --- a/tests_v2/unit/app/routes/datamart/test_land.py +++ b/tests_v2/unit/app/routes/datamart/test_land.py @@ -39,7 +39,6 @@ async def test_post_tree_cover_loss_by_drivers( "/v0/land/tree-cover-loss-by-driver", headers=headers, json=payload ) - print("HERE") print(response.json()) assert response.status_code == 202 @@ -77,12 +76,6 @@ async def test_get_tree_cover_loss_by_drivers_after_create( assert body["status"] == "success" link = body["data"]["link"] - response = await async_client.get(link, headers=headers) - - assert response.status_code == 200 - assert "Retry-After" in response.headers - assert int(response.headers["Retry-After"]) == 1 - retries = 0 while retries < 3: response = await async_client.get(link, headers=headers)